Skip to content

Commit c572adb

Browse files
author
Nimit Sachdeva
committed
Add more tests and change the condition for negation
1 parent 408fbbe commit c572adb

File tree

2 files changed

+136
-55
lines changed

2 files changed

+136
-55
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
using namespace llvm;
5151
using namespace PatternMatch;
5252

53-
5453
/// Replace a select operand based on an equality comparison with the identity
5554
/// constant of a binop.
5655
static Instruction *foldSelectBinOpIdentity(SelectInst &Sel,
@@ -1713,7 +1712,6 @@ tryToReuseConstantFromSelectInComparison(SelectInst &Sel, ICmpInst &Cmp,
17131712
if (Pred == CmpInst::ICMP_ULT && match(X, m_Add(m_Value(), m_Constant())))
17141713
return nullptr;
17151714

1716-
17171715
Value *SelVal0, *SelVal1; // We do not care which one is from where.
17181716
match(&Sel, m_Select(m_Value(), m_Value(SelVal0), m_Value(SelVal1)));
17191717
// At least one of these values we are selecting between must be a constant
@@ -2021,7 +2019,7 @@ static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
20212019
auto *TrueVal = SI.getTrueValue();
20222020
auto *FalseVal = SI.getFalseValue();
20232021

2024-
if (Pred != ICmpInst::ICMP_EQ)
2022+
if (Pred != ICmpInst::ICMP_EQ && Pred != llvm::ICmpInst::ICMP_NE)
20252023
return nullptr;
20262024

20272025
// Match: icmp eq (or (usub.sat A, IntConst1), (usub.sat B, IntConst2)), 0
@@ -2032,8 +2030,10 @@ static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
20322030
m_Value(A), m_ConstantInt(IntConst1)),
20332031
m_Intrinsic<Intrinsic::usub_sat>(
20342032
m_Value(B), m_ConstantInt(IntConst2)))) &&
2035-
match(TrueVal, m_Zero()) &&
2036-
match(FalseVal, m_ConstantInt(PossibleMSBInt))) {
2033+
(match(TrueVal, m_Zero()) &&
2034+
match(FalseVal, m_ConstantInt(PossibleMSBInt)) ||
2035+
match(TrueVal, m_ConstantInt(PossibleMSBInt)) &&
2036+
match(FalseVal, m_Zero()))) {
20372037
auto *Ty = A->getType();
20382038
unsigned BW = Ty->getIntegerBitWidth();
20392039
APInt MostSignificantBit = APInt::getOneBitSet(BW, BW - 1);
@@ -2062,7 +2062,8 @@ static Instruction *foldICmpUSubSatWithAndForMostSignificantBitCmp(
20622062
m_Constant(Const1)),
20632063
m_Intrinsic<Intrinsic::usub_sat>(
20642064
m_Value(B), m_Constant(Const2)))) &&
2065-
match(TrueVal, m_Zero()) && match(FalseVal, m_Constant(PossibleMSB))) {
2065+
(match(TrueVal, m_Zero()) && match(FalseVal, m_Constant(PossibleMSB))
2066+
|| match(TrueVal, m_Constant(PossibleMSB) ) && match(FalseVal, m_Zero()))) {
20662067
auto *VecTy1 = dyn_cast<FixedVectorType>(Const1->getType());
20672068
auto *VecTy2 = dyn_cast<FixedVectorType>(Const2->getType());
20682069
auto *VecTyMSB = dyn_cast<FixedVectorType>(PossibleMSB->getType());
Lines changed: 129 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12

23
; RUN: opt -passes=instcombine -S < %s 2>&1 | FileCheck %s
34

@@ -7,12 +8,14 @@ declare i32 @llvm.usub.sat.i32(i32, i32)
78
declare i64 @llvm.usub.sat.i64(i64, i64)
89

910
define i8 @test_i8(i8 %a, i8 %b) {
10-
; CHECK-LABEL: @test_i8(
11-
; CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 %a, i8 96)
12-
; CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 %b, i8 112)
13-
; CHECK-NEXT: or i8
14-
; CHECK-NEXT: and i8
15-
; CHECK-NEXT: ret i8
11+
; CHECK-LABEL: define i8 @test_i8(
12+
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
13+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A]], i8 96)
14+
; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 112)
15+
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]]
16+
; CHECK-NEXT: [[RES:%.*]] = and i8 [[TMP3]], -128
17+
; CHECK-NEXT: ret i8 [[RES]]
18+
;
1619

