Skip to content

Commit 0289dad

Browse files
committed
[InstCombine] Add folds for (icmp eq/ne (and (add/sub/xor A, P2), P2), 0/P2)
- `(icmp eq/ne (and (add/sub/xor X, P2), P2), P2)` -> `(icmp eq/ne (and X, P2), 0)` - `(icmp eq/ne (and (add/sub/xor X, P2), P2), 0)` -> `(icmp eq/ne (and X, P2), P2)` Folds like this come up with reasonable regularity in odd/even loops. Proofs: https://alive2.llvm.org/ce/z/45pq2x Closes #67836
1 parent 731bdce commit 0289dad

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5483,6 +5483,32 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
54835483
m_CombineAnd(m_Value(B), m_Unless(m_ImmConstant())))))
54845484
return new ICmpInst(Pred, Builder.CreateXor(A, B), Cst);
54855485

5486+
{
5487+
// (icmp eq/ne (and (add/sub/xor X, P2), P2), P2)
5488+
auto m_Matcher =
5489+
m_CombineOr(m_CombineOr(m_c_Add(m_Value(B), m_Deferred(A)),
5490+
m_c_Xor(m_Value(B), m_Deferred(A))),
5491+
m_Sub(m_Value(B), m_Deferred(A)));
5492+
std::optional<bool> IsZero = std::nullopt;
5493+
if (match(&I, m_c_ICmp(PredUnused, m_OneUse(m_c_And(m_Value(A), m_Matcher)),
5494+
m_Deferred(A))))
5495+
IsZero = false;
5496+
// (icmp eq/ne (and (add/sub/xor X, P2), P2), 0)
5497+
else if (match(&I,
5498+
m_ICmp(PredUnused, m_OneUse(m_c_And(m_Value(A), m_Matcher)),
5499+
m_Zero())))
5500+
IsZero = true;
5501+
5502+
if (IsZero && isKnownToBeAPowerOfTwo(A, /* OrZero */ true, /*Depth*/ 0, &I))
5503+
// (icmp eq/ne (and (add/sub/xor X, P2), P2), P2)
5504+
// -> (icmp eq/ne (and X, P2), 0)
5505+
// (icmp eq/ne (and (add/sub/xor X, P2), P2), 0)
5506+
// -> (icmp eq/ne (and X, P2), P2)
5507+
return new ICmpInst(Pred, Builder.CreateAnd(B, A),
5508+
*IsZero ? A
5509+
: ConstantInt::getNullValue(A->getType()));
5510+
}
5511+
54865512
return nullptr;
54875513
}
54885514

llvm/test/Transforms/InstCombine/icmp-and-add-sub-xor-p2.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ define i1 @src_add_eq_p2(i8 %x, i8 %yy) {
99
; CHECK-NEXT: [[Y:%.*]] = and i8 [[NY]], [[YY]]
1010
; CHECK-NEXT: [[X1:%.*]] = add i8 [[Y]], [[X:%.*]]
1111
; CHECK-NEXT: call void @use.i8(i8 [[X1]])
12-
; CHECK-NEXT: [[V:%.*]] = and i8 [[X1]], [[Y]]
13-
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], [[Y]]
12+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], [[X]]
13+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], 0
1414
; CHECK-NEXT: ret i1 [[R]]
1515
;
1616
%ny = sub i8 0, %yy
@@ -49,8 +49,8 @@ define i1 @src_xor_ne_zero(i8 %x, i8 %yy) {
4949
; CHECK-NEXT: [[Y:%.*]] = and i8 [[NY]], [[YY]]
5050
; CHECK-NEXT: [[X1:%.*]] = xor i8 [[Y]], [[X:%.*]]
5151
; CHECK-NEXT: call void @use.i8(i8 [[X1]])
52-
; CHECK-NEXT: [[V:%.*]] = and i8 [[X1]], [[Y]]
53-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[V]], 0
52+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], [[X]]
53+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[TMP1]], [[Y]]
5454
; CHECK-NEXT: ret i1 [[R]]
5555
;
5656
%ny = sub i8 0, %yy
@@ -89,8 +89,8 @@ define <2 x i1> @src_sub_ne_p2(<2 x i8> %x, <2 x i8> %yy) {
8989
; CHECK-NEXT: [[Y:%.*]] = and <2 x i8> [[NY]], [[YY]]
9090
; CHECK-NEXT: [[X1:%.*]] = sub <2 x i8> [[X:%.*]], [[Y]]
9191
; CHECK-NEXT: call void @use.v2i8(<2 x i8> [[X1]])
92-
; CHECK-NEXT: [[V:%.*]] = and <2 x i8> [[X1]], [[Y]]
93-
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[V]], [[Y]]
92+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[Y]], [[X]]
93+
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
9494
; CHECK-NEXT: ret <2 x i1> [[R]]
9595
;
9696
%ny = sub <2 x i8> zeroinitializer, %yy
@@ -107,8 +107,8 @@ define <2 x i1> @src_sub_eq_zero(<2 x i8> %x, <2 x i8> %yy) {
107107
; CHECK-NEXT: [[Y:%.*]] = shl <2 x i8> <i8 1, i8 2>, [[YY:%.*]]
108108
; CHECK-NEXT: [[X1:%.*]] = sub <2 x i8> [[X:%.*]], [[Y]]
109109
; CHECK-NEXT: call void @use.v2i8(<2 x i8> [[X1]])
110-
; CHECK-NEXT: [[V:%.*]] = and <2 x i8> [[X1]], [[Y]]
111-
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[V]], zeroinitializer
110+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[Y]], [[X]]
111+
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], [[Y]]
112112
; CHECK-NEXT: ret <2 x i1> [[R]]
113113
;
114114
%y = shl <2 x i8> <i8 1, i8 2>, %yy

