Skip to content

Commit 21ac510

Browse files
[InstCombine] Canonicalize icmp ult (add X, C2), C pattern
`icmp ult (add X, C2), C` can be folded to `icmp ne (and X, C), 2C`, subject to `C == -C2` and C2 being a power of 2. Proofs: https://alive2.llvm.org/ce/z/P-VVmQ.
1 parent 472465c commit 21ac510

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,6 +3130,13 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31303130
return new ICmpInst(ICmpInst::ICMP_EQ, Builder.CreateAnd(X, -C),
31313131
ConstantExpr::getNeg(cast<Constant>(Y)));
31323132

3133+
// X+C2 <u C -> (X & C) == 2C
3134+
// iff C == -(C2)
3135+
// C2 is a power of 2
3136+
if (Pred == ICmpInst::ICMP_ULT && C2->isPowerOf2() && C == -*C2)
3137+
return new ICmpInst(ICmpInst::ICMP_NE, Builder.CreateAnd(X, C),
3138+
ConstantInt::get(Ty, C * 2));
3139+
31333140
// X+C >u C2 -> (X & ~C2) != C
31343141
// iff C & C2 == 0
31353142
// C2+1 is a power of 2

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3025,8 +3025,8 @@ define i1 @icmp_addnuw_nonzero_fail_multiuse(i32 %x, i32 %y) {
30253025

30263026
define i1 @ult_add_C2_pow2_C_neg(i8 %x) {
30273027
; CHECK-LABEL: @ult_add_C2_pow2_C_neg(
3028-
; CHECK-NEXT: [[I:%.*]] = add i8 [[X:%.*]], 32
3029-
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[I]], -32
3028+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3029+
; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], -64
30303030
; CHECK-NEXT: ret i1 [[C]]
30313031
;
30323032
%i = add i8 %x, 32
@@ -3036,8 +3036,8 @@ define i1 @ult_add_C2_pow2_C_neg(i8 %x) {
30363036

30373037
define i1 @ult_add_nsw_C2_pow2_C_neg(i8 %x) {
30383038
; CHECK-LABEL: @ult_add_nsw_C2_pow2_C_neg(
3039-
; CHECK-NEXT: [[I:%.*]] = add nsw i8 [[X:%.*]], 32
3040-
; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[I]], -32
3039+
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -32
3040+
; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[TMP1]], -64
30413041
; CHECK-NEXT: ret i1 [[C]]
30423042
;
30433043
%i = add nsw i8 %x, 32
@@ -3068,8 +3068,8 @@ define i1 @ult_add_C2_neg_C_pow2(i8 %x) {
30683068

30693069
define <2 x i1> @ult_add_C2_pow2_C_neg_vec(<2 x i8> %x) {
30703070
; CHECK-LABEL: @ult_add_C2_pow2_C_neg_vec(
3071-
; CHECK-NEXT: [[I:%.*]] = add <2 x i8> [[X:%.*]], <i8 32, i8 32>
3072-
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[I]], <i8 -32, i8 -32>
3071+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -32, i8 -32>
3072+
; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i8> [[TMP1]], <i8 -64, i8 -64>
30733073
; CHECK-NEXT: ret <2 x i1> [[C]]
30743074
;
30753075
%i = add <2 x i8> %x, <i8 32, i8 32>

0 commit comments

Comments
 (0)