[llvm-commits] [llvm] r123131 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp
Dan Gohman
gohman at apple.com
Mon Jan 10 14:07:50 PST 2011
On Jan 9, 2011, at 2:26 PM, Chris Lattner wrote:
> @@ -2448,22 +2448,21 @@
>
> /// 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.
> +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.
>
> +
> + // 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.
> +
> + // 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).
Dan
More information about the llvm-commits
mailing list