summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorEli Friedman <efriedma@quicinc.com>2019-02-12 00:33:25 +0000
committerEli Friedman <efriedma@quicinc.com>2019-02-12 00:33:25 +0000
commit806136f8ef1cc440df2a1387187303fa080fd001 (patch)
treef477c548adc43ea868b5ec63f14488e0af94ba4b /llvm/lib
parent9d0c5f9953e85983371bd85504b539b05555dd50 (diff)
downloadbcm5719-llvm-806136f8ef1cc440df2a1387187303fa080fd001.tar.gz
bcm5719-llvm-806136f8ef1cc440df2a1387187303fa080fd001.zip
[LoopReroll] Fix reroll root legality checking.
The code checked that the first root was an appropriate distance from the base value, but skipped checking the other roots. This could lead to rerolling a loop that can't be legally rerolled (at least, not without rewriting the loop in a non-trivial way). Differential Revision: https://reviews.llvm.org/D56812 llvm-svn: 353779
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopRerollPass.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
index 17aa442d86e..166b57f20b4 100644
--- a/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopRerollPass.cpp
@@ -891,12 +891,22 @@ bool LoopReroll::DAGRootTracker::validateRootSet(DAGRootSet &DRS) {
const auto *ADR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(DRS.BaseInst));
if (!ADR)
return false;
+
+ // Check that the first root is evenly spaced.
unsigned N = DRS.Roots.size() + 1;
const SCEV *StepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[0]), ADR);
const SCEV *ScaleSCEV = SE->getConstant(StepSCEV->getType(), N);
if (ADR->getStepRecurrence(*SE) != SE->getMulExpr(StepSCEV, ScaleSCEV))
return false;
+ // Check that the remainling roots are evenly spaced.
+ for (unsigned i = 1; i < N - 1; ++i) {
+ const SCEV *NewStepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[i]),
+ SE->getSCEV(DRS.Roots[i-1]));
+ if (NewStepSCEV != StepSCEV)
+ return false;
+ }
+
return true;
}
OpenPOWER on IntegriCloud