[PATCH] D140456: [SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex `umin` exit counts. PR59615
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 21 03:12:34 PST 2022
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9a7286b61f61: [SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex… (authored by mkazantsev).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140456/new/
https://reviews.llvm.org/D140456
Files:
llvm/include/llvm/Analysis/ScalarEvolution.h
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll
Index: llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll
+++ llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll
@@ -8,35 +8,30 @@
; CHECK-LABEL: @test(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[VAR:%.*]] = load atomic i32, ptr addrspace(1) poison unordered, align 8, !range [[RNG0:![0-9]+]], !invariant.load !1, !noundef !1
-; CHECK-NEXT: [[VAR1:%.*]] = add nsw i32 [[VAR]], -1
; CHECK-NEXT: [[VAR2:%.*]] = icmp eq i32 [[VAR]], 0
; CHECK-NEXT: br i1 [[VAR2]], label [[BB18:%.*]], label [[BB19:%.*]]
; CHECK: bb3:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[BB19]] ], [ [[INDVARS_IV_NEXT:%.*]], [[BB12:%.*]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i64 [[TMP3:%.*]], [[INDVARS_IV]]
-; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
-; CHECK-NEXT: [[VAR6:%.*]] = icmp ult i32 [[TMP1]], [[VAR]]
-; CHECK-NEXT: br i1 [[VAR6]], label [[BB8:%.*]], label [[BB7:%.*]]
+; CHECK-NEXT: br i1 true, label [[BB8:%.*]], label [[BB7:%.*]]
; CHECK: bb7:
; CHECK-NEXT: ret void
; CHECK: bb8:
; CHECK-NEXT: [[VAR9:%.*]] = load atomic i32, ptr addrspace(1) poison unordered, align 8, !range [[RNG0]], !invariant.load !1, !noundef !1
-; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[VAR9]] to i64
-; CHECK-NEXT: [[VAR10:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP2]]
+; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[VAR9]] to i64
+; CHECK-NEXT: [[VAR10:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP0]]
; CHECK-NEXT: br i1 [[VAR10]], label [[BB12]], label [[BB11:%.*]]
; CHECK: bb11:
; CHECK-NEXT: ret void
; CHECK: bb12:
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT:%.*]]
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[TMP1:%.*]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[BB3:%.*]], label [[BB17:%.*]]
; CHECK: bb17:
; CHECK-NEXT: unreachable
; CHECK: bb18:
; CHECK-NEXT: ret void
; CHECK: bb19:
-; CHECK-NEXT: [[TMP3]] = sext i32 [[VAR1]] to i64
-; CHECK-NEXT: [[WIDE_TRIP_COUNT]] = zext i32 [[VAR]] to i64
+; CHECK-NEXT: [[TMP1]] = zext i32 [[VAR]] to i64
; CHECK-NEXT: br label [[BB3]]
;
bb:
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11046,6 +11046,26 @@
ScalarEvolution::getLoopInvariantExitCondDuringFirstIterations(
ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
const Instruction *CtxI, const SCEV *MaxIter) {
+ if (auto LIP = getLoopInvariantExitCondDuringFirstIterationsImpl(
+ Pred, LHS, RHS, L, CtxI, MaxIter))
+ return LIP;
+ if (auto *UMin = dyn_cast<SCEVUMinExpr>(MaxIter))
+ // Number of iterations expressed as UMIN isn't always great for expressing
+ // the value on the last iteration. If the straightforward approach didn't
+ // work, try the following trick: if the a predicate is invariant for X, it
+ // is also invariant for umin(X, ...). So try to find something that works
+ // among subexpressions of MaxIter expressed as umin.
+ for (auto *Op : UMin->operands())
+ if (auto LIP = getLoopInvariantExitCondDuringFirstIterationsImpl(
+ Pred, LHS, RHS, L, CtxI, Op))
+ return LIP;
+ return std::nullopt;
+}
+
+std::optional<ScalarEvolution::LoopInvariantPredicate>
+ScalarEvolution::getLoopInvariantExitCondDuringFirstIterationsImpl(
+ ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
+ const Instruction *CtxI, const SCEV *MaxIter) {
// Try to prove the following set of facts:
// - The predicate is monotonic in the iteration space.
// - If the check does not fail on the 1st iteration:
Index: llvm/include/llvm/Analysis/ScalarEvolution.h
===================================================================
--- llvm/include/llvm/Analysis/ScalarEvolution.h
+++ llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1122,6 +1122,11 @@
const Instruction *CtxI,
const SCEV *MaxIter);
+ std::optional<LoopInvariantPredicate>
+ getLoopInvariantExitCondDuringFirstIterationsImpl(
+ ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
+ const Instruction *CtxI, const SCEV *MaxIter);
+
/// Simplify LHS and RHS in a comparison with predicate Pred. Return true
/// iff any changes were made. If the operands are provably equal or
/// unequal, LHS and RHS are set to the same value and Pred is set to either
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140456.484512.patch
Type: text/x-patch
Size: 4836 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221221/909745cc/attachment.bin>
More information about the llvm-commits
mailing list