aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorEli Friedman <efriedma@quicinc.com>2023-07-12 11:37:28 -0700
committerEli Friedman <efriedma@quicinc.com>2023-07-12 12:27:39 -0700
commit60712732ea2442375cccef3eb87784a3a3888fad (patch)
treee44b223179ef77084d75cc23a0390174dd6e41ba /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parent11592667344f1f4e12da599e6669a359b99bd43b (diff)
downloadllvm-60712732ea2442375cccef3eb87784a3a3888fad.zip
llvm-60712732ea2442375cccef3eb87784a3a3888fad.tar.gz
llvm-60712732ea2442375cccef3eb87784a3a3888fad.tar.bz2
[IndVars] Teach replaceCongruentIVs to avoid scrambling induction variables
replaceCongruentIVs analysis is based on ScalarEvolution; this makes comparing different PHIs and performing the replacement straightforward. However, it can have some side-effects: it isn't aware whether an induction variable is in canonical form, so it can perform replacements which obscure the meaning of the IR. In test22 in widen-loop-comp.ll, the resulting loop can't be analyzed by ScalarEvolution at all. My attempted solution is to restrict the transform: don't try to replace induction variables using PHI nodes that don't represent simple induction variables. I'm not sure if this is the best solution; suggestions welcome. Differential Revision: https://reviews.llvm.org/D121950
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index dc094cf..2084427 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1652,11 +1652,17 @@ SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
OrigPhiRef = Phi;
if (Phi->getType()->isIntegerTy() && TTI &&
TTI->isTruncateFree(Phi->getType(), Phis.back()->getType())) {
- // This phi can be freely truncated to the narrowest phi type. Map the
- // truncated expression to it so it will be reused for narrow types.
- const SCEV *TruncExpr =
- SE.getTruncateExpr(SE.getSCEV(Phi), Phis.back()->getType());
- ExprToIVMap[TruncExpr] = Phi;
+ // Make sure we only rewrite using simple induction variables;
+ // otherwise, we can make the trip count of a loop unanalyzable
+ // to SCEV.
+ const SCEV *PhiExpr = SE.getSCEV(Phi);
+ if (isa<SCEVAddRecExpr>(PhiExpr)) {
+ // This phi can be freely truncated to the narrowest phi type. Map the
+ // truncated expression to it so it will be reused for narrow types.
+ const SCEV *TruncExpr =
+ SE.getTruncateExpr(PhiExpr, Phis.back()->getType());
+ ExprToIVMap[TruncExpr] = Phi;
+ }
}
continue;
}