1720
%a_sub = call i8 @llvm.usub.sat.i8(i8 %a, i8 223)
1821
%b_sub = call i8 @llvm.usub.sat.i8(i8 %b, i8 239)
@@ -22,13 +25,33 @@ define i8 @test_i8(i8 %a, i8 %b) {
2225
ret i8 %res
2326
}
2427

28+
define i8 @test_i8_ne(i8 %a, i8 %b) {
29+
; CHECK-LABEL: define i8 @test_i8_ne(
30+
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
31+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A]], i8 96)
32+
; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 112)
33+
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]]
34+
; CHECK-NEXT: [[RES:%.*]] = and i8 [[TMP3]], -128
35+
; CHECK-NEXT: ret i8 [[RES]]
36+
;
37+
38+
%a_sub = call i8 @llvm.usub.sat.i8(i8 %a, i8 223)
39+
%b_sub = call i8 @llvm.usub.sat.i8(i8 %b, i8 239)
40+
%or = or i8 %a_sub, %b_sub
41+
%cmp = icmp ne i8 %or, 0
42+
%res = select i1 %cmp, i8 128, i8 0
43+
ret i8 %res
44+
}
45+
2546
define i16 @test_i16(i16 %a, i16 %b) {
26-
; CHECK-LABEL: @test_i16(
27-
; CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 %a, i16 32642)
28-
; CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 %b, i16 32656)
29-
; CHECK-NEXT: or i16
30-
; CHECK-NEXT: and i16
31-
; CHECK-NEXT: ret i16
47+
; CHECK-LABEL: define i16 @test_i16(
48+
; CHECK-SAME: i16 [[A:%.*]], i16 [[B:%.*]]) {
49+
; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[A]], i16 32642)
50+
; CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[B]], i16 32656)
51+
; CHECK-NEXT: [[TMP3:%.*]] = or i16 [[TMP1]], [[TMP2]]
52+
; CHECK-NEXT: [[RES:%.*]] = and i16 [[TMP3]], -32768
53+
; CHECK-NEXT: ret i16 [[RES]]
54+
;
3255

3356
%a_sub = call i16 @llvm.usub.sat.i16(i16 %a, i16 65409)
3457
%b_sub = call i16 @llvm.usub.sat.i16(i16 %b, i16 65423)
@@ -39,12 +62,14 @@ define i16 @test_i16(i16 %a, i16 %b) {
3962
}
4063

4164
define i32 @test_i32(i32 %a, i32 %b) {
42-
; CHECK-LABEL: @test_i32(
43-
; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %a, i32 224)
44-
; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %b, i32 240)
45-
; CHECK-NEXT: or i32
46-
; CHECK-NEXT: and i32
47-
; CHECK-NEXT: ret i32
65+
; CHECK-LABEL: define i32 @test_i32(
66+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
67+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 224)
68+
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 240)
69+
; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], [[TMP2]]
70+
; CHECK-NEXT: [[RES:%.*]] = and i32 [[TMP3]], -2147483648
71+
; CHECK-NEXT: ret i32 [[RES]]
72+
;
4873

4974
%a_sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 2147483871)
5075
%b_sub = call i32 @llvm.usub.sat.i32(i32 %b, i32 2147483887)
@@ -55,12 +80,14 @@ define i32 @test_i32(i32 %a, i32 %b) {
5580
}
5681

