Skip to content

Commit 87ca693

Browse files
committed
Allow folding icmp eq (add X, C2), C when there is more than one-use when we can compute the range
If there are multiple uses of an add, we can fold a comparison anyway if we can compute a constant range for it, which should happen in cases such as saturated add.
1 parent 1c0705f commit 87ca693

File tree

6 files changed

+20
-40
lines changed

6 files changed

+20
-40
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,7 +3160,7 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31603160
return replaceInstUsesWith(Cmp, Cond);
31613161
}
31623162
const APInt *C2;
3163-
if (Cmp.isEquality() || !match(Y, m_APInt(C2)))
3163+
if (!match(Y, m_APInt(C2)))
31643164
return nullptr;
31653165

31663166
// Fold icmp pred (add X, C2), C.
@@ -3184,7 +3184,7 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
31843184
return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC));
31853185
}
31863186

3187-
if (ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() &&
3187+
if (!Cmp.isEquality() && ICmpInst::isUnsigned(Pred) && Add->hasNoSignedWrap() &&
31883188
C.isNonNegative() && (C - *C2).isNonNegative() &&
31893189
computeConstantRange(X, /*ForSigned=*/true).add(*C2).isAllNonNegative())
31903190
return new ICmpInst(ICmpInst::getSignedPredicate(Pred), X,
@@ -3205,6 +3205,9 @@ Instruction *InstCombinerImpl::foldICmpAddConstant(ICmpInst &Cmp,
32053205
return new ICmpInst(ICmpInst::ICMP_UGE, X, ConstantInt::get(Ty, Lower));
32063206
}
32073207

3208+
if (Cmp.isEquality())
3209+
return nullptr;
3210+
32083211
// This set of folds is intentionally placed after folds that use no-wrapping
32093212
// flags because those folds are likely better for later analysis/codegen.
32103213
const APInt SMax = APInt::getSignedMaxValue(Ty->getScalarSizeInBits());

llvm/test/Analysis/ValueTracking/phi-known-bits.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ define i32 @issue_124275_wrong_br_direction(i32 noundef %inp) {
11191119
; CHECK-NEXT: entry:
11201120
; CHECK-NEXT: [[TMP0:%.*]] = xor i32 [[INP:%.*]], -2
11211121
; CHECK-NEXT: [[XOR_INP_NEG:%.*]] = add i32 [[TMP0]], 1
1122-
; CHECK-NEXT: [[CMP_NE_NOT:%.*]] = icmp eq i32 [[XOR_INP_NEG]], 0
1122+
; CHECK-NEXT: [[CMP_NE_NOT:%.*]] = icmp eq i32 [[INP]], 1
11231123
; CHECK-NEXT: br i1 [[CMP_NE_NOT]], label [[B1:%.*]], label [[B0:%.*]]
11241124
; CHECK: B0:
11251125
; CHECK-NEXT: [[PHI_B0:%.*]] = phi i32 [ [[PHI_B1:%.*]], [[B1]] ], [ [[XOR_INP_NEG]], [[ENTRY:%.*]] ]

llvm/test/Transforms/InstCombine/saturating-add-sub.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,9 +2352,7 @@ define i8 @fold_add_umax_to_usub_multiuse(i8 %a) {
23522352

23532353
define i32 @add_check_zero(i32 %num) {
23542354
; CHECK-LABEL: @add_check_zero(
2355-
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[NUM:%.*]], 1
2356-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ADD]], 0
2357-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 -1, i32 [[ADD]]
2355+
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[NUM:%.*]], i32 1)
23582356
; CHECK-NEXT: ret i32 [[COND]]
23592357
;
23602358
%add = add i32 %num, 1

llvm/test/Transforms/InstCombine/uaddo.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ define i1 @uaddo_1(i8 %x, ptr %p) {
158158
; CHECK-LABEL: @uaddo_1(
159159
; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 1
160160
; CHECK-NEXT: store i8 [[A]], ptr [[P:%.*]], align 1
161-
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], 0
161+
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[X]], -1
162162
; CHECK-NEXT: ret i1 [[C]]
163163
;
164164
%a = add i8 %x, 1

llvm/test/Transforms/LoopVectorize/induction.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3183,7 +3183,7 @@ define i32 @testoverflowcheck() {
31833183
; IND-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ]
31843184
; IND-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]]
31853185
; IND-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1
3186-
; IND-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0
3186+
; IND-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1
31873187
; IND-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]]
31883188
; IND: loopexit:
31893189
; IND-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
@@ -3225,7 +3225,7 @@ define i32 @testoverflowcheck() {
32253225
; UNROLL-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ]
32263226
; UNROLL-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]]
32273227
; UNROLL-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1
3228-
; UNROLL-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0
3228+
; UNROLL-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1
32293229
; UNROLL-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]]
32303230
; UNROLL: loopexit:
32313231
; UNROLL-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
@@ -3315,7 +3315,7 @@ define i32 @testoverflowcheck() {
33153315
; INTERLEAVE-NEXT: [[INC4_I:%.*]] = phi i8 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC_I:%.*]], [[COND_END_I]] ]
33163316
; INTERLEAVE-NEXT: [[AND_I:%.*]] = and i32 [[BC_MERGE_RDX]], [[TMP0]]
33173317
; INTERLEAVE-NEXT: [[INC_I]] = add i8 [[INC4_I]], 1
3318-
; INTERLEAVE-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC_I]], 0
3318+
; INTERLEAVE-NEXT: [[TOBOOL_I:%.*]] = icmp eq i8 [[INC4_I]], -1
33193319
; INTERLEAVE-NEXT: br i1 [[TOBOOL_I]], label [[LOOPEXIT]], label [[COND_END_I]], !llvm.loop [[LOOP33:![0-9]+]]
33203320
; INTERLEAVE: loopexit:
33213321
; INTERLEAVE-NEXT: [[AND_I_LCSSA:%.*]] = phi i32 [ [[AND_I]], [[COND_END_I]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
@@ -5399,7 +5399,7 @@ define i32 @PR32419(i32 %a, i16 %b) {
53995399
; INTERLEAVE-NEXT: [[VAR4:%.*]] = phi i32 [ [[TMP50]], [[FOR_COND]] ], [ 0, [[FOR_BODY]] ]
54005400
; INTERLEAVE-NEXT: [[VAR6]] = or i32 [[VAR0]], [[VAR4]]
54015401
; INTERLEAVE-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
5402-
; INTERLEAVE-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], 0
5402+
; INTERLEAVE-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], -1
54035403
; INTERLEAVE-NEXT: br i1 [[COND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP47:![0-9]+]]
54045404
; INTERLEAVE: for.end:
54055405
; INTERLEAVE-NEXT: [[VAR7:%.*]] = phi i32 [ [[VAR6]], [[FOR_INC]] ], [ poison, [[MIDDLE_BLOCK]] ]

llvm/test/Transforms/PhaseOrdering/deletion-of-loops-that-became-side-effect-free.ll

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -96,35 +96,10 @@ while.end:
9696
}
9797

