Skip to content

Commit b403004

Browse files
authored
ConstRange: factor and introduce splitPosNeg (NFC) (llvm#126528)
Factor out some code that splits a ConstantRange into positive and negative components, introducing ConstantRange::splitPosNeg.
1 parent bfdf30e commit b403004

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

llvm/include/llvm/IR/ConstantRange.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class [[nodiscard]] ConstantRange {
9292
/// unsigned domain.
9393
static ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned);
9494

95+
/// Split the ConstantRange into positive and negative components, ignoring
96+
/// zero values.
97+
std::pair<ConstantRange, ConstantRange> splitPosNeg() const;
98+
9599
/// Produce the smallest range such that all values that may satisfy the given
96100
/// predicate with any value contained within Other is contained in the
97101
/// returned range. Formally, this returns a superset of

llvm/lib/IR/ConstantRange.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ KnownBits ConstantRange::toKnownBits() const {
9595
return Known;
9696
}
9797

98+
std::pair<ConstantRange, ConstantRange> ConstantRange::splitPosNeg() const {
99+
uint32_t BW = getBitWidth();
100+
APInt Zero = APInt::getZero(BW), One = APInt(BW, 1);
101+
APInt SignedMin = APInt::getSignedMinValue(BW);
102+
// There are no positive 1-bit values. The 1 would get interpreted as -1.
103+
ConstantRange PosFilter =
104+
BW == 1 ? getEmpty() : ConstantRange(One, SignedMin);
105+
ConstantRange NegFilter(SignedMin, Zero);
106+
return {intersectWith(PosFilter), intersectWith(NegFilter)};
107+
}
108+
98109
ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
99110
const ConstantRange &CR) {
100111
if (CR.isEmptySet())
@@ -1356,20 +1367,14 @@ ConstantRange::udiv(const ConstantRange &RHS) const {
13561367
}
13571368

13581369
ConstantRange ConstantRange::sdiv(const ConstantRange &RHS) const {
1370+
APInt Zero = APInt::getZero(getBitWidth());
1371+
APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
1372+
13591373
// We split up the LHS and RHS into positive and negative components
13601374
// and then also compute the positive and negative components of the result
13611375
// separately by combining division results with the appropriate signs.
1362-
APInt Zero = APInt::getZero(getBitWidth());
1363-
APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
1364-
// There are no positive 1-bit values. The 1 would get interpreted as -1.
1365-
ConstantRange PosFilter =
1366-
getBitWidth() == 1 ? getEmpty()
1367-
: ConstantRange(APInt(getBitWidth(), 1), SignedMin);
1368-
ConstantRange NegFilter(SignedMin, Zero);
1369-
ConstantRange PosL = intersectWith(PosFilter);
1370-
ConstantRange NegL = intersectWith(NegFilter);
1371-
ConstantRange PosR = RHS.intersectWith(PosFilter);
1372-
ConstantRange NegR = RHS.intersectWith(NegFilter);
1376+
auto [PosL, NegL] = splitPosNeg();
1377+
auto [PosR, NegR] = RHS.splitPosNeg();
13731378

13741379
ConstantRange PosRes = getEmpty();
13751380
if (!PosL.isEmptySet() && !PosR.isEmptySet())

llvm/unittests/IR/ConstantRangeTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,16 @@ TEST(ConstantRange, GetEquivalentICmp) {
21262126
});
21272127
}
21282128

2129+
TEST(ConstantRange, SplitPosNeg) {
2130+
EnumerateInterestingConstantRanges([](const ConstantRange &CR) {
2131+
auto [Pos, Neg] = CR.splitPosNeg();
2132+
EXPECT_TRUE(Pos.isAllPositive());
2133+
EXPECT_TRUE(Neg.isAllNegative());
2134+
if (CR.getBitWidth() == 1)
2135+
EXPECT_TRUE(Pos.isEmptySet());
2136+
});
2137+
}
2138+
21292139
#define EXPECT_MAY_OVERFLOW(op) \
21302140
EXPECT_EQ(ConstantRange::OverflowResult::MayOverflow, (op))
21312141
#define EXPECT_ALWAYS_OVERFLOWS_LOW(op) \

0 commit comments

Comments
 (0)