[llvm] [SCEVExpander] Relax hoisting condition for AddRec start (PR #75916)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 19 01:58:00 PST 2023
https://github.com/averine created https://github.com/llvm/llvm-project/pull/75916
Don't require the existence of a preheader to hoist an AddRec start value: a unique loop predecessor which isLegalToHoistInto should be enough.
>From 3350c5ec136b406a717d00b2482ddf8cba478e6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20V=C3=A9rine?= <“verine.alexandre at proton.me”>
Date: Tue, 19 Dec 2023 10:23:08 +0100
Subject: [PATCH] [SCEVExpander] Relax hoisting condition for AddRec start
Don't require the existence of a preheader to hoist an
AddRec start value: a unique loop predecessor which
isLegalToHoistInto should be enough.
---
.../Utils/ScalarEvolutionExpander.cpp | 13 ++++---
.../scevexpander-in-non-simplified-loop.ll | 39 +++++++++++++++++++
2 files changed, 47 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/Transforms/IndVarSimplify/scevexpander-in-non-simplified-loop.ll
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index cd3ac317cd238e..f4be4c94925e62 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -980,11 +980,14 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
PostIncLoopSet SavedPostIncLoops = PostIncLoops;
PostIncLoops.clear();
- // Expand code for the start value into the loop preheader.
- assert(L->getLoopPreheader() &&
- "Can't expand add recurrences without a loop preheader!");
- Value *StartV =
- expand(Normalized->getStart(), L->getLoopPreheader()->getTerminator());
+ // Expand code for the start value into the loop predecessor. The loop is not
+ // necessarily in Loop Simplify Form, so assert it's legal to do so.
+ auto *LP = L->getLoopPredecessor();
+ assert(LP && LP->isLegalToHoistInto() &&
+ "Can't expand add recurrences without hoisting into the loop "
+ "predecessor.");
+
+ Value *StartV = expand(Normalized->getStart(), LP->getTerminator());
// StartV must have been be inserted into L's preheader to dominate the new
// phi.
diff --git a/llvm/test/Transforms/IndVarSimplify/scevexpander-in-non-simplified-loop.ll b/llvm/test/Transforms/IndVarSimplify/scevexpander-in-non-simplified-loop.ll
new file mode 100644
index 00000000000000..7b546ab7d5d329
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/scevexpander-in-non-simplified-loop.ll
@@ -0,0 +1,39 @@
+; RUN: opt -passes=indvars < %s
+
+target datalayout = "e-n32:64"
+
+declare void @g(i64)
+
+define void @f(ptr %block_address_arg) {
+
+; This loop isn't in Simplified Form. Ensure SCEV expander doesn't hit an assert
+; when visiting it.
+f_entry:
+ indirectbr ptr %block_address_arg, [label %f.exit, label %f_for.cond]
+
+f_for.cond: ; preds = %f_for.body, %f_entry
+ %i = phi i32 [ %j, %f_for.body ], [ 0, %f_entry ]
+ %cmp = icmp ult i32 %i, 64
+ br i1 %cmp, label %f_for.body, label %f_for.end
+
+f_for.body: ; preds = %f_for.cond
+ %j = add nuw nsw i32 %i, 1
+ br label %f_for.cond
+
+; Indvars pass visits this loop, since it's in Simplified Form.
+; Because of the integer extension in that loop's body, SCEV expander may also
+; visit the first loop.
+f_for.end: ; preds = %f_for.cond
+ %k = phi i32 [ %i, %f_for.cond ]
+ br label %f_for2.body
+
+f_for2.body: ; preds = %f_for2.body, %f_for.end
+ %l = phi i32 [ %k, %f_for.end ], [ %n, %f_for2.body ]
+ %m = zext i32 %l to i64
+ call void @g(i64 %m)
+ %n = add nuw nsw i32 %l, 1
+ br label %f_for2.body
+
+f.exit: ; preds = %f_entry
+ ret void
+}
More information about the llvm-commits
mailing list