Skip to content

Commit a89b83d

Browse files
committed
[InstCombine] Extend (icmp eq/ne (and Z, X), (and Z, Y))
Only require one of the `and` ops to be single-use if both `X` / `Y` are constant.
1 parent a5424ec commit a89b83d

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5587,7 +5587,13 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
55875587
ConstantInt::get(Z->getType(), CMask + CMask));
55885588
}
55895589

5590-
if (Op0->hasOneUse() && Op1->hasOneUse()) {
5590+
// If either Op0/Op1 are both one use or X^Y will constant fold and one of
5591+
// Op0/Op1 are one use proceeed. In those cases we are instruction neutral
5592+
// but icmp eq/ne A, 0 is easier to analyze than icmp eq/ne A, B
5593+
int UseCnt =
5594+
int(Op0->hasOneUse()) + int(Op1->hasOneUse()) +
5595+
(int(match(X, m_ImmConstant()) && match(Y, m_ImmConstant())));
5596+
if (UseCnt >= 2) {
55915597
// Build (X^Y) & Z
55925598
Op1 = Builder.CreateXor(X, Y);
55935599
Op1 = Builder.CreateAnd(Op1, Z);

llvm/test/Transforms/InstCombine/and-compare.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,9 @@ define i1 @test_ne_cp2_other_fail2(i8 %x, i8 %yy) {
147147

148148
define i1 @test_ne_cp2_other_okay(i8 %x, i8 %yy) {
149149
; CHECK-LABEL: @test_ne_cp2_other_okay(
150-
; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -17
151-
; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 16
150+
; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16
152151
; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]])
153-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND_X_NEG_Y]], [[AND_X_Y]]
152+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0
154153
; CHECK-NEXT: ret i1 [[R]]
155154
;
156155
%and_x_neg_y = and i8 %x, -17
@@ -162,10 +161,9 @@ define i1 @test_ne_cp2_other_okay(i8 %x, i8 %yy) {
162161

163162
define i1 @test_ne_cp2_other_okay2(i8 %x, i8 %yy) {
164163
; CHECK-LABEL: @test_ne_cp2_other_okay2(
165-
; CHECK-NEXT: [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -17
166-
; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X]], 16
164+
; CHECK-NEXT: [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16
167165
; CHECK-NEXT: call void @use.i8(i8 [[AND_X_Y]])
168-
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[AND_X_Y]], [[AND_X_NEG_Y]]
166+
; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 0
169167
; CHECK-NEXT: ret i1 [[R]]
170168
;
171169
%and_x_neg_y = and i8 %x, -17

0 commit comments

Comments
 (0)