llvm/test/Transforms/InstCombine/pr25342.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ define void @multi_phi(i32 signext %n) {
7878
; CHECK-NEXT: entry:
7979
; CHECK-NEXT: br label [[FOR_COND:%.*]]
8080
; CHECK: for.cond:
81-
; CHECK-NEXT: [[TMP0:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP6:%.*]], [[ODD_BB:%.*]] ]
81+
; CHECK-NEXT: [[TMP0:%.*]] = phi float [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP7:%.*]], [[ODD_BB:%.*]] ]
8282
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[ODD_BB]] ]
8383
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N:%.*]]
8484
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
@@ -92,14 +92,14 @@ define void @multi_phi(i32 signext %n) {
9292
; CHECK-NEXT: [[SUB_I:%.*]] = fsub float [[MUL_I]], [[MUL4_I]]
9393
; CHECK-NEXT: [[ADD_I:%.*]] = fadd float [[SUB_I]], [[TMP0]]
9494
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
95-
; CHECK-NEXT: [[BIT0:%.*]] = and i32 [[INC]], 1
96-
; CHECK-NEXT: [[EVEN_NOT_NOT:%.*]] = icmp eq i32 [[BIT0]], 0
97-
; CHECK-NEXT: br i1 [[EVEN_NOT_NOT]], label [[EVEN_BB:%.*]], label [[ODD_BB]]
95+
; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[I_0]], 1
96+
; CHECK-NEXT: [[EVEN_NOT_NOT_NOT:%.*]] = icmp eq i32 [[TMP5]], 0
97+
; CHECK-NEXT: br i1 [[EVEN_NOT_NOT_NOT]], label [[ODD_BB]], label [[EVEN_BB:%.*]]
9898
; CHECK: even.bb:
99-
; CHECK-NEXT: [[TMP5:%.*]] = fadd float [[SUB_I]], [[ADD_I]]
99+
; CHECK-NEXT: [[TMP6:%.*]] = fadd float [[SUB_I]], [[ADD_I]]
100100
; CHECK-NEXT: br label [[ODD_BB]]
101101
; CHECK: odd.bb:
102-
; CHECK-NEXT: [[TMP6]] = phi float [ [[ADD_I]], [[FOR_BODY]] ], [ [[TMP5]], [[EVEN_BB]] ]
102+
; CHECK-NEXT: [[TMP7]] = phi float [ [[ADD_I]], [[FOR_BODY]] ], [ [[TMP6]], [[EVEN_BB]] ]
103103
; CHECK-NEXT: br label [[FOR_COND]]
104104
; CHECK: for.end:
105105
; CHECK-NEXT: store float [[TMP0]], ptr @dd, align 4

llvm/test/Transforms/PGOProfile/cspgo_profile_summary.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ for.end:
104104
; CSPGOSUMMARY-LABEL: @foo
105105
; CSPGOSUMMARY: %even.odd.i = select i1 %tobool.i{{[0-9]*}}, ptr @even, ptr @odd
106106
; CSPGOSUMMARY-SAME: !prof ![[BW_CSPGO_BAR]]
107-
; CSPGOSUMMARY: %even.odd.i2 = select i1 %tobool.i{{[0-9]*}}, ptr @even, ptr @odd
107+
; CSPGOSUMMARY: %even.odd.i2 = select i1 %tobool.i{{[0-9]*}}, ptr @odd, ptr @even
108108
; CSPGOSUMMARY-SAME: !prof ![[BW_CSPGO_BAR]]
109109

110110
declare dso_local i32 @bar_m(i32)

0 commit comments

Comments
 (0)