Skip to content

Commit 7e70922

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 8f9dcce commit 7e70922

File tree

5 files changed

+24
-26
lines changed

5 files changed

+24
-26
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -3502,15 +3502,13 @@ Instruction *InstCombinerImpl::foldICmpBinOpEqualityWithConstant(
35023502
break;
35033503
}
35043504
case Instruction::Xor:
3505-
if (BO->hasOneUse()) {
3506-
if (Constant *BOC = dyn_cast<Constant>(BOp1)) {
3507-
// For the xor case, we can xor two constants together, eliminating
3508-
// the explicit xor.
3509-
return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC));
3510-
} else if (C.isZero()) {
3511-
// Replace ((xor A, B) != 0) with (A != B)
3512-
return new ICmpInst(Pred, BOp0, BOp1);
3513-
}
3505+
if (Constant *BOC = dyn_cast<Constant>(BOp1)) {
3506+
// For the xor case, we can xor two constants together, eliminating
3507+
// the explicit xor.
3508+
return new ICmpInst(Pred, BOp0, ConstantExpr::getXor(RHS, BOC));
3509+
} else if (C.isZero()) {
3510+
// Replace ((xor A, B) != 0) with (A != B)
3511+
return new ICmpInst(Pred, BOp0, BOp1);
35143512
}
35153513
break;
35163514
case Instruction::Or: {

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

+2-2
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

+6-6
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
;
@@ -955,7 +955,7 @@ define i1 @icmp_or_xor_with_sub_3_6(i64 %x1, i64 %y1, i64 %x2, i64 %y2, i64 %x3,
955955

956956
define i1 @or_disjoint_with_constants(i8 %x) {
957957
; CHECK-LABEL: @or_disjoint_with_constants(
958-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1:%.*]], 18
958+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 18
959959
; CHECK-NEXT: ret i1 [[CMP]]
960960
;
961961
%or = or disjoint i8 %x, 1
@@ -966,8 +966,8 @@ define i1 @or_disjoint_with_constants(i8 %x) {
966966

967967
define i1 @or_disjoint_with_constants2(i8 %x) {
968968
; CHECK-LABEL: @or_disjoint_with_constants2(
969-
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[TMP1:%.*]], 5
970-
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 66
969+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], 5
970+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], 66
971971
; CHECK-NEXT: call void @use(i8 [[OR]])
972972
; CHECK-NEXT: ret i1 [[CMP]]
973973
;

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

+7-7
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -4547,7 +4547,7 @@ define i32 @src_no_trans_select_xor_eq0_xor_or(i32 %x, i32 %y) {
45474547
define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
45484548
; CHECK-LABEL: @src_no_trans_select_xor_eq0_and_xor(
45494549
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4550-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 0
4550+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
45514551
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], [[Y]]
45524552
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[AND]], i32 [[XOR]]
45534553
; CHECK-NEXT: ret i32 [[COND]]
@@ -4563,7 +4563,7 @@ define i32 @src_no_trans_select_xor_eq0_and_xor(i32 %x, i32 %y) {
45634563
define i32 @src_no_trans_select_xor_eq0_or_xor(i32 %x, i32 %y) {
45644564
; CHECK-LABEL: @src_no_trans_select_xor_eq0_or_xor(
45654565
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
4566-
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[XOR]], 0
4566+
; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X]], [[Y]]
45674567
; CHECK-NEXT: [[OR:%.*]] = or i32 [[X]], [[Y]]
45684568
; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 [[OR]], i32 [[XOR]]
45694569
; CHECK-NEXT: ret i32 [[COND]]

0 commit comments

Comments
 (0)