diff options
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 393a810db7f..2469d867044 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -9,6 +9,7 @@ #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/KnownBits.h" #include "gtest/gtest.h" using namespace llvm; @@ -1406,4 +1407,68 @@ TEST_F(ConstantRangeTest, SignedSubOverflowExhautive) { }); } +TEST_F(ConstantRangeTest, FromKnownBits) { + KnownBits Unknown(16); + EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/false)); + EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/true)); + + // .10..01. -> unsigned 01000010 (66) to 11011011 (219) + // -> signed 11000010 (194) to 01011011 (91) + KnownBits Known(8); + Known.Zero = 36; + Known.One = 66; + ConstantRange Unsigned(APInt(8, 66), APInt(8, 219 + 1)); + ConstantRange Signed(APInt(8, 194), APInt(8, 91 + 1)); + EXPECT_EQ(Unsigned, ConstantRange::fromKnownBits(Known, /*signed*/false)); + EXPECT_EQ(Signed, ConstantRange::fromKnownBits(Known, /*signed*/true)); + + // 1.10.10. -> 10100100 (164) to 11101101 (237) + Known.Zero = 18; + Known.One = 164; + ConstantRange CR1(APInt(8, 164), APInt(8, 237 + 1)); + EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/false)); + EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/true)); + + // 01.0.1.0 -> 01000100 (68) to 01101110 (110) + Known.Zero = 145; + Known.One = 68; + ConstantRange CR2(APInt(8, 68), APInt(8, 110 + 1)); + EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/false)); + EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/true)); +} + +TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) { + unsigned Bits = 4; + unsigned Max = 1 << Bits; + KnownBits Known(Bits); + for (unsigned Zero = 0; Zero < Max; ++Zero) { + for (unsigned One = 0; One < Max; ++One) { + Known.Zero = Zero; + Known.One = One; + if (Known.hasConflict() || Known.isUnknown()) + continue; + + APInt MinUnsigned = APInt::getMaxValue(Bits); + APInt MaxUnsigned = APInt::getMinValue(Bits); + APInt MinSigned = APInt::getSignedMaxValue(Bits); + APInt MaxSigned = APInt::getSignedMinValue(Bits); + for (unsigned N = 0; N < Max; ++N) { + APInt Num(Bits, N); + if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0) + continue; + + if (Num.ult(MinUnsigned)) MinUnsigned = Num; + if (Num.ugt(MaxUnsigned)) MaxUnsigned = Num; + if (Num.slt(MinSigned)) MinSigned = Num; + if (Num.sgt(MaxSigned)) MaxSigned = Num; + } + + ConstantRange UnsignedCR(MinUnsigned, MaxUnsigned + 1); + ConstantRange SignedCR(MinSigned, MaxSigned + 1); + EXPECT_EQ(UnsignedCR, ConstantRange::fromKnownBits(Known, false)); + EXPECT_EQ(SignedCR, ConstantRange::fromKnownBits(Known, true)); + } + } +} + } // anonymous namespace |