Skip to content

Commit 45a6a87

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 b7b8d02 commit 45a6a87

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
@@ -19,8 +19,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known(ptr %s) {
1919
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
2020
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
2121
; CHECK: [[EXIT]]:
22-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
23-
; CHECK-NEXT: ret i1 [[T]]
22+
; CHECK-NEXT: ret i1 true
2423
;
2524
entry:
2625
br label %loop.header
@@ -341,8 +340,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(ptr %s, i32
341340
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
342341
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
343342
; CHECK: [[EXIT]]:
344-
; CHECK-NEXT: [[T:%.*]] = icmp ule i32 [[IV]], [[N]]
345-
; CHECK-NEXT: ret i1 [[T]]
343+
; CHECK-NEXT: ret i1 true
346344
;
347345
entry:
348346
br label %loop.header
@@ -380,8 +378,7 @@ define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(ptr %s) {
380378
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
381379
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
382380
; CHECK: [[EXIT]]:
383-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
384-
; CHECK-NEXT: ret i1 [[T]]
381+
; CHECK-NEXT: ret i1 true
385382
;
386383
entry:
387384
br label %loop.header

0 commit comments

Comments
 (0)