diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-09-06 21:42:18 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-09-06 21:42:18 +0000 |
commit | e0aa54bb98526b5732c59f7359c66e6cce1ff6f7 (patch) | |
tree | 6f1fc9e24c2bc5f68bd7215150f9a24d383ced6a /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | e0e9630e0776d4692aadda33b3d23bef470efa56 (diff) | |
download | bcm5719-llvm-e0aa54bb98526b5732c59f7359c66e6cce1ff6f7.tar.gz bcm5719-llvm-e0aa54bb98526b5732c59f7359c66e6cce1ff6f7.zip |
This transform only handles two-operand AddRec's. Prevent it from trying to
handle anything more complex. Fixes PR10383 again!
llvm-svn: 139186
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index b4c4da60ee5..57c42656481 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/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. |