diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-01-01 21:57:34 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-20 22:52:09 +0100 |
commit | a852234f70e344b238824b9d71e8df9c46de62f2 (patch) | |
tree | e100dab9c5882d951eca466538685104157cbb87 /llvm/lib/IR/ConstantRange.cpp | |
parent | e772618f1ee2fe7709a17e6d850623a97e23a8dc (diff) | |
download | llvm-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.cpp | 20 |
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 |