Skip to content

Commit 4ba8827

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 193b3d6 commit 4ba8827

7 files changed

+68
-69
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4651,6 +4651,22 @@ static Instruction *foldICmpAndXX(ICmpInst &I, const SimplifyQuery &Q,
46514651
if (Pred == ICmpInst::ICMP_UGE)
46524652
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
46534653

4654+
if (ICmpInst::isEquality(Pred) && Op0->hasOneUse()) {
4655+
// icmp (X & Y) eq/ne Y --> (X | ~Y) eq/ne -1 if Y is freely invertible and
4656+
// Y is non-constant. If Y is constant this form is preferable (and
4657+
// canonicalize too it elsewhere).
4658+
if (!match(Op1, m_ImmConstant()) &&
4659+
IC.isFreeToInvert(Op1, Op1->hasOneUse() || Op1->hasNUses(2)))
4660+
return new ICmpInst(Pred,
4661+
IC.Builder.CreateOr(A, IC.Builder.CreateNot(Op1)),
4662+
Constant::getAllOnesValue(Op1->getType()));
4663+
// icmp (X & Y) eq/ne Y --> (~X & Y) eq/ne 0 if X is freely invertible.
4664+
if (IC.isFreeToInvert(A, A->hasOneUse()))
4665+
return new ICmpInst(Pred,
4666+
IC.Builder.CreateAnd(Op1, IC.Builder.CreateNot(A)),
4667+
Constant::getNullValue(Op1->getType()));
4668+
}
4669+
46544670
return nullptr;
46554671
}
46564672

@@ -5185,9 +5201,6 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
51855201
if (Value *V = foldMultiplicationOverflowCheck(I))
51865202
return replaceInstUsesWith(I, V);
51875203

5188-
if (Instruction *R = foldICmpAndXX(I, Q, *this))
5189-
return R;
5190-
51915204
if (Value *V = foldICmpWithTruncSignExtendedVal(I, Builder))
51925205
return replaceInstUsesWith(I, V);
51935206

@@ -5427,21 +5440,6 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
54275440
}
54285441
}
54295442

5430-
// canoncalize:
5431-
// (icmp eq/ne (and X, C), X)
5432-
// -> (icmp eq/ne (and X, ~C), 0)
5433-
{
5434-
Constant *CMask;
5435-
A = nullptr;
5436-
if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_ImmConstant(CMask)))))
5437-
A = Op1;
5438-
else if (match(Op1, m_OneUse(m_And(m_Specific(Op0), m_ImmConstant(CMask)))))
5439-
A = Op0;
5440-
if (A)
5441-
return new ICmpInst(Pred, Builder.CreateAnd(A, Builder.CreateNot(CMask)),
5442-
Constant::getNullValue(A->getType()));
5443-
}
5444-
54455443
if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) {
54465444
// A == (A^B) -> B == 0
54475445
Value *OtherVal = A == Op0 ? B : A;
@@ -7221,6 +7219,11 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
72217219
foldICmpCommutative(I.getSwappedPredicate(), Op1, Op0, I))
72227220
return Res;
72237221

