summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2019-11-06 12:36:28 -0800
committerPhilip Reames <listmail@philipreames.com>2019-11-06 14:04:45 -0800
commit9bfa5ab3d1982a7cef60ee00b935f4ddc89fc98e (patch)
treeaef1dff69b0dc2c363f04591f97b7d23f99c7522 /llvm/lib/Analysis/ScalarEvolution.cpp
parent6cecd3c3dbef48eca6c4cf2dcc2df3290ab91488 (diff)
downloadbcm5719-llvm-9bfa5ab3d1982a7cef60ee00b935f4ddc89fc98e.tar.gz
bcm5719-llvm-9bfa5ab3d1982a7cef60ee00b935f4ddc89fc98e.zip
[LoopPred] Fix two subtle issues found by inspection
This patch fixes two issues noticed by inspection when going to enable the loop predication code in IndVarSimplify. Issue 1 - Both the LoopPredication transform, and the already on by default optimizeLoopExits transform, modify the exit count of the exits they modify. (either to 0 or Infinity) Looking at the code more closely, this was not reflected into SCEV and we were instead running later transforms with incorrect SCEVs. Fixing this requires forgetting the loop, weakening a too strong assert, and updating SCEV to not pessimize results when a loop is provable untaken. I haven't been able to find a test case to demonstrate the miscompile. Issue 2 - For modules without a data layout, we can end up with unsized pointer typed exit counts. Just bail out of this case. I think these are the last two issues which need addressed before we enable this by default. The code has already survived a decent amount of fuzzing without revealing either of the above. Differential Revision: https://reviews.llvm.org/D69695
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index e4295f64dca..ebdaf4eda07 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -7075,6 +7075,17 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
// Do a union of all the predicates here.
for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
BasicBlock *ExitBB = ExitingBlocks[i];
+
+ // We canonicalize untaken exits to br (constant), ignore them so that
+ // proving an exit untaken doesn't negatively impact our ability to reason
+ // about the loop as whole.
+ if (auto *BI = dyn_cast<BranchInst>(ExitBB->getTerminator()))
+ if (auto *CI = dyn_cast<ConstantInt>(BI->getCondition())) {
+ bool ExitIfTrue = !L->contains(BI->getSuccessor(0));
+ if ((ExitIfTrue && CI->isZero()) || (!ExitIfTrue && CI->isOne()))
+ continue;
+ }
+
ExitLimit EL = computeExitLimit(L, ExitBB, AllowPredicates);
assert((AllowPredicates || EL.Predicates.empty()) &&
OpenPOWER on IntegriCloud