Skip to content

Commit dc6c9f5

Browse files
committed
[ConstraintElim] Use cond from header as upper bound on IV in exit BB.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes #90417.
1 parent 41d7350 commit dc6c9f5

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,23 @@ void State::addInfoForInductions(BasicBlock &BB) {
10311031
WorkList.push_back(FactOrCheck::getConditionFact(
10321032
DTN, CmpInst::ICMP_SLT, PN, B,
10331033
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
1034+
1035+
assert(!StepOffset.isNegative() && "induction must be increasing");
1036+
// Try to add condition from header to the unique exit block, if there is one.
1037+
// When exiting either with EQ or NE, we know that the induction value must be
1038+
// u<= B, as a different exit may exit earlier.
1039+
if (Pred == CmpInst::ICMP_EQ) {
1040+
BasicBlock *EB = cast<BranchInst>(BB.getTerminator())->getSuccessor(0);
1041+
if (L->getUniqueExitBlock() == EB)
1042+
WorkList.emplace_back(FactOrCheck::getConditionFact(
1043+
DT.getNode(EB), CmpInst::ICMP_ULE, A, B));
1044+
}
1045+
if (Pred == CmpInst::ICMP_NE) {
1046+
BasicBlock *EB = cast<BranchInst>(BB.getTerminator())->getSuccessor(1);
1047+
if (L->getUniqueExitBlock() == EB)
1048+
WorkList.emplace_back(FactOrCheck::getConditionFact(
1049+
DT.getNode(EB), CmpInst::ICMP_ULE, A, B));
1050+
}
10341051
}
10351052

10361053
void State::addInfoFor(BasicBlock &BB) {

llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known(ptr %s) {
1717
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1818
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
1919
; CHECK: [[EXIT]]:
20-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
21-
; CHECK-NEXT: ret i1 [[T]]
20+
; CHECK-NEXT: ret i1 true
2221
;
2322
entry:
2423
br label %loop.header
@@ -175,8 +174,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(ptr %s, i32
175174
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
176175
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
177176
; CHECK: [[EXIT]]:
178-
; CHECK-NEXT: [[T:%.*]] = icmp ule i32 [[IV]], [[N]]
179-
; CHECK-NEXT: ret i1 [[T]]
177+
; CHECK-NEXT: ret i1 true
180178
;
181179
entry:
182180
br label %loop.header
@@ -214,8 +212,7 @@ define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(ptr %s) {
214212
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
215213
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
216214
; CHECK: [[EXIT]]:
217-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
218-
; CHECK-NEXT: ret i1 [[T]]
215+
; CHECK-NEXT: ret i1 true
219216
;
220217
entry:
221218
br label %loop.header

0 commit comments

Comments
 (0)