[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