5782
define i64 @test_i64(i64 %a, i64 %b) {
58-
; CHECK-LABEL: @test_i64(
59-
; CHECK-NEXT: call i64 @llvm.usub.sat.i64(i64 %a, i64 224)
60-
; CHECK-NEXT: call i64 @llvm.usub.sat.i64(i64 %b, i64 240)
61-
; CHECK-NEXT: or i64
62-
; CHECK-NEXT: and i64
63-
; CHECK-NEXT: ret i64
83+
; CHECK-LABEL: define i64 @test_i64(
84+
; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {
85+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 224)
86+
; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[B]], i64 240)
87+
; CHECK-NEXT: [[TMP3:%.*]] = or i64 [[TMP1]], [[TMP2]]
88+
; CHECK-NEXT: [[RES:%.*]] = and i64 [[TMP3]], -9223372036854775808
89+
; CHECK-NEXT: ret i64 [[RES]]
90+
;
6491

6592
%a_sub = call i64 @llvm.usub.sat.i64(i64 %a, i64 9223372036854776031)
6693
%b_sub = call i64 @llvm.usub.sat.i64(i64 %b, i64 9223372036854776047)
@@ -71,13 +98,15 @@ define i64 @test_i64(i64 %a, i64 %b) {
7198
}
7299

73100
define i32 @no_fold_due_to_small_K(i32 %a, i32 %b) {
74-
; CHECK-LABEL: @no_fold_due_to_small_K(
75-
; CHECK: call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
76-
; CHECK: call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
77-
; CHECK: or i32
78-
; CHECK: icmp eq i32
79-
; CHECK: select
80-
; CHECK: ret i32
101+
; CHECK-LABEL: define i32 @no_fold_due_to_small_K(
102+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
103+
; CHECK-NEXT: [[A_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 100)
104+
; CHECK-NEXT: [[B_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 239)
105+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[A_SUB]], [[B_SUB]]
106+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
107+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 -2147483648
108+
; CHECK-NEXT: ret i32 [[RES]]
109+
;
81110

82111
%a_sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
83112
%b_sub = call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
@@ -88,13 +117,15 @@ define i32 @no_fold_due_to_small_K(i32 %a, i32 %b) {
88117
}
89118

90119
define i32 @commuted_test_neg(i32 %a, i32 %b) {
91-
; CHECK-LABEL: @commuted_test_neg(
92-
; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
93-
; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %a, i32 223)
94-
; CHECK-NEXT: or i32
95-
; CHECK-NEXT: icmp eq i32
96-
; CHECK-NEXT: select
97-
; CHECK-NEXT: ret i32
120+
; CHECK-LABEL: define i32 @commuted_test_neg(
121+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
122+
; CHECK-NEXT: [[B_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 239)
123+
; CHECK-NEXT: [[A_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 223)
124+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[B_SUB]], [[A_SUB]]
125+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
126+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 -2147483648
127+
; CHECK-NEXT: ret i32 [[RES]]
128+
;
98129

99130
%b_sub = call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
100131
%a_sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 223)
@@ -104,23 +135,72 @@ define i32 @commuted_test_neg(i32 %a, i32 %b) {
104135
ret i32 %res
105136
}
106137
define <4 x i32> @vector_test(<4 x i32> %a, <4 x i32> %b) {
107-
; CHECK-LABEL: @vector_test(
108-
; CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %a, <4 x i32> splat (i32 224))
109-
; CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %b, <4 x i32> splat (i32 240))
110-
; CHECK-NEXT: or <4 x i32>
111-
; CHECK-NEXT: and <4 x i32>
112-
; CHECK-NEXT: ret <4 x i32>
138+
; CHECK-LABEL: define <4 x i32> @vector_test(
139+
; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
140+
; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> splat (i32 224))
141+
; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 240))
142+
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]]
143+
; CHECK-NEXT: [[RES:%.*]] = and <4 x i32> [[TMP3]], splat (i32 -2147483648)
144+
; CHECK-NEXT: ret <4 x i32> [[RES]]
145+
;
146+
147+
148+
%a_sub = call <4 x i32> @llvm.usub.sat.v4i32(
149+
<4 x i32> %a,
150+
<4 x i32> <i32 2147483871, i32 2147483871, i32 2147483871, i32 2147483871>)
151+
%b_sub = call <4 x i32> @llvm.usub.sat.v4i32(
152+
<4 x i32> %b,
153+
<4 x i32> <i32 2147483887, i32 2147483887, i32 2147483887, i32 2147483887>)
154+
%or = or <4 x i32> %a_sub, %b_sub
155+
%cmp = icmp eq <4 x i32> %or, zeroinitializer
156+
%res = select <4 x i1> %cmp, <4 x i32> zeroinitializer,
157+
<4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
158+
ret <4 x i32> %res
159+
}
160+
161+
define <4 x i32> @vector_negative_test(<4 x i32> %a, <4 x i32> %b) {
162+
; CHECK-LABEL: define <4 x i32> @vector_negative_test(
163+
; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
164+
; CHECK-NEXT: [[A_SUB:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> <i32 -2147483425, i32 0, i32 -2147483425, i32 -2147483425>)
165+
; CHECK-NEXT: [[B_SUB:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 -2147483409))
166+
; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[A_SUB]], [[B_SUB]]
167+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[OR]], zeroinitializer
168+
; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> splat (i32 -2147483648)
169+
; CHECK-NEXT: ret <4 x i32> [[RES]]
170+
;
171+
%a_sub = call <4 x i32> @llvm.usub.sat.v4i32(
172+
<4 x i32> %a,
173+
<4 x i32> <i32 2147483871, i32 0, i32 2147483871, i32 2147483871>)
174+
%b_sub = call <4 x i32> @llvm.usub.sat.v4i32(
175+
<4 x i32> %b,
176+
<4 x i32> <i32 2147483887, i32 2147483887, i32 2147483887, i32 2147483887>)
177+
%or = or <4 x i32> %a_sub, %b_sub
178+
%cmp = icmp eq <4 x i32> %or, zeroinitializer
179+
%res = select <4 x i1> %cmp, <4 x i32> zeroinitializer,
180+
<4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
181+
ret <4 x i32> %res
182+
}
183+
184+
define <4 x i32> @vector_ne_test(<4 x i32> %a, <4 x i32> %b) {
185+
; CHECK-LABEL: define <4 x i32> @vector_ne_test(
186+
; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
187+
; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> splat (i32 224))
188+
; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 240))
189+
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]]
190+
; CHECK-NEXT: [[RES:%.*]] = and <4 x i32> [[TMP3]], splat (i32 -2147483648)
191+
; CHECK-NEXT: ret <4 x i32> [[RES]]
192+
;
113193

114194

115195
%a_sub = call <4 x i32> @llvm.usub.sat.v4i32(
116-
<4 x i32> %a,
117-
<4 x i32> <i32 2147483871, i32 2147483871, i32 2147483871, i32 2147483871>)
196+
<4 x i32> %a,
197+
<4 x i32> <i32 2147483871, i32 2147483871, i32 2147483871, i32 2147483871>)
118198
%b_sub = call <4 x i32> @llvm.usub.sat.v4i32(
119-
<4 x i32> %b,
120-
<4 x i32> <i32 2147483887, i32 2147483887, i32 2147483887, i32 2147483887>)
199+
<4 x i32> %b,
200+
<4 x i32> <i32 2147483887, i32 2147483887, i32 2147483887, i32 2147483887>)
121201
%or = or <4 x i32> %a_sub, %b_sub
122202
%cmp = icmp eq <4 x i32> %or, zeroinitializer
123203
%res = select <4 x i1> %cmp, <4 x i32> zeroinitializer,
124-
<4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
204+
<4 x i32> <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>
125205
ret <4 x i32> %res
126206
}

0 commit comments

Comments
 (0)