Skip to content

Commit 5b92713

Browse files
authored
[ConstraintElim] Use cond from header as upper bound on IV in exit BB. (#94610)
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. PR: #94610
1 parent e217f98 commit 5b92713

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

Diff for: llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,20 @@ void State::addInfoForInductions(BasicBlock &BB) {
10321032
WorkList.push_back(FactOrCheck::getConditionFact(
10331033
DTN, CmpInst::ICMP_SLT, PN, B,
10341034
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
1035+
1036+
// Try to add condition from header to the exit blocks. When exiting either
1037+
// with EQ or NE in the header, we know that the induction value must be u<=
1038+
// B, as other exits may only exit earlier.
1039+
assert(!StepOffset.isNegative() && "induction must be increasing");
1040+
assert((Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) &&
1041+
"unsupported predicate");
1042+
ConditionTy Precond = {CmpInst::ICMP_ULE, StartValue, B};
1043+
SmallVector<BasicBlock *> ExitBBs;
1044+
L->getExitBlocks(ExitBBs);
1045+
for (BasicBlock *EB : ExitBBs) {
1046+
WorkList.emplace_back(FactOrCheck::getConditionFact(
1047+
DT.getNode(EB), CmpInst::ICMP_ULE, A, B, Precond));
1048+
}
10351049
}
10361050

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

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

+5-10
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
@@ -99,8 +98,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known_due_to_pre
9998
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
10099
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
101100
; CHECK: [[EXIT]]:
102-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
103-
; CHECK-NEXT: ret i1 [[T]]
101+
; CHECK-NEXT: ret i1 true
104102
;
105103
entry:
106104
%pre.c = icmp ule i32 %start, 1234
@@ -341,8 +339,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(ptr %s, i32
341339
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
342340
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
343341
; CHECK: [[EXIT]]:
344-
; CHECK-NEXT: [[T:%.*]] = icmp ule i32 [[IV]], [[N]]
345-
; CHECK-NEXT: ret i1 [[T]]
342+
; CHECK-NEXT: ret i1 true
346343
;
347344
entry:
348345
br label %loop.header
@@ -419,8 +416,7 @@ define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(ptr %s) {
419416
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
420417
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
421418
; CHECK: [[EXIT]]:
422-
; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
423-
; CHECK-NEXT: ret i1 [[T]]
419+
; CHECK-NEXT: ret i1 true
424420
;
425421
entry:
426422
br label %loop.header
@@ -545,8 +541,7 @@ define i1 @multi_exiting_loop_eq_different_exits_2_const_compare_known(ptr %s, i
545541
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
546542
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2]]
547543
; CHECK: [[EXIT_1]]:
548-
; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[IV]], 1235
549-
; CHECK-NEXT: ret i1 [[T_1]]
544+
; CHECK-NEXT: ret i1 true
550545
; CHECK: [[EXIT_2]]:
551546
; CHECK-NEXT: ret i1 true
552547
;

0 commit comments

Comments
 (0)