[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

Dan Gohman gohman at apple.com
Wed Jan 7 16:32:10 PST 2009


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sdiv-scev.bc
Type: application/octet-stream
Size: 704 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20090107/1a40714e/attachment.obj>
-------------- next part --------------



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



More information about the llvm-commits mailing list