diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-07 18:44:36 +0000 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-04-07 18:44:36 +0000 |
| commit | 4246106abac4b0803d46936b808f2bb0c7c18887 (patch) | |
| tree | 1c3df4daa6cdbf13765c9bf4c039d28ae575eeb0 /llvm/unittests | |
| parent | a51883cfab4ea36215549a58f29d65b862ef857c (diff) | |
| download | bcm5719-llvm-4246106abac4b0803d46936b808f2bb0c7c18887.tar.gz bcm5719-llvm-4246106abac4b0803d46936b808f2bb0c7c18887.zip | |
[ConstantRange] Add unsigned and signed intersection types
The intersection of two ConstantRanges may consist of two disjoint
ranges. As we can only return one range as the result, we need to
return one of the two possible ranges that cover both. Currently the
result is picked based on set size. However, this is not always
optimal: If we're in an unsigned context, we'd prefer to get a large
unsigned range over a small signed range -- the latter effectively
becomes a full set in the unsigned domain.
This revision adds a PreferredRangeType, which can be either Smallest,
Unsigned or Signed. Smallest is the current behavior and Unsigned and
Signed are new variants that prefer not to wrap the unsigned/signed
domain. The new type isn't used anywhere yet (but SCEV will be a good
first user, see D60035).
I've also added some comments to illustrate the various cases in
intersectWith(), which should hopefully make it more obvious what is
going on.
Differential Revision: https://reviews.llvm.org/D59959
llvm-svn: 357873
Diffstat (limited to 'llvm/unittests')
| -rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index be4b4766b5d..0b20456664b 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -409,19 +409,30 @@ TEST_F(ConstantRangeTest, IntersectWithExhaustive) { assert(!HaveInterrupt3 && "Should have at most three ranges"); - ConstantRange CR = CR1.intersectWith(CR2); + ConstantRange SmallestCR = + CR1.intersectWith(CR2, ConstantRange::Smallest); + ConstantRange UnsignedCR = + CR1.intersectWith(CR2, ConstantRange::Unsigned); + ConstantRange SignedCR = + CR1.intersectWith(CR2, ConstantRange::Signed); if (!HaveRange1) { - EXPECT_TRUE(CR.isEmptySet()); + EXPECT_TRUE(SmallestCR.isEmptySet()); + EXPECT_TRUE(UnsignedCR.isEmptySet()); + EXPECT_TRUE(SignedCR.isEmptySet()); return; } if (!HaveRange2) { if (Lower1 == Upper1 + 1) { - EXPECT_TRUE(CR.isFullSet()); + EXPECT_TRUE(SmallestCR.isFullSet()); + EXPECT_TRUE(UnsignedCR.isFullSet()); + EXPECT_TRUE(SignedCR.isFullSet()); } else { ConstantRange Expected(Lower1, Upper1 + 1); - EXPECT_EQ(Expected, CR); + EXPECT_EQ(Expected, SmallestCR); + EXPECT_EQ(Expected, UnsignedCR); + EXPECT_EQ(Expected, SignedCR); } return; } @@ -443,13 +454,41 @@ TEST_F(ConstantRangeTest, IntersectWithExhaustive) { Variant2 = ConstantRange(Lower3, Upper2 + 1); } - // The intersection should return the smaller of the two variants. + // Smallest: Smaller set, then any set. if (Variant1.isSizeStrictlySmallerThan(Variant2)) - EXPECT_EQ(Variant1, CR); + EXPECT_EQ(Variant1, SmallestCR); else if (Variant2.isSizeStrictlySmallerThan(Variant1)) - EXPECT_EQ(Variant2, CR); + EXPECT_EQ(Variant2, SmallestCR); else - EXPECT_TRUE(Variant1 == CR || Variant2 == CR); + EXPECT_TRUE(Variant1 == SmallestCR || Variant2 == SmallestCR); + + // Unsigned: Non-wrapped set, then smaller set, then any set. + bool Variant1Full = Variant1.isFullSet() || Variant1.isWrappedSet(); + bool Variant2Full = Variant2.isFullSet() || Variant2.isWrappedSet(); + if (!Variant1Full && Variant2Full) + EXPECT_EQ(Variant1, UnsignedCR); + else if (Variant1Full && !Variant2Full) + EXPECT_EQ(Variant2, UnsignedCR); + else if (Variant1.isSizeStrictlySmallerThan(Variant2)) + EXPECT_EQ(Variant1, UnsignedCR); + else if (Variant2.isSizeStrictlySmallerThan(Variant1)) + EXPECT_EQ(Variant2, UnsignedCR); + else + EXPECT_TRUE(Variant1 == UnsignedCR || Variant2 == UnsignedCR); + + // Signed: Signed non-wrapped set, then smaller set, then any set. + Variant1Full = Variant1.isFullSet() || Variant1.isSignWrappedSet(); + Variant2Full = Variant2.isFullSet() || Variant2.isSignWrappedSet(); + if (!Variant1Full && Variant2Full) + EXPECT_EQ(Variant1, SignedCR); + else if (Variant1Full && !Variant2Full) + EXPECT_EQ(Variant2, SignedCR); + else if (Variant1.isSizeStrictlySmallerThan(Variant2)) + EXPECT_EQ(Variant1, SignedCR); + else if (Variant2.isSizeStrictlySmallerThan(Variant1)) + EXPECT_EQ(Variant2, SignedCR); + else + EXPECT_TRUE(Variant1 == SignedCR || Variant2 == SignedCR); }); } |

