[llvm] [ConstraintElim] Use cond from header as upper bound on IV in exit BB. (PR #94610)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 6 05:56:16 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
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 https://github.com/llvm/llvm-project/issues/90417.
---
Full diff: https://github.com/llvm/llvm-project/pull/94610.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/ConstraintElimination.cpp (+17)
- (modified) llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll (+3-6)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 70bfa469193bf..4b3ef4d4c222c 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -1031,6 +1031,23 @@ void State::addInfoForInductions(BasicBlock &BB) {
WorkList.push_back(FactOrCheck::getConditionFact(
DTN, CmpInst::ICMP_SLT, PN, B,
ConditionTy(CmpInst::ICMP_SLE, StartValue, B)));
+
+ assert(!StepOffset.isNegative() && "induction must be increasing");
+ // Try to add condition from header to the unique exit block, if there is one.
+ // When exiting either with EQ or NE, we know that the induction value must be
+ // u<= B, as a different exit may exit earlier.
+ if (Pred == CmpInst::ICMP_EQ) {
+ BasicBlock *EB = cast<BranchInst>(BB.getTerminator())->getSuccessor(0);
+ if (L->getUniqueExitBlock() == EB)
+ WorkList.emplace_back(FactOrCheck::getConditionFact(
+ DT.getNode(EB), CmpInst::ICMP_ULE, A, B));
+ }
+ if (Pred == CmpInst::ICMP_NE) {
+ BasicBlock *EB = cast<BranchInst>(BB.getTerminator())->getSuccessor(1);
+ if (L->getUniqueExitBlock() == EB)
+ WorkList.emplace_back(FactOrCheck::getConditionFact(
+ DT.getNode(EB), CmpInst::ICMP_ULE, A, B));
+ }
}
void State::addInfoFor(BasicBlock &BB) {
diff --git a/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll b/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll
index 44ce82b51d707..86828b5e7f369 100644
--- a/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll
+++ b/llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll
@@ -17,8 +17,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_const_compare_known(ptr %s) {
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
br label %loop.header
@@ -175,8 +174,7 @@ define i1 @multi_exiting_loop_eq_same_unique_exit_var_compare_known(ptr %s, i32
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[T:%.*]] = icmp ule i32 [[IV]], [[N]]
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
br label %loop.header
@@ -214,8 +212,7 @@ define i1 @multi_exiting_loop_ne_same_unique_exit_const_compare_known(ptr %s) {
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT]]
; CHECK: [[EXIT]]:
-; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[IV]], 1235
-; CHECK-NEXT: ret i1 [[T]]
+; CHECK-NEXT: ret i1 true
;
entry:
br label %loop.header
``````````
</details>
https://github.com/llvm/llvm-project/pull/94610
More information about the llvm-commits
mailing list