Skip to content

Commit 7465da2

Browse files
committed
[ConstantRange] Introduce getMinSignedBits() method
Similar to the ConstantRange::getActiveBits(), and to similarly-named methods in APInt, returns the bitwidth needed to represent the given signed constant range
1 parent b85395f commit 7465da2

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

llvm/include/llvm/IR/ConstantRange.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ class LLVM_NODISCARD ConstantRange {
265265
/// in this range.
266266
unsigned getActiveBits() const;
267267

268+
/// Compute the maximal number of bits needed to represent every value
269+
/// in this signed range.
270+
unsigned getMinSignedBits() const;
271+
268272
/// Subtract the specified constant from the endpoints of this constant range.
269273
ConstantRange subtract(const APInt &CI) const;
270274

llvm/lib/IR/ConstantRange.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,14 @@ unsigned ConstantRange::getActiveBits() const {
420420
return getUnsignedMax().getActiveBits();
421421
}
422422

423+
unsigned ConstantRange::getMinSignedBits() const {
424+
if (isEmptySet())
425+
return 0;
426+
427+
return std::max(getSignedMin().getMinSignedBits(),
428+
getSignedMax().getMinSignedBits());
429+
}
430+
423431
ConstantRange ConstantRange::subtract(const APInt &Val) const {
424432
assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width");
425433
// If the set is empty or full, don't modify the endpoints.

llvm/unittests/IR/ConstantRangeTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,32 @@ TEST_F(ConstantRangeTest, losslessUnsignedTruncationZeroext) {
668668
});
669669
}
670670

671+
TEST_F(ConstantRangeTest, getMinSignedBits) {
672+
unsigned Bits = 4;
673+
EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) {
674+
unsigned Exact = 0;
675+
ForeachNumInConstantRange(CR, [&](const APInt &N) {
676+
Exact = std::max(Exact, N.getMinSignedBits());
677+
});
678+
679+
unsigned ResultCR = CR.getMinSignedBits();
680+
EXPECT_EQ(Exact, ResultCR);
681+
});
682+
}
683+
TEST_F(ConstantRangeTest, losslessSignedTruncationSignext) {
684+
unsigned Bits = 4;
685+
EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) {
686+
unsigned MinBitWidth = CR.getMinSignedBits();
687+
if (MinBitWidth == 0) {
688+
EXPECT_TRUE(CR.isEmptySet());
689+
return;
690+
}
691+
if (MinBitWidth == Bits)
692+
return;
693+
EXPECT_EQ(CR, CR.truncate(MinBitWidth).signExtend(Bits));
694+
});
695+
}
696+
671697
TEST_F(ConstantRangeTest, SubtractAPInt) {
672698
EXPECT_EQ(Full.subtract(APInt(16, 4)), Full);
673699
EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty);

0 commit comments

Comments
 (0)