9898
define dso_local zeroext i1 @is_not_empty_variant3(ptr %p) {
99-
; O3-LABEL: @is_not_empty_variant3(
100-
; O3-NEXT: entry:
101-
; O3-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
102-
; O3-NEXT: ret i1 [[TOBOOL_NOT4_I]]
103-
;
104-
; O2-LABEL: @is_not_empty_variant3(
105-
; O2-NEXT: entry:
106-
; O2-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
107-
; O2-NEXT: ret i1 [[TOBOOL_NOT4_I]]
108-
;
109-
; O1-LABEL: @is_not_empty_variant3(
110-
; O1-NEXT: entry:
111-
; O1-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp eq ptr [[P:%.*]], null
112-
; O1-NEXT: br i1 [[TOBOOL_NOT4_I]], label [[COUNT_NODES_VARIANT3_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
113-
; O1: while.body.i:
114-
; O1-NEXT: [[SIZE_06_I:%.*]] = phi i64 [ [[INC_I:%.*]], [[WHILE_BODY_I]] ], [ 0, [[ENTRY:%.*]] ]
115-
; O1-NEXT: [[P_ADDR_05_I:%.*]] = phi ptr [ [[TMP0:%.*]], [[WHILE_BODY_I]] ], [ [[P]], [[ENTRY]] ]
116-
; O1-NEXT: [[CMP_I:%.*]] = icmp ne i64 [[SIZE_06_I]], -1
117-
; O1-NEXT: call void @llvm.assume(i1 [[CMP_I]])
118-
; O1-NEXT: [[TMP0]] = load ptr, ptr [[P_ADDR_05_I]], align 8
119-
; O1-NEXT: [[INC_I]] = add i64 [[SIZE_06_I]], 1
120-
; O1-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp eq ptr [[TMP0]], null
121-
; O1-NEXT: br i1 [[TOBOOL_NOT_I]], label [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT:%.*]], label [[WHILE_BODY_I]], !llvm.loop [[LOOP0:![0-9]+]]
122-
; O1: count_nodes_variant3.exit.loopexit:
123-
; O1-NEXT: [[PHI_CMP:%.*]] = icmp ne i64 [[INC_I]], 0
124-
; O1-NEXT: br label [[COUNT_NODES_VARIANT3_EXIT]]
125-
; O1: count_nodes_variant3.exit:
126-
; O1-NEXT: [[SIZE_0_LCSSA_I:%.*]] = phi i1 [ false, [[ENTRY]] ], [ [[PHI_CMP]], [[COUNT_NODES_VARIANT3_EXIT_LOOPEXIT]] ]
127-
; O1-NEXT: ret i1 [[SIZE_0_LCSSA_I]]
99+
; ALL-LABEL: @is_not_empty_variant3(
100+
; ALL-NEXT: entry:
101+
; ALL-NEXT: [[TOBOOL_NOT4_I:%.*]] = icmp ne ptr [[P:%.*]], null
102+
; ALL-NEXT: ret i1 [[TOBOOL_NOT4_I]]
128103
;
129104
entry:
130105
%p.addr = alloca ptr, align 8
@@ -182,3 +157,7 @@ declare void @llvm.assume(i1 noundef)
182157
!1 = !{!"llvm.loop.mustprogress"}
183158
!2 = distinct !{!2, !1}
184159
!3 = distinct !{!3, !1}
160+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
161+
; O1: {{.*}}
162+
; O2: {{.*}}
163+
; O3: {{.*}}

0 commit comments

Comments
 (0)