Skip to content

Commit ea7be26

Browse files
committed
[ConstantRange] Optimize smul_sat() (NFC)
Base the implementation on the APInt smul_sat() implementation, which is much more efficient than performing calculations in double the bitwidth.
1 parent b7e12ca commit ea7be26

File tree

1 file changed

+7
-12
lines changed

1 file changed

+7
-12
lines changed

llvm/lib/IR/ConstantRange.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,20 +1510,15 @@ ConstantRange ConstantRange::smul_sat(const ConstantRange &Other) const {
15101510
// [-1,4) * [-2,3) = min(-1*-2, -1*2, 3*-2, 3*2) = -6.
15111511
// Similarly for the upper bound, swapping min for max.
15121512

1513-
APInt this_min = getSignedMin().sext(getBitWidth() * 2);
1514-
APInt this_max = getSignedMax().sext(getBitWidth() * 2);
1515-
APInt Other_min = Other.getSignedMin().sext(getBitWidth() * 2);
1516-
APInt Other_max = Other.getSignedMax().sext(getBitWidth() * 2);
1513+
APInt Min = getSignedMin();
1514+
APInt Max = getSignedMax();
1515+
APInt OtherMin = Other.getSignedMin();
1516+
APInt OtherMax = Other.getSignedMax();
15171517

1518-
auto L = {this_min * Other_min, this_min * Other_max, this_max * Other_min,
1519-
this_max * Other_max};
1518+
auto L = {Min.smul_sat(OtherMin), Min.smul_sat(OtherMax),
1519+
Max.smul_sat(OtherMin), Max.smul_sat(OtherMax)};
15201520
auto Compare = [](const APInt &A, const APInt &B) { return A.slt(B); };
1521-
1522-
// Note that we wanted to perform signed saturating multiplication,
1523-
// so since we performed plain multiplication in twice the bitwidth,
1524-
// we need to perform signed saturating truncation.
1525-
return getNonEmpty(std::min(L, Compare).truncSSat(getBitWidth()),
1526-
std::max(L, Compare).truncSSat(getBitWidth()) + 1);
1521+
return getNonEmpty(std::min(L, Compare), std::max(L, Compare) + 1);
15271522
}
15281523

15291524
ConstantRange ConstantRange::ushl_sat(const ConstantRange &Other) const {

0 commit comments

Comments
 (0)