7222+
// Need this to be after foldICmpCommutative so we do mask folds before
7223+
// transforming the `and`.
7224+
if (Instruction *R = foldICmpAndXX(I, Q, *this))
7225+
return R;
7226+
72247227
if (I.isCommutative()) {
72257228
if (auto Pair = matchSymmetricPair(I.getOperand(0), I.getOperand(1))) {
72267229
replaceOperand(I, 0, Pair->first);

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

Lines changed: 5 additions & 6 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
288-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
289-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
286+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[T0]], -2
287+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
288+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP2]], 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: 5 additions & 6 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
288-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
289-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
286+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[T0]], -2
287+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
288+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP2]], 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: 6 additions & 6 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
255-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
256-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
254+
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[T0]]
255+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
256+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP2]], 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
272-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
273-
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[T2]], [[X]]
271+
; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 -2, [[T0]]
272+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP2]], 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: 6 additions & 6 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
255-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
256-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
254+
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 0, [[T0]]
255+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
256+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP2]], 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
272-
; CHECK-NEXT: [[T2:%.*]] = and i8 [[T1]], [[X:%.*]]
273-
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[T2]], [[X]]
271+
; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 -2, [[T0]]
272+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
273+
; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP2]], 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: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
@@ -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
@@ -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
@@ -342,12 +342,12 @@ define i1 @src_is_mask_umin(i8 %x_in, i8 %y, i8 %z) {
342342

343343
define i1 @src_is_mask_umin_fail_mismatch(i8 %x_in, i8 %y) {
344344
; CHECK-LABEL: @src_is_mask_umin_fail_mismatch(
345-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
346345
; CHECK-NEXT: [[Y_M1:%.*]] = add i8 [[Y:%.*]], -1
347346
; CHECK-NEXT: [[YMASK:%.*]] = xor i8 [[Y_M1]], [[Y]]
348347
; CHECK-NEXT: [[MASK:%.*]] = call i8 @llvm.umin.i8(i8 [[YMASK]], i8 -32)
349-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[MASK]], [[X]]
350-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND]], [[X]]
348+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
349+
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[MASK]], [[TMP1]]
350+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP2]], -1
351351
; CHECK-NEXT: ret i1 [[R]]
352352
;
353353
%x = xor i8 %x_in, 123
@@ -494,12 +494,12 @@ define i1 @src_is_notmask_lshr_shl(i8 %x_in, i8 %y) {
494494

495495
define i1 @src_is_notmask_lshr_shl_fail_mismatch_shifts(i8 %x_in, i8 %y, i8 %z) {
496496
; CHECK-LABEL: @src_is_notmask_lshr_shl_fail_mismatch_shifts(
497-
; CHECK-NEXT: [[X:%.*]] = xor i8 [[X_IN:%.*]], 123
498497
; CHECK-NEXT: [[MASK_SHR:%.*]] = lshr i8 -1, [[Y:%.*]]
499498
; CHECK-NEXT: [[NMASK:%.*]] = shl i8 [[MASK_SHR]], [[Z:%.*]]
500499
; CHECK-NEXT: [[MASK:%.*]] = xor i8 [[NMASK]], -1
501-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[MASK]]
502-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
500+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X_IN:%.*]], -124
501+
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], [[MASK]]
502+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1
503503
; CHECK-NEXT: ret i1 [[R]]
504504
;
505505
%x = xor i8 %x_in, 123

llvm/test/Transforms/InstCombine/icmp-of-and-x.ll

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,9 @@ define i1 @icmp_sle_negx_y_fail_maybe_zero(i8 %x, i8 %y) {
238238

239239
define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) {
240240
; CHECK-LABEL: @icmp_eq_x_invertable_y_todo(
241-
; CHECK-NEXT: [[YY:%.*]] = select i1 [[Y:%.*]], i8 7, i8 24
242-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
243-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
241+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
242+
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]]
243+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], 0
244244
; CHECK-NEXT: ret i1 [[R]]
245245
;
246246
%yy = select i1 %y, i8 7, i8 24
@@ -251,9 +251,8 @@ define i1 @icmp_eq_x_invertable_y_todo(i8 %x, i1 %y) {
251251

252252
define i1 @icmp_eq_x_invertable_y(i8 %x, i8 %y) {
253253
; CHECK-LABEL: @icmp_eq_x_invertable_y(
254-
; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], -1
255-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
256-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[X]]
254+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
255+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 0
257256
; CHECK-NEXT: ret i1 [[R]]
258257
;
259258
%yy = xor i8 %y, -1
@@ -264,9 +263,9 @@ define i1 @icmp_eq_x_invertable_y(i8 %x, i8 %y) {
264263

265264
define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) {
266265
; CHECK-LABEL: @icmp_eq_x_invertable_y2_todo(
267-
; CHECK-NEXT: [[YY:%.*]] = select i1 [[Y:%.*]], i8 7, i8 24
268-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
269-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[YY]], [[AND]]
266+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 -25
267+
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], [[X:%.*]]
268+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP2]], -1
270269
; CHECK-NEXT: ret i1 [[R]]
271270
;
272271
%yy = select i1 %y, i8 7, i8 24
@@ -277,9 +276,8 @@ define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y) {
277276

278277
define i1 @icmp_eq_x_invertable_y2(i8 %x, i8 %y) {
279278
; CHECK-LABEL: @icmp_eq_x_invertable_y2(
280-
; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], -1
281-
; CHECK-NEXT: [[AND:%.*]] = and i8 [[YY]], [[X:%.*]]
282-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], [[YY]]
279+
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
280+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], -1
283281
; CHECK-NEXT: ret i1 [[R]]
284282
;
285283
%yy = xor i8 %y, -1

0 commit comments

Comments
 (0)