forked from OSchip/llvm-project
[ConstantRange] Shl considers full-set shifting to last bit position.
if we do SHL of two 16-bit ranges like [0, 30000) with [1,2) we get "full-set" instead of what I would have expected [0, 60000) which is still in the 16-bit unsigned range. This patch changes the SHL algorithm to allow getting a usable range even in this case. Differential Revision: https://reviews.llvm.org/D57983 llvm-svn: 357854
This commit is contained in:
parent
545ed223a6
commit
30eb575811
|
@ -1006,8 +1006,12 @@ ConstantRange::shl(const ConstantRange &Other) const {
|
|||
APInt max = getUnsignedMax();
|
||||
APInt Other_umax = Other.getUnsignedMax();
|
||||
|
||||
// If we are shifting by maximum amount of
|
||||
// zero return return the original range.
|
||||
if (Other_umax.isNullValue())
|
||||
return *this;
|
||||
// there's overflow!
|
||||
if (Other_umax.uge(max.countLeadingZeros()))
|
||||
if (Other_umax.ugt(max.countLeadingZeros()))
|
||||
return getFull();
|
||||
|
||||
// FIXME: implement the other tricky cases
|
||||
|
|
|
@ -704,6 +704,8 @@ TEST_F(ConstantRangeTest, UDiv) {
|
|||
}
|
||||
|
||||
TEST_F(ConstantRangeTest, Shl) {
|
||||
ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));
|
||||
ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));
|
||||
EXPECT_EQ(Full.shl(Full), Full);
|
||||
EXPECT_EQ(Full.shl(Empty), Empty);
|
||||
EXPECT_EQ(Full.shl(One), Full); // TODO: [0, (-1 << 0xa) + 1)
|
||||
|
@ -720,6 +722,10 @@ TEST_F(ConstantRangeTest, Shl) {
|
|||
EXPECT_EQ(Some.shl(Some), Full); // TODO: [0xa << 0xa, 0xfc01)
|
||||
EXPECT_EQ(Some.shl(Wrap), Full); // TODO: [0xa, 0x7ff << 0x5 + 1)
|
||||
EXPECT_EQ(Wrap.shl(Wrap), Full);
|
||||
EXPECT_EQ(
|
||||
Some2.shl(ConstantRange(APInt(16, 0x1))),
|
||||
ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));
|
||||
EXPECT_EQ(One.shl(WrapNullMax), Full);
|
||||
}
|
||||
|
||||
TEST_F(ConstantRangeTest, Lshr) {
|
||||
|
|
Loading…
Reference in New Issue