[llvm-commits] [llvm] r60407 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Analysis/ScalarEvolutionExpander.h include/llvm/Analysis/ScalarEvolutionExpressions.h lib/Analysis/ScalarEvolution.cpp lib/Analysis/ScalarEvolutionExpander.cpp
Nick Lewycky
nicholas at mxc.ca
Wed Jan 7 21:47:11 PST 2009
Dan Gohman wrote:
> Hi Nick,
>
> 254.gap is failing in an SCEV-related assertion failure in llc on x86_64
> as of this commit. I've attached a bugpoint-reduced testcase. Can you
> investigate?
>
Thanks Dan! What's happened is that this patch has exposed more code to
SCEV, which in turn is finding more previously-existing bugs. I haven't
finished analyzing, but I filed it as PR3295 for now. I may not have
time to fix it until next week.
Nick
> Thanks,
>
> Dan
>
>
>
> On Dec 2, 2008, at 12:05 AM, Nick Lewycky wrote:
>
>> Author: nicholas
>> Date: Tue Dec 2 02:05:48 2008
>> New Revision: 60407
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=60407&view=rev
>> Log:
>> Add a new SCEV representing signed division.
>>
>> Modified:
>> llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
>> llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h
>> llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h
>> llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>> llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
>>
>> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=60407&r1=60406&r2=60407&view=diff
>>
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> ======================================================================
>> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
>> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Tue Dec 2
>> 02:05:48 2008
>> @@ -225,6 +225,7 @@
>> return getMulExpr(Ops);
>> }
>> SCEVHandle getUDivExpr(const SCEVHandle &LHS, const SCEVHandle
>> &RHS);
>> + SCEVHandle getSDivExpr(const SCEVHandle &LHS, const SCEVHandle
>> &RHS);
>> SCEVHandle getAddRecExpr(const SCEVHandle &Start, const
>> SCEVHandle &Step,
>> const Loop *L);
>> SCEVHandle getAddRecExpr(std::vector<SCEVHandle> &Operands,
>>
>> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=60407&r1=60406&r2=60407&view=diff
>>
>>
>> ==============================================================================
>>
>> --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h
>> (original)
>> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Tue
>> Dec 2 02:05:48 2008
>> @@ -104,6 +104,8 @@
>>
>> Value *visitUDivExpr(SCEVUDivExpr *S);
>>
>> + Value *visitSDivExpr(SCEVSDivExpr *S);
>> +
>> Value *visitAddRecExpr(SCEVAddRecExpr *S);
>>
>> Value *visitSMaxExpr(SCEVSMaxExpr *S);
>>
>> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=60407&r1=60406&r2=60407&view=diff
>>
>>
>> ==============================================================================
>>
>> --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h
>> (original)
>> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Tue
>> Dec 2 02:05:48 2008
>> @@ -25,7 +25,7 @@
>> // These should be ordered in terms of increasing complexity to
>> make the
>> // folders simpler.
>> scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr,
>> scMulExpr,
>> - scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown,
>> + scUDivExpr, scSDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
>> scUnknown,
>> scCouldNotCompute
>> };
>>
>> @@ -358,6 +358,55 @@
>>
>>
>>
>> //===--------------------------------------------------------------------===//
>>
>> + /// SCEVSDivExpr - This class represents a binary signed division
>> operation.
>> + ///
>> + class SCEVSDivExpr : public SCEV {
>> + friend class ScalarEvolution;
>> +
>> + SCEVHandle LHS, RHS;
>> + SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
>> + : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {}
>> +
>> + virtual ~SCEVSDivExpr();
>> + public:
>> + const SCEVHandle &getLHS() const { return LHS; }
>> + const SCEVHandle &getRHS() const { return RHS; }
>> +
>> + virtual bool isLoopInvariant(const Loop *L) const {
>> + return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
>> + }
>> +
>> + virtual bool hasComputableLoopEvolution(const Loop *L) const {
>> + return LHS->hasComputableLoopEvolution(L) &&
>> + RHS->hasComputableLoopEvolution(L);
>> + }
>> +
>> + SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
>> + const SCEVHandle
>> &Conc,
>> + ScalarEvolution
>> &SE) const {
>> + SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym,
>> Conc, SE);
>> + SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym,
>> Conc, SE);
>> + if (L == LHS && R == RHS)
>> + return this;
>> + else
>> + return SE.getSDivExpr(L, R);
>> + }
>> +
>> +
>> + virtual const Type *getType() const;
>> +
>> + void print(std::ostream &OS) const;
>> + void print(std::ostream *OS) const { if (OS) print(*OS); }
>> +
>> + /// Methods for support type inquiry through isa, cast, and
>> dyn_cast:
>> + static inline bool classof(const SCEVSDivExpr *S) { return true; }
>> + static inline bool classof(const SCEV *S) {
>> + return S->getSCEVType() == scSDivExpr;
>> + }
>> + };
>> +
>> +
>> +
>> //===--------------------------------------------------------------------===//
>>
>> /// SCEVAddRecExpr - This node represents a polynomial recurrence
>> on the trip
>> /// count of the specified loop.
>> ///
>> @@ -550,6 +599,8 @@
>> return ((SC*)this)->visitMulExpr((SCEVMulExpr*)S);
>> case scUDivExpr:
>> return ((SC*)this)->visitUDivExpr((SCEVUDivExpr*)S);
>> + case scSDivExpr:
>> + return ((SC*)this)->visitSDivExpr((SCEVSDivExpr*)S);
>> case scAddRecExpr:
>> return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S);
>> case scSMaxExpr:
>>
>> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=60407&r1=60406&r2=60407&view=diff
>>
>>
>> ==============================================================================
>>
>> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Dec 2 02:05:48 2008
>> @@ -324,6 +324,26 @@
>> return LHS->getType();
>> }
>>
>> +
>> +// SCEVSDivs - Only allow the creation of one SCEVSDivExpr for any
>> particular
>> +// input. Don't use a SCEVHandle here, or else the object will
>> never be
>> +// deleted!
>> +static ManagedStatic<std::map<std::pair<SCEV*, SCEV*>,
>> + SCEVSDivExpr*> > SCEVSDivs;
>> +
>> +SCEVSDivExpr::~SCEVSDivExpr() {
>> + SCEVSDivs->erase(std::make_pair(LHS, RHS));
>> +}
>> +
>> +void SCEVSDivExpr::print(std::ostream &OS) const {
>> + OS << "(" << *LHS << " /s " << *RHS << ")";
>> +}
>> +
>> +const Type *SCEVSDivExpr::getType() const {
>> + return LHS->getType();
>> +}
>> +
>> +
>> // SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr
>> for any
>> // particular input. Don't use a SCEVHandle here, or else the object
>> will never
>> // be deleted!
>> @@ -1109,9 +1129,12 @@
>> }
>>
>> SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, const
>> SCEVHandle &RHS) {
>> + if (LHS == RHS)
>> + return getIntegerSCEV(1, LHS->getType()); // X udiv X --> 1
>> +
>> if (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
>> if (RHSC->getValue()->equalsInt(1))
>> - return LHS; // X udiv 1 --> x
>> + return LHS; // X udiv 1 --> X
>>
>> if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
>> Constant *LHSCV = LHSC->getValue();
>> @@ -1120,13 +1143,34 @@
>> }
>> }
>>
>> - // FIXME: implement folding of (X*4)/4 when we know X*4 doesn't
>> overflow.
>> -
>> SCEVUDivExpr *&Result = (*SCEVUDivs)[std::make_pair(LHS, RHS)];
>> if (Result == 0) Result = new SCEVUDivExpr(LHS, RHS);
>> return Result;
>> }
>>
>> +SCEVHandle ScalarEvolution::getSDivExpr(const SCEVHandle &LHS, const
>> SCEVHandle &RHS) {
>> + if (LHS == RHS)
>> + return getIntegerSCEV(1, LHS->getType()); // X sdiv X --> 1
>> +
>> + if (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
>> + if (RHSC->getValue()->equalsInt(1))
>> + return LHS; // X sdiv 1 --> X
>> +
>> + if (RHSC->getValue()->isAllOnesValue())
>> + return getNegativeSCEV(LHS); // X sdiv -1 --> -X
>> +
>> + if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
>> + Constant *LHSCV = LHSC->getValue();
>> + Constant *RHSCV = RHSC->getValue();
>> + return getUnknown(ConstantExpr::getSDiv(LHSCV, RHSCV));
>> + }
>> + }
>> +
>> + SCEVSDivExpr *&Result = (*SCEVSDivs)[std::make_pair(LHS, RHS)];
>> + if (Result == 0) Result = new SCEVSDivExpr(LHS, RHS);
>> + return Result;
>> +}
>> +
>>
>> /// SCEVAddRecExpr::get - Get a add recurrence expression for the
>> /// specified loop. Simplify the expression as much as possible.
>> @@ -1732,7 +1776,7 @@
>> return MinOpRes;
>> }
>>
>> - // SCEVUDivExpr, SCEVUnknown
>> + // SCEVUDivExpr, SCEVSDivExpr, SCEVUnknown
>> return 0;
>> }
>>
>> @@ -1762,6 +1806,9 @@
>> case Instruction::UDiv:
>> return SE.getUDivExpr(getSCEV(U->getOperand(0)),
>> getSCEV(U->getOperand(1)));
>> + case Instruction::SDiv:
>> + return SE.getSDivExpr(getSCEV(U->getOperand(0)),
>> + getSCEV(U->getOperand(1)));
>> case Instruction::Sub:
>> return SE.getMinusSCEV(getSCEV(U->getOperand(0)),
>> getSCEV(U->getOperand(1)));
>> @@ -1805,7 +1852,7 @@
>> break;
>>
>> case Instruction::LShr:
>> - // Turn logical shift right of a constant into a unsigned divide.
>> + // Turn logical shift right of a constant into an unsigned divide.
>> if (ConstantInt *SA = dyn_cast<ConstantInt>(U->getOperand(1))) {
>> uint32_t BitWidth =
>> cast<IntegerType>(V->getType())->getBitWidth();
>> Constant *X = ConstantInt::get(
>> @@ -2505,16 +2552,26 @@
>> return Comm;
>> }
>>
>> - if (SCEVUDivExpr *Div = dyn_cast<SCEVUDivExpr>(V)) {
>> - SCEVHandle LHS = getSCEVAtScope(Div->getLHS(), L);
>> + if (SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(V)) {
>> + SCEVHandle LHS = getSCEVAtScope(UDiv->getLHS(), L);
>> if (LHS == UnknownValue) return LHS;
>> - SCEVHandle RHS = getSCEVAtScope(Div->getRHS(), L);
>> + SCEVHandle RHS = getSCEVAtScope(UDiv->getRHS(), L);
>> if (RHS == UnknownValue) return RHS;
>> - if (LHS == Div->getLHS() && RHS == Div->getRHS())
>> - return Div; // must be loop invariant
>> + if (LHS == UDiv->getLHS() && RHS == UDiv->getRHS())
>> + return UDiv; // must be loop invariant
>> return SE.getUDivExpr(LHS, RHS);
>> }
>>
>> + if (SCEVSDivExpr *SDiv = dyn_cast<SCEVSDivExpr>(V)) {
>> + SCEVHandle LHS = getSCEVAtScope(SDiv->getLHS(), L);
>> + if (LHS == UnknownValue) return LHS;
>> + SCEVHandle RHS = getSCEVAtScope(SDiv->getRHS(), L);
>> + if (RHS == UnknownValue) return RHS;
>> + if (LHS == SDiv->getLHS() && RHS == SDiv->getRHS())
>> + return SDiv; // must be loop invariant
>> + return SE.getSDivExpr(LHS, RHS);
>> + }
>> +
>> // If this is a loop recurrence for a loop that does not contain L,
>> then we
>> // are dealing with the final value computed by the loop.
>> if (SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
>>
>> Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=60407&r1=60406&r2=60407&view=diff
>>
>>
>> ==============================================================================
>>
>> --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
>> +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Tue Dec 2
>> 02:05:48 2008
>> @@ -143,6 +143,15 @@
>> return InsertBinop(Instruction::UDiv, LHS, RHS, InsertPt);
>> }
>>
>> +Value *SCEVExpander::visitSDivExpr(SCEVSDivExpr *S) {
>> + // Do not fold sdiv into ashr, unless you know that LHS is
>> positive. On
>> + // negative values, it rounds the wrong way.
>> +
>> + Value *LHS = expand(S->getLHS());
>> + Value *RHS = expand(S->getRHS());
>> + return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt);
>> +}
>> +
>> Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) {
>> const Type *Ty = S->getType();
>> const Loop *L = S->getLoop();
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list