Skip to content

Commit 5e6ea3c

Browse files
committed
[InstCombine] Make the (icmp eq/ne (and X, Y), X) canonicalization work for non-const operands
We currently do: `(icmp eq/ne (and X, Y), Y)` -> `(icmp eq/ne (and ~X, Y), 0)` if `X` is constant. We can make this more general and do it if `X` is freely invertable (i.e say `X = ~Z`). As well, we can also do: `(icmp eq/ne (and X, Y), Y)` -> `(icmp eq/ne (or X, ~Y), -1)` If `Y` is freely invertible. Proofs: https://alive2.llvm.org/ce/z/yeWH3E Differential Revision: https://reviews.llvm.org/D159059
1 parent e7175b0 commit 5e6ea3c

7 files changed

+74
-74
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4709,6 +4709,26 @@ static Instruction *foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q,
47094709
if (Pred == ICmpInst::ICMP_UGE)
47104710
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
47114711

4712+
if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) {
4713+
// icmp (X & Y) eq/ne Y --> (X | ~Y) eq/ne -1 if Y is freely invertible and
4714+
// Y is non-constant. If Y is constant this form is preferable (and
4715+
// canonicalize too it elsewhere).
4716+
if (!match(Op1, m_ImmConstant()))
4717+
if (auto *NotOp1 =
4718+
IC.getFreelyInverted(Op1, !Op1->hasNUsesOrMore(3), &IC.Builder))
4719+
return new ICmpInst(Pred, IC.Builder.CreateOr(A, NotOp1),
4720+
Constant::getAllOnesValue(Op1->getType()));
4721+
// icmp (X & Y) eq/ne Y --> (~X & Y) eq/ne 0 if X is freely invertible.
4722+
// Since we may be consuming a `not` here, first check if we match
4723+
// `foldICmpWithLowBitMaskedVal` as it is a "better" user of `not`
4724+
// instructions.
4725+
if (Value *R = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, IC))
4726+
return IC.replaceInstUsesWith(I, R);
4727+
if (auto *NotA = IC.getFreelyInverted(A, A->hasOneUse(), &IC.Builder))
4728+
return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, NotA),
4729+
Constant::getNullValue(Op1->getType()));
4730+
}
4731+
47124732
return nullptr;
47134733
}
47144734

@@ -5485,21 +5505,6 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
54855505
}
54865506
}
54875507

