Skip to content

Commit 72b8d41

Browse files
committedJul 1, 2019
[InstCombine] Shift amount reassociation in bittest (PR42399)
Summary: Given pattern: `icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0` we should move shifts to the same hand of 'and', i.e. rewrite as `icmp eq/ne (and (x shift (Q+K)), y), 0` iff `(Q+K) u< bitwidth(x)` It might be tempting to not restrict this to situations where we know we'd fold two shifts together, but i'm not sure what rules should there be to avoid endless combine loops. We pick the same shift that was originally used to shift the variable we picked to shift: https://rise4fun.com/Alive/6x1v Should fix [[ https://bugs.llvm.org/show_bug.cgi?id=42399 | PR42399]]. Reviewers: spatel, nikic, RKSimon Reviewed By: spatel Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63829 llvm-svn: 364791
1 parent 5abf80c commit 72b8d41

File tree

2 files changed

+148
-108
lines changed

2 files changed

+148
-108
lines changed
 

Diff for: ‎llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -3270,6 +3270,63 @@ foldICmpWithTruncSignExtendedVal(ICmpInst &I,
32703270
return T1;
32713271
}
32723272

3273+
// Given pattern:
3274+
// icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0
3275+
// we should move shifts to the same hand of 'and', i.e. rewrite as
3276+
// icmp eq/ne (and (x shift (Q+K)), y), 0 iff (Q+K) u< bitwidth(x)
3277+
// We are only interested in opposite logical shifts here.
3278+
// If we can, we want to end up creating 'lshr' shift.
3279+
static Value *
3280+
foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ,
3281+
InstCombiner::BuilderTy &Builder) {
3282+
if (!I.isEquality() || !match(I.getOperand(1), m_Zero()) ||
3283+
!I.getOperand(0)->hasOneUse())
3284+
return nullptr;
3285+
3286+
auto m_AnyLogicalShift = m_LogicalShift(m_Value(), m_Value());
3287+
auto m_AnyLShr = m_LShr(m_Value(), m_Value());
3288+
3289+
// Look for an 'and' of two (opposite) logical shifts.
3290+
// Pick the single-use shift as XShift.
3291+
Value *XShift, *YShift;
3292+
if (!match(I.getOperand(0),
3293+
m_c_And(m_OneUse(m_CombineAnd(m_AnyLogicalShift, m_Value(XShift))),
3294+
m_CombineAnd(m_AnyLogicalShift, m_Value(YShift)))))
3295+
return nullptr;
3296+
3297+
// If YShift is a single-use 'lshr', swap the shifts around.
3298+
if (match(YShift, m_OneUse(m_AnyLShr)))
3299+
std::swap(XShift, YShift);
3300+
3301+
// The shifts must be in opposite directions.
3302+
Instruction::BinaryOps XShiftOpcode =
3303+
cast<BinaryOperator>(XShift)->getOpcode();
3304+
if (XShiftOpcode == cast<BinaryOperator>(YShift)->getOpcode())
3305+
return nullptr; // Do not care about same-direction shifts here.
3306+
3307+
Value *X, *XShAmt, *Y, *YShAmt;
3308+
match(XShift, m_BinOp(m_Value(X), m_Value(XShAmt)));
3309+
match(YShift, m_BinOp(m_Value(Y), m_Value(YShAmt)));
3310+
3311+
// Can we fold (XShAmt+YShAmt) ?
3312+
Value *NewShAmt = SimplifyBinOp(Instruction::BinaryOps::Add, XShAmt, YShAmt,
3313+
SQ.getWithInstruction(&I));
3314+
if (!NewShAmt)
3315+
return nullptr;
3316+
// Is the new shift amount smaller than the bit width?
3317+
// FIXME: could also rely on ConstantRange.
3318+
unsigned BitWidth = X->getType()->getScalarSizeInBits();
3319+
if (!match(NewShAmt, m_SpecificInt_ULT(APInt(BitWidth, BitWidth))))
3320+
return nullptr;
3321+
// All good, we can do this fold. The shift is the same that was for X.
3322+
Value *T0 = XShiftOpcode == Instruction::BinaryOps::LShr
3323+
? Builder.CreateLShr(X, NewShAmt)
3324+
: Builder.CreateShl(X, NewShAmt);
3325+
Value *T1 = Builder.CreateAnd(T0, Y);
3326+
return Builder.CreateICmp(I.getPredicate(), T1,
3327+
Constant::getNullValue(X->getType()));
3328+
}
3329+
32733330
/// Try to fold icmp (binop), X or icmp X, (binop).
32743331
/// TODO: A large part of this logic is duplicated in InstSimplify's
32753332
/// simplifyICmpWithBinOp(). We should be able to share that and avoid the code
@@ -3625,6 +3682,9 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) {
36253682
if (Value *V = foldICmpWithTruncSignExtendedVal(I, Builder))
36263683
return replaceInstUsesWith(I, V);
36273684

3685+
if (Value *V = foldShiftIntoShiftInAnotherHandOfAndInICmp(I, SQ, Builder))
3686+
return replaceInstUsesWith(I, V);
3687+
36283688
return nullptr;
36293689
}
36303690

