Skip to content

Commit 37b2ffc

Browse files
committed
[InstCombine] Fold (icmp eq/ne (xor x, y), C1) even if multiuse
Two folds unlocked: `(icmp eq/ne (xor x, C0), C1)` -> `(icmp eq/ne x, C2)` `(icmp eq/ne (xor x, y), 0)` -> `(icmp eq/ne x, y)` This fixes regressions assosiated with #87180
1 parent eb8511b commit 37b2ffc

File tree

6 files changed

+32
-31
lines changed

6 files changed

+32
-31
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3461,15 +3461,13 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
34613461
break;
34623462
}
34633463
case Instruction::Xor:
3464-
if (BO->hasOneUse()) {
3465-
if (Constant *BOC = dyn_cast<Constant>(BOp1)) {
3466-
// For the xor case, we can xor two constants together, eliminating
3467-
// the explicit xor.
3468-
return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC));
3469-
} else if (C.isZero()) {
3470-
// Replace ((xor A, B) != 0) with (A != B)
3471-
return new ICmpInst(Pred, BOp0, BOp1);
3472-
}
3464+
if (Constant *BOC = dyn_cast<Constant>(BOp1)) {
3465+
// For the xor case, we can xor two constants together, eliminating
3466+
// the explicit xor.
3467+
return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC));
3468+
} else if (C.isZero()) {
3469+
// Replace ((xor A, B) != 0) with (A != B)
3470+
return new ICmpInst(Pred, BOp0, BOp1);
34733471
}
34743472
break;
34753473
case Instruction::Or: {

llvm/test/Transforms/InstCombine/abs-1.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,10 +852,10 @@ define i8 @abs_diff_signed_sgt_nuw_extra_use3(i8 %a, i8 %b) {
852852

853853
define i32 @abs_diff_signed_slt_swap_wrong_pred1(i32 %a, i32 %b) {
854854
; CHECK-LABEL: @abs_diff_signed_slt_swap_wrong_pred1(
855-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
856-
; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i32 [[B]], [[A]]
855+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[B:%.*]], [[A:%.*]]
857856
; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A]], [[B]]
858-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_BA]], i32 [[SUB_AB]]
857+
; CHECK-NEXT: [[SUB_AB1:%.*]] = sub nsw i32 [[B]], [[A]]
858+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_AB]], i32 [[SUB_AB1]]
859859
; CHECK-NEXT: ret i32 [[COND]]
860860
;
861861
%cmp = icmp eq i32 %a, %b

llvm/test/Transforms/InstCombine/icmp-equality-xor.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ declare void @use.i8(i8)
150150
define i1 @fold_xorC_eq0_multiuse(i8 %x, i8 %y) {
151151
; CHECK-LABEL: @fold_xorC_eq0_multiuse(
152152
; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
153-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XX]], 0
153+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y]]
154154
; CHECK-NEXT: call void @use.i8(i8 [[XX]])
155155
; CHECK-NEXT: ret i1 [[R]]
156156
;
@@ -176,7 +176,7 @@ define i1 @fold_xorC_eq1_multiuse_fail(i8 %x, i8 %y) {
176176
define i1 @fold_xorC_neC_multiuse(i8 %x) {
177177
; CHECK-LABEL: @fold_xorC_neC_multiuse(
178178
; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 45
179-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[XX]], 67
179+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 110
180180
; CHECK-NEXT: call void @use.i8(i8 [[XX]])
181181
; CHECK-NEXT: ret i1 [[R]]
182182
;

llvm/test/Transforms/InstCombine/icmp-or.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
2+
; RUN: opt < %s -passes='instcombine<no-verify-fixpoint>' -S | FileCheck %s
33

44
declare void @use(i8)
55

@@ -434,7 +434,7 @@ define i1 @icmp_or_xor_2_3_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
434434
; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]]
435435
; CHECK-NEXT: [[OR:%.*]] = or i64 [[XOR]], [[XOR1]]
436436
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 0
437-
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[XOR]], 0
437+
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[X1]], [[Y1]]
438438
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP]], [[CMP_1]]
439439
; CHECK-NEXT: ret i1 [[OR1]]
440440
;
@@ -455,7 +455,7 @@ define i1 @icmp_or_xor_2_4_fail(i64 %x1, i64 %y1, i64 %x2, i64 %y2) {
455455
; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[X2:%.*]], [[Y2:%.*]]
456456
; CHECK-NEXT: [[OR:%.*]] = or i64 [[XOR]], [[XOR1]]
457457
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[OR]], 0
458-
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[XOR1]], 0
458+
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i64 [[X2]], [[Y2]]
459459
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[CMP]], [[CMP_1]]
460460
; CHECK-NEXT: ret i1 [[OR1]]
461461
;

llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
define zeroext i1 @test1(i32 %lhs, i32 %rhs) {
99
; CHECK-LABEL: @test1(
10-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LHS:%.*]], 5
11-
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[XOR]], 10
12-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[XOR]], [[RHS:%.*]]
10+
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[LHS:%.*]], 15
11+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[LHS]], [[RHS:%.*]]
12+
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 5
1313
; CHECK-NEXT: [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]]
1414
; CHECK-NEXT: ret i1 [[SEL]]
1515
;
@@ -23,9 +23,9 @@ define zeroext i1 @test1(i32 %lhs, i32 %rhs) {
2323

2424
define zeroext i1 @test1_logical(i32 %lhs, i32 %rhs) {
2525
; CHECK-LABEL: @test1_logical(
26-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LHS:%.*]], 5
27-
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[XOR]], 10
28-
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[XOR]], [[RHS:%.*]]
26+
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[LHS:%.*]], 15
27+
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[LHS]], [[RHS:%.*]]
28+
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[TMP1]], 5
2929
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
3030
; CHECK-NEXT: ret i1 [[SEL]]
3131
;
@@ -40,7 +40,7 @@ define zeroext i1 @test1_logical(i32 %lhs, i32 %rhs) {
4040
define zeroext i1 @test2(i32 %lhs, i32 %rhs) {
4141
; CHECK-LABEL: @test2(
4242
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[LHS:%.*]], [[RHS:%.*]]
43-
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[XOR]], 0
43+
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[LHS]], [[RHS]]
4444
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[XOR]], 32
4545
; CHECK-NEXT: [[SEL:%.*]] = xor i1 [[CMP1]], [[CMP2]]
4646
; CHECK-NEXT: ret i1 [[SEL]]

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4430,9 +4430,10 @@ define i32 @src_no_trans_select_and_ne0_xor_or(i32 %x, i32 %y) {
44304430

44314431
define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) {
44324432
; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_and(
4433-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4433+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4434+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
44344435
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
4435-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[AND]]
4436+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[XOR]], i32 [[AND]]
44364437
; CHECK-NEXT: ret i32 [[COND]]
44374438
;
44384439
%xor = xor i32 %x, %y
@@ -4444,9 +4445,10 @@ define i32 @src_no_trans_select_xor_eq0_xor_and(i32 %x, i32 %y) {
44444445

44454446
define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {
44464447
; CHECK-LABEL: @src_no_trans_select_xor_eq0_xor_or(
4447-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4448+
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4449+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
44484450
; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
4449-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[OR]]
4451+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[XOR]], i32 [[OR]]
44504452
; CHECK-NEXT: ret i32 [[COND]]
44514453
;
44524454
%xor = xor i32 %x, %y
@@ -4459,7 +4461,7 @@ define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {
44594461
define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
44604462
; CHECK-LABEL: @src_no_trans_select_xor_eq0_and_xor(
44614463
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4462-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 0
4464+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
44634465
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
44644466
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]]
44654467
; CHECK-NEXT: ret i32 [[COND]]
@@ -4475,7 +4477,7 @@ define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
44754477
define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {
44764478
; CHECK-LABEL: @src_no_trans_select_xor_eq0_or_xor(
44774479
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4478-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 0
4480+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
44794481
; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
44804482
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]]
44814483
; CHECK-NEXT: ret i32 [[COND]]
@@ -4492,7 +4494,8 @@ define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {
44924494
define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
44934495
; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y(
44944496
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
4495-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]]
4497+
; CHECK-NEXT: [[XOR:%.*]] = select i1 [[XOR0]], i32 [[X]], i32 0
4498+
; CHECK-NEXT: [[COND:%.*]] = xor i32 [[XOR]], [[Y]]
44964499
; CHECK-NEXT: ret i32 [[COND]]
44974500
;
44984501
%xor = xor i32 %x, %y

0 commit comments

Comments
 (0)