aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support/ConstantRange.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-09-06 23:52:49 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-09-06 23:52:49 +0000
commit096983faabc9e98c906ff8ab3fe440acea15db8f (patch)
tree092226f89f03ed3f6063bdd508313f56831f403d /lib/Support/ConstantRange.cpp
parent85d7402f9e63ab2da66b153d24d1edb6f73d8c1c (diff)
downloadexternal_llvm-096983faabc9e98c906ff8ab3fe440acea15db8f.zip
external_llvm-096983faabc9e98c906ff8ab3fe440acea15db8f.tar.gz
external_llvm-096983faabc9e98c906ff8ab3fe440acea15db8f.tar.bz2
Add a new isSignWrappedSet() method to ConstantRange.
Fix zeroExtend and signExtend to support empty sets, and to return the smallest possible result set which contains the extension of each element in their inputs. For example zext i8 [100, 10) to i16 is now [0, 256), not i16 [100, 10) which contains 63446 members. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113187 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/ConstantRange.cpp')
-rw-r--r--lib/Support/ConstantRange.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index 8ef3785..defb818 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -115,6 +115,14 @@ bool ConstantRange::isWrappedSet() const {
return Lower.ugt(Upper);
}
+/// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
+/// its bitwidth, for example: i8 [120, 140).
+///
+bool ConstantRange::isSignWrappedSet() const {
+ return contains(APInt::getSignedMaxValue(getBitWidth())) &&
+ contains(APInt::getSignedMinValue(getBitWidth()));
+}
+
/// getSetSize - Return the number of elements in this set.
///
APInt ConstantRange::getSetSize() const {
@@ -408,10 +416,12 @@ ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
/// correspond to the possible range of values as if the source range had been
/// zero extended.
ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
+ if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
+
unsigned SrcTySize = getBitWidth();
assert(SrcTySize < DstTySize && "Not a value extension");
- if (isFullSet())
- // Change a source full set into [0, 1 << 8*numbytes)
+ if (isFullSet() || isWrappedSet())
+ // Change into [0, 1 << src bit width)
return ConstantRange(APInt(DstTySize,0), APInt(DstTySize,1).shl(SrcTySize));
APInt L = Lower; L.zext(DstTySize);
@@ -424,9 +434,11 @@ ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
/// correspond to the possible range of values as if the source range had been
/// sign extended.
ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
+ if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
+
unsigned SrcTySize = getBitWidth();
assert(SrcTySize < DstTySize && "Not a value extension");
- if (isFullSet()) {
+ if (isFullSet() || isSignWrappedSet()) {
return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
}