[llvm-commits] [llvm] r123131 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp

Chris Lattner sabre at nondot.org
Tue Jan 11 09:16:35 PST 2011


On Jan 10, 2011, at 2:07 PM, Dan Gohman wrote:
> On Jan 9, 2011, at 2:26 PM, Chris Lattner wrote:
>> /// getMinusSCEV - Return a SCEV corresponding to LHS - RHS.
>> ///
>> -const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS,
>> -                                          const SCEV *RHS) {
>> +const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
>> +                                          bool HasNUW, bool HasNSW) {
>>  // Fast path: X - X --> 0.
>>  if (LHS == RHS)
>>    return getConstant(LHS->getType(), 0);
>> 
>>  // X - Y --> X + -Y
>> -  return getAddExpr(LHS, getNegativeSCEV(RHS));
>> +  return getAddExpr(LHS, getNegativeSCEV(RHS), HasNUW, HasNSW);
> 
> This isn't safe. For example, suppose X and Y are bot INT_MIN (dynamically).
> Then X - Y does not overflow, but X + -Y does.

Ok, the only current client of this is reasoning about the generated add, not the hypothetical subtract.  You're right that this is confusing, I added a clarifying comment in r123243.

>> +static const SCEVAddRecExpr *
>> +isSimpleUnwrappingAddRec(const SCEV *S, const Loop *L) {
>> +  const SCEVAddRecExpr *SA = dyn_cast<SCEVAddRecExpr>(S);
>> +  
>> +  // The SCEV must be an addrec of this loop.
>> +  if (!SA || SA->getLoop() != L || !SA->isAffine())
>> +    return 0;
>> +  
>> +  // The SCEV must be known to not wrap in some way to be interesting.
>> +  if (!SA->hasNoUnsignedWrap() && !SA->hasNoSignedWrap())
>> +    return 0;
> 
> It's suspicious that this code doesn't care which of nsw or nuw
> the instruction has.

NSW is enough to know that the bounds is limited to (e.g.) 2^32, just in a different coordinate space.   It means you can't "stride past" a value.  

> 
>> 
>> +  
>> +  // If the strides are equal, then this is just a (complex) loop invariant
>> +  // comparison of a/b.
>> +  if (LHSStride == RHSStride)
>> +    return SE.getMinusSCEV(LHSA->getStart(), RHSA->getStart());
> 
> The comment should say a-b, not a/b.

Ok, I didn't actually mean divide, I tweaked the wording.

>> +  // If the signs of the strides differ, then the negative stride is counting
>> +  // down to the positive stride.
>> +  if (LHSStride->getValue().isNegative() != RHSStride->getValue().isNegative()){
>> +    if (RHSStride->getValue().isNegative())
>> +      std::swap(LHS, RHS);
>> +  } else {
>> +    // If LHS's stride is smaller than RHS's stride, then "b" must be less than
>> +    // "a" and "b" is RHS is counting up (catching up) to LHS.  This is true
>> +    // whether the strides are positive or negative.
>> +    if (RHSStride->getValue().slt(LHSStride->getValue()))
>> +      std::swap(LHS, RHS);
>> +  }
>> +    
>> +  return SE.getMinusSCEV(LHS, RHS, true /*HasNUW*/);
> 
> This isn't safe if the addrecs are nsw but not nuw (following the suspicion
> above).

How so?

Thanks for the review!!

-Chris





More information about the llvm-commits mailing list