summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2017-11-22 06:21:39 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2017-11-22 06:21:39 +0000
commitf66b47b32879fceffde1fe1511500ae3ce749667 (patch)
tree25ac2327091a39251f58000ee92b907d70f22892 /lib/Analysis
parent882fbe3d4ca592cdc6be84327ff21d691df5d0d3 (diff)
[SCEV] Strengthen variance condition in calculateLoopDisposition
Given loops `L1` and `L2` with AddRecs `AR1` and `AR2` varying in them respectively. When identifying loop disposition of `AR2` w.r.t. `L1`, we only say that it is varying if `L1` contains `L2`. But there is also a possible situation where `L1` and `L2` are consecutive sibling loops within the parent loop. In this case, `AR2` is also varying w.r.t. `L1`, but we don't correctly identify it. It can lead, for exaple, to attempt of incorrect folding. Consider: AR1 = {a,+,b}<L1> AR2 = {c,+,d}<L2> EXAR2 = sext(AR1) MUL = mul AR1, EXAR2 If we incorrectly assume that `EXAR2` is invariant w.r.t. `L1`, we can end up trying to construct something like: `{a * {c,+,d}<L2>,+,b * {c,+,d}<L2>}<L1>`, which is incorrect because `AR2` is not available on entrance of `L1`. Both situations "`L1` contains `L2`" and "`L1` preceeds sibling loop `L2`" can be handled with one check: "header of `L1` dominates header of `L2`". This patch replaces the old insufficient check with this one. Differential Revision: https://reviews.llvm.org/D39453 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@318819 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 5a88e68dc90..d2a7a545733 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -10927,9 +10927,11 @@ ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
if (!L)
return LoopVariant;
- // This recurrence is variant w.r.t. L if L contains AR's loop.
- if (L->contains(AR->getLoop()))
+ // Everything that is not defined at loop entry is variant.
+ if (DT.dominates(L->getHeader(), AR->getLoop()->getHeader()))
return LoopVariant;
+ assert(!L->contains(AR->getLoop()) && "Containing loop's header does not"
+ " dominate the contained loop's header?");
// This recurrence is invariant w.r.t. L if AR's loop contains L.
if (AR->getLoop()->contains(L))