[ConstantRange] Rename a method and add more doc

Rename makeNoWrapRegion to a more obvious makeGuaranteedNoWrapRegion,
and add a comment about the counter-intuitive aspects of the function.
This is to help prevent cases like PR26628.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261532 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjoy Das 2016-02-22 16:13:02 +00:00
parent 5fa0e4be6e
commit e9d736f57c
4 changed files with 25 additions and 17 deletions

View File

@ -82,16 +82,25 @@ public:
static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
const ConstantRange &Other);
/// Return the largest range containing all X such that "X BinOpC C" does not
/// wrap (overflow).
/// Return the largest range containing all X such that "X BinOpC C" is
/// guaranteed not to wrap (overflow).
///
/// NB! The returned set does *not* contain **all** possible values of X for
/// which "X BinOpC C" does not wrap -- some viable values of X may be
/// missing, so you cannot use this to contrain X's range. E.g. in the last
/// example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), but (-2)
/// is not in the set returned.
///
/// Example:
/// typedef OverflowingBinaryOperator OBO;
/// makeNoWrapRegion(Add, i8 1, OBO::NoSignedWrap) == [-128, 127)
/// makeNoWrapRegion(Add, i8 1, OBO::NoUnsignedWrap) == [0, -1)
/// makeNoWrapRegion(Add, i8 0, OBO::NoUnsignedWrap) == Full Set
static ConstantRange makeNoWrapRegion(Instruction::BinaryOps BinOp,
const APInt &C, unsigned NoWrapKind);
/// makeNoWrapRegion(Add, i8 1, OBO::NoUnsignedWrap | OBO::NoSignedWrap) ==
/// [0,INT_MAX)
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
const APInt &C,
unsigned NoWrapKind);
/// Return the lower value for this range.
///

View File

@ -1969,15 +1969,14 @@ StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type,
const APInt &C = cast<SCEVConstant>(Ops[0])->getAPInt();
if (!(SignOrUnsignWrap & SCEV::FlagNSW)) {
auto NSWRegion =
ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoSignedWrap);
auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, C, OBO::NoSignedWrap);
if (NSWRegion.contains(SE->getSignedRange(Ops[1])))
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW);
}
if (!(SignOrUnsignWrap & SCEV::FlagNUW)) {
auto NUWRegion =
ConstantRange::makeNoWrapRegion(Instruction::Add, C,
OBO::NoUnsignedWrap);
auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, C, OBO::NoUnsignedWrap);
if (NUWRegion.contains(SE->getUnsignedRange(Ops[1])))
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
}

View File

@ -127,9 +127,9 @@ ConstantRange ConstantRange::makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
.inverse();
}
ConstantRange ConstantRange::makeNoWrapRegion(Instruction::BinaryOps BinOp,
const APInt &C,
unsigned NoWrapKind) {
ConstantRange
ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
const APInt &C, unsigned NoWrapKind) {
typedef OverflowingBinaryOperator OBO;
// Computes the intersection of CR0 and CR1. It is different from

View File

@ -577,17 +577,17 @@ TEST(ConstantRange, MakeOverflowingRegion) {
for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
APInt C(4, Const, true /* = isSigned */);
auto NUWRegion =
ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoUnsignedWrap);
auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, C, OBO::NoUnsignedWrap);
EXPECT_FALSE(NUWRegion.isEmptySet());
auto NSWRegion =
ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoSignedWrap);
auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, C, OBO::NoSignedWrap);
EXPECT_FALSE(NSWRegion.isEmptySet());
auto NoWrapRegion = ConstantRange::makeNoWrapRegion(
auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
EXPECT_FALSE(NoWrapRegion.isEmptySet());