5488-
// canoncalize:
5489-
// (icmp eq/ne (and X, C), X)
5490-
// -> (icmp eq/ne (and X, ~C), 0)
5491-
{
5492-
Constant *CMask;
5493-
A = nullptr;
5494-
if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_ImmConstant(CMask)))))
5495-
A = Op1;
5496-
else if (match(Op1, m_OneUse(m_And(m_Specific(Op0), m_ImmConstant(CMask)))))
5497-
A = Op0;
5498-
if (A)
5499-
return new ICmpInst(Pred, Builder.CreateAnd(A, Builder.CreateNot(CMask)),
5500-
Constant::getNullValue(A->getType()));
5501-
}
5502-
55035508
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) {
55045509
// A == (A^B) -> B == 0
55055510
Value *OtherVal = A == Op0 ? B : A;

llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-eq-to-icmp-ule.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,8 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
269269
define i1 @n1(i8 %x, i8 %y) {
270270
; CHECK-LABEL: @n1(
271271
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
272-
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
273-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
274-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
272+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[T0]], [[X:%.*]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP1]], 0
275274
; CHECK-NEXT: ret i1 [[RET]]
276275
;
277276
%t0 = shl i8 1, %y ; not -1
@@ -284,9 +283,9 @@ define i1 @n1(i8 %x, i8 %y) {
284283
define i1 @n2(i8 %x, i8 %y) {
285284
; CHECK-LABEL: @n2(
286285
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
287-
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], 1
286+
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -2
288287
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
289-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
288+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
290289
; CHECK-NEXT: ret i1 [[RET]]
291290
;
292291
%t0 = shl i8 -1, %y

llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v2-and-icmp-ne-to-icmp-ugt.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,8 @@ define i1 @n0(i8 %x, i8 %y, i8 %notx) {
269269
define i1 @n1(i8 %x, i8 %y) {
270270
; CHECK-LABEL: @n1(
271271
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
272-
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -1
273-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
274-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
272+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[T0]], [[X:%.*]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP1]], 0
275274
; CHECK-NEXT: ret i1 [[RET]]
276275
;
277276
%t0 = shl i8 1, %y ; not -1
@@ -284,9 +283,9 @@ define i1 @n1(i8 %x, i8 %y) {
284283
define i1 @n2(i8 %x, i8 %y) {
285284
; CHECK-LABEL: @n2(
286285
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
287-
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], 1
286+
; CHECK-NEXT: [[T1:%.*]] = xor i8 [[T0]], -2
288287
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
289-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
288+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
290289
; CHECK-NEXT: ret i1 [[RET]]
291290
;
292291
%t0 = shl i8 -1, %y

llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-eq-to-icmp-ule.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ define i1 @n1(i8 %x, i8 %y) {
251251
; CHECK-LABEL: @n1(
252252
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
253253
; CHECK-NEXT: call void @use8(i8 [[T0]])
254-
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
254+
; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]]
255255
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
256-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
256+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
257257
; CHECK-NEXT: ret i1 [[RET]]
258258
;
259259
%t0 = shl i8 -1, %y ; not 1
@@ -268,9 +268,9 @@ define i1 @n2(i8 %x, i8 %y) {
268268
; CHECK-LABEL: @n2(
269269
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
270270
; CHECK-NEXT: call void @use8(i8 [[T0]])
271-
; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
271+
; CHECK-NEXT: [[T1:%.*]] = sub nuw i8 -2, [[T0]]
272272
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
273-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], 0
274274
; CHECK-NEXT: ret i1 [[RET]]
275275
;
276276
%t0 = shl i8 1, %y

llvm/test/Transforms/InstCombine/canonicalize-low-bit-mask-v3-and-icmp-ne-to-icmp-ugt.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ define i1 @n1(i8 %x, i8 %y) {
251251
; CHECK-LABEL: @n1(
252252
; CHECK-NEXT: [[T0:%.*]] = shl nsw i8 -1, [[Y:%.*]]
253253
; CHECK-NEXT: call void @use8(i8 [[T0]])
254-
; CHECK-NEXT: [[T1:%.*]] = add i8 [[T0]], -1
254+
; CHECK-NEXT: [[T1:%.*]] = sub i8 0, [[T0]]
255255
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
256-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
256+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
257257
; CHECK-NEXT: ret i1 [[RET]]
258258
;
259259
%t0 = shl i8 -1, %y ; not 1
@@ -268,9 +268,9 @@ define i1 @n2(i8 %x, i8 %y) {
268268
; CHECK-LABEL: @n2(
269269
; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[Y:%.*]]
270270
; CHECK-NEXT: call void @use8(i8 [[T0]])
271-
; CHECK-NEXT: [[T1:%.*]] = add nuw i8 [[T0]], 1
271+
; CHECK-NEXT: [[T1:%.*]] = sub nuw i8 -2, [[T0]]
272272
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
273-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], 0
274274
; CHECK-NEXT: ret i1 [[RET]]
275275
;
276276
%t0 = shl i8 1, %y

llvm/test/Transforms/InstCombine/icmp-and-lowbit-mask.ll

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ declare void @use.i8(i8)
55
declare void @use.i16(i16)
66
define i1 @src_is_mask_zext(i16 %x_in, i8 %y) {
77
; CHECK-LABEL: @src_is_mask_zext(
8-
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
98
; CHECK-NEXT: [[M_IN:%.*]] = lshr i8 -1, [[Y:%.*]]
109
; CHECK-NEXT: [[MASK:%.*]] = zext i8 [[M_IN]] to i16
10+
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
1111
; CHECK-NEXT: [[R:%.*]] = icmp ule i16 [[X]], [[MASK]]
1212
; CHECK-NEXT: ret i1 [[R]]
1313
;
@@ -22,11 +22,11 @@ define i1 @src_is_mask_zext(i16 %x_in, i8 %y) {
2222

2323
define i1 @src_is_mask_zext_fail_not_mask(i16 %x_in, i8 %y) {
2424
; CHECK-LABEL: @src_is_mask_zext_fail_not_mask(
25-
; CHECK-NEXT: [[X:%.*]] = xor i16 [[X_IN:%.*]], 123
2625
; CHECK-NEXT: [[M_IN:%.*]] = lshr i8 -2, [[Y:%.*]]
2726
; CHECK-NEXT: [[MASK:%.*]] = zext i8 [[M_IN]] to i16
28-
; CHECK-NEXT: [[AND:%.*]] = and i16 [[X]], [[MASK]]
29-
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[AND]], [[X]]
27+
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -124
28+
; CHECK-NEXT: [[TMP2:%.*]] = or i16 [[TMP1]], [[MASK]]
29+
; CHECK-NEXT: [[R:%.*]] = icmp eq i16 [[TMP2]], -1
3030
; CHECK-NEXT: ret i1 [[R]]
3131
;
3232
%x = xor i16 %x_in, 123
@@ -80,10 +80,10 @@ define i1 @src_is_mask_sext_fail_multiuse(i16 %x_in, i8 %y) {
8080

8181
define i1 @src_is_mask_and(i8 %x_in, i8 %y, i8 %z) {
8282
; CHECK-LABEL: @src_is_mask_and(
83-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
8483
; CHECK-NEXT: [[MY:%.*]] = lshr i8 7, [[Y:%.*]]
8584
; CHECK-NEXT: [[MZ:%.*]] = lshr i8 -1, [[Z:%.*]]
8685
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], [[MZ]]
86+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
8787
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
8888
; CHECK-NEXT: ret i1 [[R]]
8989
;
@@ -99,12 +99,12 @@ define i1 @src_is_mask_and(i8 %x_in, i8 %y, i8 %z) {
9999

100100
define i1 @src_is_mask_and_fail_mixed(i8 %x_in, i8 %y, i8 %z) {
101101
; CHECK-LABEL: @src_is_mask_and_fail_mixed(
102-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
103102
; CHECK-NEXT: [[MY:%.*]] = ashr i8 -8, [[Y:%.*]]
104103
; CHECK-NEXT: [[MZ:%.*]] = lshr i8 -1, [[Z:%.*]]
105104
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], [[MZ]]
106-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[MASK]]
107-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[AND]]
105+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
106+
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[MASK]], [[TMP1]]
107+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1
108108
; CHECK-NEXT: ret i1 [[R]]
109109
;
110110
%x = xor i8 %x_in, 123
@@ -119,9 +119,9 @@ define i1 @src_is_mask_and_fail_mixed(i8 %x_in, i8 %y, i8 %z) {
119119

120120
define i1 @src_is_mask_or(i8 %x_in, i8 %y) {
121121
; CHECK-LABEL: @src_is_mask_or(
122-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
123122
; CHECK-NEXT: [[MY:%.*]] = lshr i8 -1, [[Y:%.*]]
124123
; CHECK-NEXT: [[MASK:%.*]] = and i8 [[MY]], 7
124+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
125125
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
126126
; CHECK-NEXT: ret i1 [[R]]
127127
;
@@ -136,9 +136,9 @@ define i1 @src_is_mask_or(i8 %x_in, i8 %y) {
136136

137137
define i1 @src_is_mask_xor(i8 %x_in, i8 %y) {
138138
; CHECK-LABEL: @src_is_mask_xor(
139-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
140139
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
141140
; CHECK-NEXT: [[MASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
141+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
142142
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
143143
; CHECK-NEXT: ret i1 [[R]]
144144
;
@@ -152,11 +152,11 @@ define i1 @src_is_mask_xor(i8 %x_in, i8 %y) {
152152

153153
define i1 @src_is_mask_xor_fail_notmask(i8 %x_in, i8 %y) {
154154
; CHECK-LABEL: @src_is_mask_xor_fail_notmask(
155-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
156155
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[Y:%.*]]
157156
; CHECK-NEXT: [[NOTMASK:%.*]] = xor i8 [[TMP1]], [[Y]]
158-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[NOTMASK]]
159-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[X]]
157+
; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[X_IN:%.*]], -124
158+
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[NOTMASK]], [[TMP2]]
159+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP3]], -1
160160
; CHECK-NEXT: ret i1 [[R]]
161161
;
162162
%x = xor i8 %x_in, 123
@@ -170,10 +170,10 @@ define i1 @src_is_mask_xor_fail_notmask(i8 %x_in, i8 %y) {
170170

171171
define i1 @src_is_mask_select(i8 %x_in, i8 %y, i1 %cond) {
172172
; CHECK-LABEL: @src_is_mask_select(
173-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
174173
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
175174
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
176175
; CHECK-NEXT: [[MASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
176+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
177177
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
178178
; CHECK-NEXT: ret i1 [[R]]
179179
;
@@ -245,11 +245,11 @@ define i1 @src_is_mask_shl_lshr_fail_not_allones(i8 %x_in, i8 %y, i1 %cond) {
245245

246246
define i1 @src_is_mask_lshr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
247247
; CHECK-LABEL: @src_is_mask_lshr(
248-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
249248
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
250249
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
251250
; CHECK-NEXT: [[SMASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
252251
; CHECK-NEXT: [[MASK:%.*]] = lshr i8 [[SMASK]], [[Z:%.*]]
252+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
253253
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
254254
; CHECK-NEXT: ret i1 [[R]]
255255
;
@@ -265,11 +265,11 @@ define i1 @src_is_mask_lshr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
265265

266266
define i1 @src_is_mask_ashr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
267267
; CHECK-LABEL: @src_is_mask_ashr(
268-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
269268
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
270269
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
271270
; CHECK-NEXT: [[SMASK:%.*]] = select i1 [[COND:%.*]], i8 [[YMASK]], i8 15
272271
; CHECK-NEXT: [[MASK:%.*]] = ashr i8 [[SMASK]], [[Z:%.*]]
272+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
273273
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
274274
; CHECK-NEXT: ret i1 [[R]]
275275
;
@@ -285,9 +285,9 @@ define i1 @src_is_mask_ashr(i8 %x_in, i8 %y, i8 %z, i1 %cond) {
285285

286286
define i1 @src_is_mask_p2_m1(i8 %x_in, i8 %y) {
287287
; CHECK-LABEL: @src_is_mask_p2_m1(
288-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
289288
; CHECK-NEXT: [[P2ORZ:%.*]] = shl i8 2, [[Y:%.*]]
290289
; CHECK-NEXT: [[MASK:%.*]] = add i8 [[P2ORZ]], -1
290+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
291291
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
292292
; CHECK-NEXT: ret i1 [[R]]
293293
;
@@ -301,10 +301,10 @@ define i1 @src_is_mask_p2_m1(i8 %x_in, i8 %y) {
301301

302302
define i1 @src_is_mask_umax(i8 %x_in, i8 %y) {
303303
; CHECK-LABEL: @src_is_mask_umax(
304-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
305304
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
306305
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
307306
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umax.i8(i8 [[YMASK]], i8 3)
307+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
308308
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
309309
; CHECK-NEXT: ret i1 [[R]]
310310
;
@@ -320,11 +320,11 @@ define i1 @src_is_mask_umax(i8 %x_in, i8 %y) {
320320

321321
define i1 @src_is_mask_umin(i8 %x_in, i8 %y, i8 %z) {
322322
; CHECK-LABEL: @src_is_mask_umin(
323-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
324323
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
325324
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
326325
; CHECK-NEXT: [[ZMASK:%.*]] = lshr i8 15, [[Z:%.*]]
327326
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umin.i8(i8 [[YMASK]], i8 [[ZMASK]])
327+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
328328
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], [[MASK]]
329329
; CHECK-NEXT: ret i1 [[R]]
330330
;
@@ -341,12 +341,12 @@ define i1 @src_is_mask_umin(i8 %x_in, i8 %y, i8 %z) {
341341

342342
define i1 @src_is_mask_umin_fail_mismatch(i8 %x_in, i8 %y) {
343343
; CHECK-LABEL: @src_is_mask_umin_fail_mismatch(
344-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
345344
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
346345
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
347346
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umin.i8(i8 [[YMASK]], i8 -32)
348-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X]]
349-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[X]]
347+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
348+
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[MASK]], [[TMP1]]
349+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP2]], -1
350350
; CHECK-NEXT: ret i1 [[R]]
351351
;
352352
%x = xor i8 %x_in, 123
@@ -361,10 +361,10 @@ define i1 @src_is_mask_umin_fail_mismatch(i8 %x_in, i8 %y) {
361361

362362
define i1 @src_is_mask_smax(i8 %x_in, i8 %y) {
363363
; CHECK-LABEL: @src_is_mask_smax(
364-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
365364
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
366365
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
367366
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.smax.i8(i8 [[YMASK]], i8 -1)
367+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
368368
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
369369
; CHECK-NEXT: ret i1 [[R]]
370370
;
@@ -380,10 +380,10 @@ define i1 @src_is_mask_smax(i8 %x_in, i8 %y) {
380380

381381
define i1 @src_is_mask_smin(i8 %x_in, i8 %y) {
382382
; CHECK-LABEL: @src_is_mask_smin(
383-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
384383
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
385384
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
386385
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.smin.i8(i8 [[YMASK]], i8 0)
386+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
387387
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
388388
; CHECK-NEXT: ret i1 [[R]]
389389
;
@@ -399,9 +399,9 @@ define i1 @src_is_mask_smin(i8 %x_in, i8 %y) {
399399

400400
define i1 @src_is_mask_bitreverse_not_mask(i8 %x_in, i8 %y) {
401401
; CHECK-LABEL: @src_is_mask_bitreverse_not_mask(
402-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
403402
; CHECK-NEXT: [[NMASK:%.*]] = shl nsw i8 -1, [[Y:%.*]]
404403
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[NMASK]])
404+
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
405405
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[X]], [[MASK]]
406406
; CHECK-NEXT: ret i1 [[R]]
407407
;
@@ -417,7 +417,7 @@ define i1 @src_is_mask_bitreverse_not_mask(i8 %x_in, i8 %y) {
417417
define i1 @src_is_notmask_sext(i16 %x_in, i8 %y) {
418418
; CHECK-LABEL: @src_is_notmask_sext(
419419
; CHECK-NEXT: [[M_IN:%.*]] = shl i8 -8, [[Y:%.*]]
420-
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -124
420+
; CHECK-NEXT: [[TMP1:%.*]] = xor i16 [[X_IN:%.*]], -128
421421
; CHECK-NEXT: [[TMP2:%.*]] = sext i8 [[M_IN]] to i16
422422
; CHECK-NEXT: [[R:%.*]] = icmp uge i16 [[TMP1]], [[TMP2]]
423423
; CHECK-NEXT: ret i1 [[R]]
@@ -529,12 +529,11 @@ define i1 @src_is_notmask_lshr_shl(i8 %x_in, i8 %y) {
529529

530530
define i1 @src_is_notmask_lshr_shl_fail_mismatch_shifts(i8 %x_in, i8 %y, i8 %z) {
531531
; CHECK-LABEL: @src_is_notmask_lshr_shl_fail_mismatch_shifts(
532-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
533532
; CHECK-NEXT: [[MASK_SHR:%.*]] = lshr i8 -1, [[Y:%.*]]
534533
; CHECK-NEXT: [[NMASK:%.*]] = shl i8 [[MASK_SHR]], [[Z:%.*]]
535-
; CHECK-NEXT: [[MASK:%.*]] = xor i8 [[NMASK]], -1
536-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[MASK]]
537-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
534+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], 123
535+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[NMASK]]
536+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], 0
538537
; CHECK-NEXT: ret i1 [[R]]
539538
;
540539
%x = xor i8 %x_in, 123

0 commit comments

Comments
 (0)