[Support] Add KnownBits::getSignedMinValue/getSignedMaxValue helpers.

Add unit test coverage - a followup will update InstCombineCompares.cpp to use this and could be used by D86578 as well.
This commit is contained in:
Simon Pilgrim 2020-12-24 12:07:55 +00:00
parent fb46895308
commit 6895581fd2
2 changed files with 34 additions and 0 deletions

View File

@ -119,12 +119,32 @@ public:
return One;
}
/// Return the minimal signed value possible given these KnownBits.
APInt getSignedMinValue() const {
// Assume that all bits that aren't known-ones are zeros.
APInt Min = One;
// Sign bit is unknown.
if (Zero.isSignBitClear() && One.isSignBitClear())
Min.setSignBit();
return Min;
}
/// Return the maximal unsigned value possible given these KnownBits.
APInt getMaxValue() const {
// Assume that all bits that aren't known-zeros are ones.
return ~Zero;
}
/// Return the maximal signed value possible given these KnownBits.
APInt getSignedMaxValue() const {
// Assume that all bits that aren't known-zeros are ones.
APInt Max = ~Zero;
// Sign bit is unknown.
if (Zero.isSignBitClear() && One.isSignBitClear())
Max.clearSignBit();
return Max;
}
/// Return known bits for a truncation of the value we're tracking.
KnownBits trunc(unsigned BitWidth) const {
return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));

View File

@ -295,6 +295,20 @@ TEST(KnownBitsTest, GetMinMaxVal) {
});
}
TEST(KnownBitsTest, GetSignedMinMaxVal) {
unsigned Bits = 4;
ForeachKnownBits(Bits, [&](const KnownBits &Known) {
APInt Min = APInt::getSignedMaxValue(Bits);
APInt Max = APInt::getSignedMinValue(Bits);
ForeachNumInKnownBits(Known, [&](const APInt &N) {
Min = APIntOps::smin(Min, N);
Max = APIntOps::smax(Max, N);
});
EXPECT_EQ(Min, Known.getSignedMinValue());
EXPECT_EQ(Max, Known.getSignedMaxValue());
});
}
TEST(KnownBitsTest, SExtOrTrunc) {
const unsigned NarrowerSize = 4;
const unsigned BaseSize = 6;