diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-28 15:40:56 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-28 15:40:56 +0000 |
commit | 7a94795b2b7fb9eb3f9bbfa514f3b28fec59408a (patch) | |
tree | 82e3c51412a3b2c73aacb251e45cc72b864830fe /llvm/lib/IR/ConstantRange.cpp | |
parent | d394195221ad1a446e0318b7417abd1076512243 (diff) | |
download | bcm5719-llvm-7a94795b2b7fb9eb3f9bbfa514f3b28fec59408a.tar.gz bcm5719-llvm-7a94795b2b7fb9eb3f9bbfa514f3b28fec59408a.zip |
[ConstantRange] Add makeExactNoWrapRegion()
I got confused on the terminology, and the change in D60598 was not
correct. I was thinking of "exact" in terms of the result being
non-approximate. However, the relevant distinction here is whether
the result is
* Largest range such that:
Forall Y in Other: Forall X in Result: X BinOp Y does not wrap.
(makeGuaranteedNoWrapRegion)
* Smallest range such that:
Forall Y in Other: Forall X not in Result: X BinOp Y wraps.
(A hypothetical makeAllowedNoWrapRegion)
* Both. (makeExactNoWrapRegion)
I'm adding a separate makeExactNoWrapRegion method accepting a
single APInt (same as makeExactICmpRegion) and using it in the
places where the guarantee is relevant.
Differential Revision: https://reviews.llvm.org/D60960
llvm-svn: 359402
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 76e0b0ca5b3..e40bbbb7e9a 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -309,6 +309,14 @@ ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, } } +ConstantRange ConstantRange::makeExactNoWrapRegion(Instruction::BinaryOps BinOp, + const APInt &Other, + unsigned NoWrapKind) { + // makeGuaranteedNoWrapRegion() is exact for single-element ranges, as + // "for all" and "for any" coincide in this case. + return makeGuaranteedNoWrapRegion(BinOp, ConstantRange(Other), NoWrapKind); +} + bool ConstantRange::isFullSet() const { return Lower == Upper && Lower.isMaxValue(); } @@ -843,10 +851,8 @@ ConstantRange::add(const ConstantRange &Other) const { ConstantRange ConstantRange::addWithNoSignedWrap(const APInt &Other) const { // Calculate the subset of this range such that "X + Other" is // guaranteed not to wrap (overflow) for all X in this subset. - // makeGuaranteedNoWrapRegion will produce an exact NSW range. - auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(BinaryOperator::Add, - ConstantRange(Other), - OverflowingBinaryOperator::NoSignedWrap); + auto NSWRange = ConstantRange::makeExactNoWrapRegion( + BinaryOperator::Add, Other, OverflowingBinaryOperator::NoSignedWrap); auto NSWConstrainedRange = intersectWith(NSWRange); return NSWConstrainedRange.add(ConstantRange(Other)); |