Diff for: ‎llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll

+88-108
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@
1111

1212
define i1 @t0_const_lshr_shl_ne(i32 %x, i32 %y) {
1313
; CHECK-LABEL: @t0_const_lshr_shl_ne(
14-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
15-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
16-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
17-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
18-
; CHECK-NEXT: ret i1 [[T3]]
14+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
15+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
16+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
17+
; CHECK-NEXT: ret i1 [[TMP3]]
1918
;
2019
%t0 = lshr i32 %x, 1
2120
%t1 = shl i32 %y, 1
@@ -25,11 +24,10 @@ define i1 @t0_const_lshr_shl_ne(i32 %x, i32 %y) {
2524
}
2625
define i1 @t1_const_shl_lshr_ne(i32 %x, i32 %y) {
2726
; CHECK-LABEL: @t1_const_shl_lshr_ne(
28-
; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 1
29-
; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[Y:%.*]], 1
30-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
31-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
32-
; CHECK-NEXT: ret i1 [[T3]]
27+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 2
28+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
29+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
30+
; CHECK-NEXT: ret i1 [[TMP3]]
3331
;
3432
%t0 = shl i32 %x, 1
3533
%t1 = lshr i32 %y, 1
@@ -41,11 +39,10 @@ define i1 @t1_const_shl_lshr_ne(i32 %x, i32 %y) {
4139
; We are ok with 'eq' predicate too.
4240
define i1 @t2_const_lshr_shl_eq(i32 %x, i32 %y) {
4341
; CHECK-LABEL: @t2_const_lshr_shl_eq(
44-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
45-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
46-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
47-
; CHECK-NEXT: [[T3:%.*]] = icmp eq i32 [[T2]], 0
48-
; CHECK-NEXT: ret i1 [[T3]]
42+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
43+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
44+
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
45+
; CHECK-NEXT: ret i1 [[TMP3]]
4946
;
5047
%t0 = lshr i32 %x, 1
5148
%t1 = shl i32 %y, 1
@@ -58,13 +55,10 @@ define i1 @t2_const_lshr_shl_eq(i32 %x, i32 %y) {
5855

5956
define i1 @t3_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
6057
; CHECK-LABEL: @t3_const_after_fold_lshr_shl_ne(
61-
; CHECK-NEXT: [[T0:%.*]] = sub i32 32, [[LEN:%.*]]
62-
; CHECK-NEXT: [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]
63-
; CHECK-NEXT: [[T2:%.*]] = add i32 [[LEN]], -1
64-
; CHECK-NEXT: [[T3:%.*]] = shl i32 [[Y:%.*]], [[T2]]
65-
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T1]], [[T3]]
66-
; CHECK-NEXT: [[T5:%.*]] = icmp ne i32 [[T4]], 0
67-
; CHECK-NEXT: ret i1 [[T5]]
58+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
59+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
60+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
61+
; CHECK-NEXT: ret i1 [[TMP3]]
6862
;
6963
%t0 = sub i32 32, %len
7064
%t1 = lshr i32 %x, %t0
@@ -76,13 +70,10 @@ define i1 @t3_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
7670
}
7771
define i1 @t4_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
7872
; CHECK-LABEL: @t4_const_after_fold_lshr_shl_ne(
79-
; CHECK-NEXT: [[T0:%.*]] = sub i32 32, [[LEN:%.*]]
80-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[X:%.*]], [[T0]]
81-
; CHECK-NEXT: [[T2:%.*]] = add i32 [[LEN]], -1
82-
; CHECK-NEXT: [[T3:%.*]] = lshr i32 [[Y:%.*]], [[T2]]
83-
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T1]], [[T3]]
84-
; CHECK-NEXT: [[T5:%.*]] = icmp ne i32 [[T4]], 0
85-
; CHECK-NEXT: ret i1 [[T5]]
73+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 31
74+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
75+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
76+
; CHECK-NEXT: ret i1 [[TMP3]]
8677
;
8778
%t0 = sub i32 32, %len
8879
%t1 = shl i32 %x, %t0
@@ -128,11 +119,10 @@ define i1 @t6_const_shl_lshr_ne(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
128119

129120
define <2 x i1> @t7_const_lshr_shl_ne_vec_splat(<2 x i32> %x, <2 x i32> %y) {
130121
; CHECK-LABEL: @t7_const_lshr_shl_ne_vec_splat(
131-
; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 1, i32 1>
132-
; CHECK-NEXT: [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 1, i32 1>
133-
; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]
134-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
135-
; CHECK-NEXT: ret <2 x i1> [[T3]]
122+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 2, i32 2>
123+
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]
124+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
125+
; CHECK-NEXT: ret <2 x i1> [[TMP3]]
136126
;
137127
%t0 = lshr <2 x i32> %x, <i32 1, i32 1>
138128
%t1 = shl <2 x i32> %y, <i32 1, i32 1>
@@ -142,11 +132,10 @@ define <2 x i1> @t7_const_lshr_shl_ne_vec_splat(<2 x i32> %x, <2 x i32> %y) {
142132
}
143133
define <2 x i1> @t8_const_lshr_shl_ne_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
144134
; CHECK-LABEL: @t8_const_lshr_shl_ne_vec_nonsplat(
145-
; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 1, i32 2>
146-
; CHECK-NEXT: [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 3, i32 4>
147-
; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]
148-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
149-
; CHECK-NEXT: ret <2 x i1> [[T3]]
135+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 6>
136+
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]
137+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
138+
; CHECK-NEXT: ret <2 x i1> [[TMP3]]
150139
;
151140
%t0 = lshr <2 x i32> %x, <i32 1, i32 2>
152141
%t1 = shl <2 x i32> %y, <i32 3, i32 4>
@@ -156,11 +145,10 @@ define <2 x i1> @t8_const_lshr_shl_ne_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
156145
}
157146
define <3 x i1> @t9_const_lshr_shl_ne_vec_undef0(<3 x i32> %x, <3 x i32> %y) {
158147
; CHECK-LABEL: @t9_const_lshr_shl_ne_vec_undef0(
159-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 undef, i32 1>
160-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 1, i32 1>
161-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
162-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], zeroinitializer
163-
; CHECK-NEXT: ret <3 x i1> [[T3]]
148+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
149+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
150+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
151+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
164152
;
165153
%t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
166154
%t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
@@ -170,11 +158,10 @@ define <3 x i1> @t9_const_lshr_shl_ne_vec_undef0(<3 x i32> %x, <3 x i32> %y) {
170158
}
171159
define <3 x i1> @t10_const_lshr_shl_ne_vec_undef1(<3 x i32> %x, <3 x i32> %y) {
172160
; CHECK-LABEL: @t10_const_lshr_shl_ne_vec_undef1(
173-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 1, i32 1>
174-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 undef, i32 1>
175-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
176-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], zeroinitializer
177-
; CHECK-NEXT: ret <3 x i1> [[T3]]
161+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
162+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
163+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
164+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
178165
;
179166
%t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
180167
%t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
@@ -184,11 +171,10 @@ define <3 x i1> @t10_const_lshr_shl_ne_vec_undef1(<3 x i32> %x, <3 x i32> %y) {
184171
}
185172
define <3 x i1> @t11_const_lshr_shl_ne_vec_undef2(<3 x i32> %x, <3 x i32> %y) {
186173
; CHECK-LABEL: @t11_const_lshr_shl_ne_vec_undef2(
187-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 1, i32 1>
188-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 1, i32 1>
189-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
190-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], <i32 0, i32 undef, i32 0>
191-
; CHECK-NEXT: ret <3 x i1> [[T3]]
174+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 2, i32 2>
175+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
176+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
177+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
192178
;
193179
%t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
194180
%t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
@@ -198,11 +184,10 @@ define <3 x i1> @t11_const_lshr_shl_ne_vec_undef2(<3 x i32> %x, <3 x i32> %y) {
198184
}
199185
define <3 x i1> @t12_const_lshr_shl_ne_vec_undef3(<3 x i32> %x, <3 x i32> %y) {
200186
; CHECK-LABEL: @t12_const_lshr_shl_ne_vec_undef3(
201-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 undef, i32 1>
202-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 undef, i32 1>
203-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
204-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], zeroinitializer
205-
; CHECK-NEXT: ret <3 x i1> [[T3]]
187+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
188+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
189+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
190+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
206191
;
207192
%t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
208193
%t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
@@ -212,11 +197,10 @@ define <3 x i1> @t12_const_lshr_shl_ne_vec_undef3(<3 x i32> %x, <3 x i32> %y) {
212197
}
213198
define <3 x i1> @t13_const_lshr_shl_ne_vec_undef4(<3 x i32> %x, <3 x i32> %y) {
214199
; CHECK-LABEL: @t13_const_lshr_shl_ne_vec_undef4(
215-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 1, i32 1>
216-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 undef, i32 1>
217-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
218-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], <i32 0, i32 undef, i32 0>
219-
; CHECK-NEXT: ret <3 x i1> [[T3]]
200+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
201+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
202+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
203+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
220204
;
221205
%t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
222206
%t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
@@ -226,11 +210,10 @@ define <3 x i1> @t13_const_lshr_shl_ne_vec_undef4(<3 x i32> %x, <3 x i32> %y) {
226210
}
227211
define <3 x i1> @t14_const_lshr_shl_ne_vec_undef5(<3 x i32> %x, <3 x i32> %y) {
228212
; CHECK-LABEL: @t14_const_lshr_shl_ne_vec_undef5(
229-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 undef, i32 1>
230-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 1, i32 1>
231-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
232-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], <i32 0, i32 undef, i32 0>
233-
; CHECK-NEXT: ret <3 x i1> [[T3]]
213+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
214+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
215+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
216+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
234217
;
235218
%t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
236219
%t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
@@ -240,11 +223,10 @@ define <3 x i1> @t14_const_lshr_shl_ne_vec_undef5(<3 x i32> %x, <3 x i32> %y) {
240223
}
241224
define <3 x i1> @t15_const_lshr_shl_ne_vec_undef6(<3 x i32> %x, <3 x i32> %y) {
242225
; CHECK-LABEL: @t15_const_lshr_shl_ne_vec_undef6(
243-
; CHECK-NEXT: [[T0:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 1, i32 undef, i32 1>
244-
; CHECK-NEXT: [[T1:%.*]] = shl <3 x i32> [[Y:%.*]], <i32 1, i32 undef, i32 1>
245-
; CHECK-NEXT: [[T2:%.*]] = and <3 x i32> [[T1]], [[T0]]
246-
; CHECK-NEXT: [[T3:%.*]] = icmp ne <3 x i32> [[T2]], <i32 0, i32 undef, i32 0>
247-
; CHECK-NEXT: ret <3 x i1> [[T3]]
226+
; CHECK-NEXT: [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
227+
; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
228+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
229+
; CHECK-NEXT: ret <3 x i1> [[TMP3]]
248230
;
249231
%t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
250232
%t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
@@ -260,11 +242,10 @@ declare i32 @gen32()
260242
define i1 @t16_commutativity0(i32 %x) {
261243
; CHECK-LABEL: @t16_commutativity0(
262244
; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
263-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
264-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
265-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
266-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
267-
; CHECK-NEXT: ret i1 [[T3]]
245+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
246+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
247+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
248+
; CHECK-NEXT: ret i1 [[TMP3]]
268249
;
269250
%y = call i32 @gen32()
270251
%t0 = lshr i32 %x, 1
@@ -277,11 +258,10 @@ define i1 @t16_commutativity0(i32 %x) {
277258
define i1 @t17_commutativity1(i32 %y) {
278259
; CHECK-LABEL: @t17_commutativity1(
279260
; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
280-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
281-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
282-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
283-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
284-
; CHECK-NEXT: ret i1 [[T3]]
261+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 2
262+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
263+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
264+
; CHECK-NEXT: ret i1 [[TMP3]]
285265
;
286266
%x = call i32 @gen32()
287267
%t0 = lshr i32 %x, 1
@@ -299,10 +279,10 @@ define i1 @t18_const_oneuse0(i32 %x, i32 %y) {
299279
; CHECK-LABEL: @t18_const_oneuse0(
300280
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
301281
; CHECK-NEXT: call void @use32(i32 [[T0]])
302-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
303-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
304-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
305-
; CHECK-NEXT: ret i1 [[T3]]
282+
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 2
283+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
284+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
285+
; CHECK-NEXT: ret i1 [[TMP3]]
306286
;
307287
%t0 = lshr i32 %x, 1
308288
call void @use32(i32 %t0)
@@ -313,12 +293,12 @@ define i1 @t18_const_oneuse0(i32 %x, i32 %y) {
313293
}
314294
define i1 @t19_const_oneuse1(i32 %x, i32 %y) {
315295
; CHECK-LABEL: @t19_const_oneuse1(
316-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
317296
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
318297
; CHECK-NEXT: call void @use32(i32 [[T1]])
319-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
320-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
321-
; CHECK-NEXT: ret i1 [[T3]]
298+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
299+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
300+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
301+
; CHECK-NEXT: ret i1 [[TMP3]]
322302
;
323303
%t0 = lshr i32 %x, 1
324304
%t1 = shl i32 %y, 1
@@ -548,10 +528,10 @@ define i1 @t32_commutativity0_oneuse0(i32 %x) {
548528
; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
549529
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
550530
; CHECK-NEXT: call void @use32(i32 [[T0]])
551-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
552-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
553-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
554-
; CHECK-NEXT: ret i1 [[T3]]
531+
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y]], 2
532+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
533+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
534+
; CHECK-NEXT: ret i1 [[TMP3]]
555535
;
556536
%y = call i32 @gen32()
557537
%t0 = lshr i32 %x, 1
@@ -564,12 +544,12 @@ define i1 @t32_commutativity0_oneuse0(i32 %x) {
564544
define i1 @t33_commutativity0_oneuse1(i32 %x) {
565545
; CHECK-LABEL: @t33_commutativity0_oneuse1(
566546
; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
567-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
568547
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
569548
; CHECK-NEXT: call void @use32(i32 [[T1]])
570-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
571-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
572-
; CHECK-NEXT: ret i1 [[T3]]
549+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
550+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
551+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
552+
; CHECK-NEXT: ret i1 [[TMP3]]
573553
;
574554
%y = call i32 @gen32()
575555
%t0 = lshr i32 %x, 1
@@ -585,10 +565,10 @@ define i1 @t34_commutativity1_oneuse0(i32 %y) {
585565
; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
586566
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
587567
; CHECK-NEXT: call void @use32(i32 [[T0]])
588-
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
589-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
590-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
591-
; CHECK-NEXT: ret i1 [[T3]]
568+
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[Y:%.*]], 2
569+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
570+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
571+
; CHECK-NEXT: ret i1 [[TMP3]]
592572
;
593573
%x = call i32 @gen32()
594574
%t0 = lshr i32 %x, 1
@@ -601,12 +581,12 @@ define i1 @t34_commutativity1_oneuse0(i32 %y) {
601581
define i1 @t35_commutativity1_oneuse1(i32 %y) {
602582
; CHECK-LABEL: @t35_commutativity1_oneuse1(
603583
; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
604-
; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
605584
; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
606585
; CHECK-NEXT: call void @use32(i32 [[T1]])
607-
; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
608-
; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
609-
; CHECK-NEXT: ret i1 [[T3]]
586+
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 2
587+
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
588+
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
589+
; CHECK-NEXT: ret i1 [[TMP3]]
610590
;
611591
%x = call i32 @gen32()
612592
%t0 = lshr i32 %x, 1

0 commit comments

Comments
 (0)
Please sign in to comment.