Rewrite the overflow checking in the get{Signed,Unsigned}Range code for

AddRecs so that it checks for overflow in the computation that it is
performing, rather than just checking hasNo{Signed,Unsigned}Wrap, since
those flags are for a different computation. This fixes a bug that
impacts an upcoming change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101028 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2010-04-12 07:39:33 +00:00
parent dd842e34c8
commit 646e047765

View File

@ -2933,14 +2933,26 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty); MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart(); const SCEV *Start = AddRec->getStart();
const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this); const SCEV *Step = AddRec->getStepRecurrence(*this);
// Check for overflow.
if (!AddRec->hasNoUnsignedWrap())
return ConservativeResult;
ConstantRange StartRange = getUnsignedRange(Start); ConstantRange StartRange = getUnsignedRange(Start);
ConstantRange EndRange = getUnsignedRange(End); ConstantRange StepRange = getSignedRange(Step);
ConstantRange MaxBECountRange = getUnsignedRange(MaxBECount);
ConstantRange EndRange =
StartRange.add(MaxBECountRange.multiply(StepRange));
// Check for overflow. This must be done with ConstantRange arithmetic
// because we could be called from within the ScalarEvolution overflow
// checking code.
ConstantRange ExtStartRange = StartRange.zextOrTrunc(BitWidth*2+1);
ConstantRange ExtStepRange = StepRange.sextOrTrunc(BitWidth*2+1);
ConstantRange ExtMaxBECountRange =
MaxBECountRange.zextOrTrunc(BitWidth*2+1);
ConstantRange ExtEndRange = EndRange.zextOrTrunc(BitWidth*2+1);
if (ExtStartRange.add(ExtMaxBECountRange.multiply(ExtStepRange)) !=
ExtEndRange)
return ConservativeResult;
APInt Min = APIntOps::umin(StartRange.getUnsignedMin(), APInt Min = APIntOps::umin(StartRange.getUnsignedMin(),
EndRange.getUnsignedMin()); EndRange.getUnsignedMin());
APInt Max = APIntOps::umax(StartRange.getUnsignedMax(), APInt Max = APIntOps::umax(StartRange.getUnsignedMax(),
@ -3064,14 +3076,26 @@ ScalarEvolution::getSignedRange(const SCEV *S) {
MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty); MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty);
const SCEV *Start = AddRec->getStart(); const SCEV *Start = AddRec->getStart();
const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this); const SCEV *Step = AddRec->getStepRecurrence(*this);
// Check for overflow.
if (!AddRec->hasNoSignedWrap())
return ConservativeResult;
ConstantRange StartRange = getSignedRange(Start); ConstantRange StartRange = getSignedRange(Start);
ConstantRange EndRange = getSignedRange(End); ConstantRange StepRange = getSignedRange(Step);
ConstantRange MaxBECountRange = getUnsignedRange(MaxBECount);
ConstantRange EndRange =
StartRange.add(MaxBECountRange.multiply(StepRange));
// Check for overflow. This must be done with ConstantRange arithmetic
// because we could be called from within the ScalarEvolution overflow
// checking code.
ConstantRange ExtStartRange = StartRange.sextOrTrunc(BitWidth*2+1);
ConstantRange ExtStepRange = StepRange.sextOrTrunc(BitWidth*2+1);
ConstantRange ExtMaxBECountRange =
MaxBECountRange.zextOrTrunc(BitWidth*2+1);
ConstantRange ExtEndRange = EndRange.sextOrTrunc(BitWidth*2+1);
if (ExtStartRange.add(ExtMaxBECountRange.multiply(ExtStepRange)) !=
ExtEndRange)
return ConservativeResult;
APInt Min = APIntOps::smin(StartRange.getSignedMin(), APInt Min = APIntOps::smin(StartRange.getSignedMin(),
EndRange.getSignedMin()); EndRange.getSignedMin());
APInt Max = APIntOps::smax(StartRange.getSignedMax(), APInt Max = APIntOps::smax(StartRange.getSignedMax(),