aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-09-06 21:42:18 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-09-06 21:42:18 +0000
commitc103a08a1115249548d6bb57a74a16de4f0864e3 (patch)
tree015086e49c8ab2b9b9997fa0d132cb4aee987075 /lib/Analysis/ScalarEvolution.cpp
parent34c4485b7479a12b5ef1cb15d27e96277e8a499a (diff)
downloadexternal_llvm-c103a08a1115249548d6bb57a74a16de4f0864e3.zip
external_llvm-c103a08a1115249548d6bb57a74a16de4f0864e3.tar.gz
external_llvm-c103a08a1115249548d6bb57a74a16de4f0864e3.tar.bz2
This transform only handles two-operand AddRec's. Prevent it from trying to
handle anything more complex. Fixes PR10383 again! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp36
1 files changed, 23 insertions, 13 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index b4c4da6..57c4265 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -1974,7 +1974,8 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// multiplied together. If so, we can fold them.
for (unsigned OtherIdx = Idx+1;
OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
- ++OtherIdx)
+ ++OtherIdx) {
+ bool Retry = false;
if (AddRecLoop == cast<SCEVAddRecExpr>(Ops[OtherIdx])->getLoop()) {
// {A,+,B}<L> * {C,+,D}<L> --> {A*C,+,A*D + B*C + B*D,+,2*B*D}<L>
//
@@ -1985,7 +1986,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// Rearranging, X = x, Y = y+z, Z = 2z.
//
// x = A*C, y = (A*D + B*C), z = B*D.
- // Therefore X = A*C, Y = (A*D + B*C) + B*D and Z = 2*B*D.
+ // Therefore X = A*C, Y = A*D + B*C + B*D and Z = 2*B*D.
for (; OtherIdx != Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
++OtherIdx)
if (const SCEVAddRecExpr *OtherAddRec =
@@ -2002,19 +2003,28 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
const SCEV *NewSecondOrderStep =
getMulExpr(BD, getConstant(BD->getType(), 2));
- SmallVector<const SCEV *, 3> AddRecOps;
- AddRecOps.push_back(NewStart);
- AddRecOps.push_back(NewStep);
- AddRecOps.push_back(NewSecondOrderStep);
- const SCEV *NewAddRec = getAddRecExpr(AddRecOps,
- AddRec->getLoop(),
- SCEV::FlagAnyWrap);
- if (Ops.size() == 2) return NewAddRec;
- Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
- Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
+ // This can happen when AddRec or OtherAddRec have >3 operands.
+ // TODO: support these add-recs.
+ if (isLoopInvariant(NewStart, AddRecLoop) &&
+ isLoopInvariant(NewStep, AddRecLoop) &&
+ isLoopInvariant(NewSecondOrderStep, AddRecLoop)) {
+ SmallVector<const SCEV *, 3> AddRecOps;
+ AddRecOps.push_back(NewStart);
+ AddRecOps.push_back(NewStep);
+ AddRecOps.push_back(NewSecondOrderStep);
+ const SCEV *NewAddRec = getAddRecExpr(AddRecOps,
+ AddRec->getLoop(),
+ SCEV::FlagAnyWrap);
+ if (Ops.size() == 2) return NewAddRec;
+ Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
+ Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
+ Retry = true;
+ }
}
- return getMulExpr(Ops);
+ if (Retry)
+ return getMulExpr(Ops);
}
+ }
// Otherwise couldn't fold anything into this recurrence. Move onto the
// next one.