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/unittests/IR/ConstantRangeTest.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/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 2b9c56b..12362b9 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -1080,10 +1080,18 @@ TEST_F(ConstantRangeTest, UMax) { EXPECT_EQ(Some.umax(Some), Some); EXPECT_EQ(Some.umax(Wrap), ConstantRange(APInt(16, 0xa), APInt(16, 0))); EXPECT_EQ(Some.umax(One), Some); - // TODO: ConstantRange is currently over-conservative here. - EXPECT_EQ(Wrap.umax(Wrap), Full); + EXPECT_EQ(Wrap.umax(Wrap), Wrap); EXPECT_EQ(Wrap.umax(One), ConstantRange(APInt(16, 0xa), APInt(16, 0))); EXPECT_EQ(One.umax(One), One); + + TestBinaryOpExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.umax(CR2); + }, + [](const APInt &N1, const APInt &N2) { + return APIntOps::umax(N1, N2); + }, + PreferSmallestNonFullUnsigned); } TEST_F(ConstantRangeTest, SMax) { @@ -1105,6 +1113,15 @@ TEST_F(ConstantRangeTest, SMax) { EXPECT_EQ(Wrap.smax(One), ConstantRange(APInt(16, 0xa), APInt(16, (uint64_t)INT16_MIN))); EXPECT_EQ(One.smax(One), One); + + TestBinaryOpExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.smax(CR2); + }, + [](const APInt &N1, const APInt &N2) { + return APIntOps::smax(N1, N2); + }, + PreferSmallestNonFullSigned); } TEST_F(ConstantRangeTest, UMin) { @@ -1119,10 +1136,18 @@ TEST_F(ConstantRangeTest, UMin) { EXPECT_EQ(Some.umin(Some), Some); EXPECT_EQ(Some.umin(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa))); EXPECT_EQ(Some.umin(One), One); - // TODO: ConstantRange is currently over-conservative here. - EXPECT_EQ(Wrap.umin(Wrap), Full); + EXPECT_EQ(Wrap.umin(Wrap), Wrap); EXPECT_EQ(Wrap.umin(One), ConstantRange(APInt(16, 0), APInt(16, 0xb))); EXPECT_EQ(One.umin(One), One); + + TestBinaryOpExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.umin(CR2); + }, + [](const APInt &N1, const APInt &N2) { + return APIntOps::umin(N1, N2); + }, + PreferSmallestNonFullUnsigned); } TEST_F(ConstantRangeTest, SMin) { @@ -1139,11 +1164,19 @@ TEST_F(ConstantRangeTest, SMin) { EXPECT_EQ(Some.smin(Wrap), ConstantRange(APInt(16, (uint64_t)INT16_MIN), APInt(16, 0xaaa))); EXPECT_EQ(Some.smin(One), One); - // TODO: ConstantRange is currently over-conservative here. - EXPECT_EQ(Wrap.smin(Wrap), Full); + EXPECT_EQ(Wrap.smin(Wrap), Wrap); EXPECT_EQ(Wrap.smin(One), ConstantRange(APInt(16, (uint64_t)INT16_MIN), APInt(16, 0xb))); EXPECT_EQ(One.smin(One), One); + + TestBinaryOpExhaustive( + [](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.smin(CR2); + }, + [](const APInt &N1, const APInt &N2) { + return APIntOps::smin(N1, N2); + }, + PreferSmallestNonFullSigned); } TEST_F(ConstantRangeTest, UDiv) { |