aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-01-01 21:57:34 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-20 22:52:09 +0100
commita852234f70e344b238824b9d71e8df9c46de62f2 (patch)
treee100dab9c5882d951eca466538685104157cbb87 /llvm/lib/IR/ConstantRange.cpp
parente772618f1ee2fe7709a17e6d850623a97e23a8dc (diff)
downloadllvm-a852234f70e344b238824b9d71e8df9c46de62f2.zip
llvm-a852234f70e344b238824b9d71e8df9c46de62f2.tar.gz
llvm-a852234f70e344b238824b9d71e8df9c46de62f2.tar.bz2
[ConstantRange] Handle wrapping ranges in min/max (PR48643)
When one of the inputs is a wrapping range, intersect with the union of the two inputs. The union of the two inputs corresponds to the result we would get if we treated the min/max as a simple select. This fixes PR48643.
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 275996d..4dbe1a1 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1058,7 +1058,10 @@ ConstantRange::smax(const ConstantRange &Other) const {
return getEmpty();
APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin());
APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1;
- return getNonEmpty(std::move(NewL), std::move(NewU));
+ ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
+ if (isSignWrappedSet() || Other.isSignWrappedSet())
+ return Res.intersectWith(unionWith(Other, Signed), Signed);
+ return Res;
}
ConstantRange
@@ -1069,7 +1072,10 @@ ConstantRange::umax(const ConstantRange &Other) const {
return getEmpty();
APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1;
- return getNonEmpty(std::move(NewL), std::move(NewU));
+ ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
+ if (isWrappedSet() || Other.isWrappedSet())
+ return Res.intersectWith(unionWith(Other, Unsigned), Unsigned);
+ return Res;
}
ConstantRange
@@ -1080,7 +1086,10 @@ ConstantRange::smin(const ConstantRange &Other) const {
return getEmpty();
APInt NewL = APIntOps::smin(getSignedMin(), Other.getSignedMin());
APInt NewU = APIntOps::smin(getSignedMax(), Other.getSignedMax()) + 1;
- return getNonEmpty(std::move(NewL), std::move(NewU));
+ ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
+ if (isSignWrappedSet() || Other.isSignWrappedSet())
+ return Res.intersectWith(unionWith(Other, Signed), Signed);
+ return Res;
}
ConstantRange
@@ -1091,7 +1100,10 @@ ConstantRange::umin(const ConstantRange &Other) const {
return getEmpty();
APInt NewL = APIntOps::umin(getUnsignedMin(), Other.getUnsignedMin());
APInt NewU = APIntOps::umin(getUnsignedMax(), Other.getUnsignedMax()) + 1;
- return getNonEmpty(std::move(NewL), std::move(NewU));
+ ConstantRange Res = getNonEmpty(std::move(NewL), std::move(NewU));
+ if (isWrappedSet() || Other.isWrappedSet())
+ return Res.intersectWith(unionWith(Other, Unsigned), Unsigned);
+ return Res;
}
ConstantRange