Skip to content

Commit

Permalink
[ConstantRange] Calculate precise range for multiply by -1
Browse files Browse the repository at this point in the history
These are pretty common in SCEV, so make sure we get a precise
result by mapping to the sub() operation.
  • Loading branch information
nikic committed Jun 23, 2023
1 parent 04a8070 commit 7cf567d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
14 changes: 14 additions & 0 deletions llvm/lib/IR/ConstantRange.cpp
Expand Up @@ -1095,6 +1095,20 @@ ConstantRange::multiply(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
return getEmpty();

if (const APInt *C = getSingleElement()) {
if (C->isOne())
return Other;
if (C->isAllOnes())
return ConstantRange(APInt::getZero(getBitWidth())).sub(Other);
}

if (const APInt *C = Other.getSingleElement()) {
if (C->isOne())
return *this;
if (C->isAllOnes())
return ConstantRange(APInt::getZero(getBitWidth())).sub(*this);
}

// Multiplication is signedness-independent. However different ranges can be
// obtained depending on how the input ranges are treated. These different
// ranges are all conservatively correct, but one might be better than the
Expand Down
20 changes: 20 additions & 0 deletions llvm/unittests/IR/ConstantRangeTest.cpp
Expand Up @@ -997,6 +997,26 @@ TEST_F(ConstantRangeTest, Multiply) {
EXPECT_EQ(ConstantRange(APInt(8, -2)).multiply(
ConstantRange(APInt(8, 0), APInt(8, 2))),
ConstantRange(APInt(8, -2), APInt(8, 1)));

// Multiplication by -1 should give precise results.
EXPECT_EQ(ConstantRange(APInt(8, 3), APInt(8, -11))
.multiply(ConstantRange(APInt(8, -1))),
ConstantRange(APInt(8, 12), APInt(8, -2)));
EXPECT_EQ(ConstantRange(APInt(8, -1))
.multiply(ConstantRange(APInt(8, 3), APInt(8, -11))),
ConstantRange(APInt(8, 12), APInt(8, -2)));

TestBinaryOpExhaustive(
[](const ConstantRange &CR1, const ConstantRange &CR2) {
return CR1.multiply(CR2);
},
[](const APInt &N1, const APInt &N2) {
return N1 * N2;
},
PreferSmallest,
[](const ConstantRange &, const ConstantRange &) {
return false; // Check correctness only.
});
}

TEST_F(ConstantRangeTest, smul_fast) {
Expand Down

0 comments on commit 7cf567d

Please sign in to comment.