forked from OSchip/llvm-project
[APInt] Add saturating multiply ops
Summary: There are `*_ov()` functions already, so at least for consistency it may be good to also have saturating variants. These may or may not be needed for `ConstantRange`'s `mulWithNoWrap()` Reviewers: spatel, nikic Reviewed By: nikic Subscribers: hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69397
This commit is contained in:
parent
59a51d84b3
commit
b2c184458e
|
@ -1109,6 +1109,8 @@ public:
|
|||
APInt uadd_sat(const APInt &RHS) const;
|
||||
APInt ssub_sat(const APInt &RHS) const;
|
||||
APInt usub_sat(const APInt &RHS) const;
|
||||
APInt smul_sat(const APInt &RHS) const;
|
||||
APInt umul_sat(const APInt &RHS) const;
|
||||
|
||||
/// Array-indexing support.
|
||||
///
|
||||
|
|
|
@ -2048,6 +2048,27 @@ APInt APInt::usub_sat(const APInt &RHS) const {
|
|||
return APInt(BitWidth, 0);
|
||||
}
|
||||
|
||||
APInt APInt::smul_sat(const APInt &RHS) const {
|
||||
bool Overflow;
|
||||
APInt Res = smul_ov(RHS, Overflow);
|
||||
if (!Overflow)
|
||||
return Res;
|
||||
|
||||
// The result is negative if one and only one of inputs is negative.
|
||||
bool ResIsNegative = isNegative() ^ RHS.isNegative();
|
||||
|
||||
return ResIsNegative ? APInt::getSignedMinValue(BitWidth)
|
||||
: APInt::getSignedMaxValue(BitWidth);
|
||||
}
|
||||
|
||||
APInt APInt::umul_sat(const APInt &RHS) const {
|
||||
bool Overflow;
|
||||
APInt Res = umul_ov(RHS, Overflow);
|
||||
if (!Overflow)
|
||||
return Res;
|
||||
|
||||
return APInt::getMaxValue(BitWidth);
|
||||
}
|
||||
|
||||
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
|
||||
// Check our assumptions here
|
||||
|
|
|
@ -1197,6 +1197,24 @@ TEST(APIntTest, SaturatingMath) {
|
|||
EXPECT_EQ(APInt(8, 127), AP_100.ssub_sat(-AP_100));
|
||||
EXPECT_EQ(APInt(8, -128), (-AP_100).ssub_sat(AP_100));
|
||||
EXPECT_EQ(APInt(8, -128), APInt(8, -128).ssub_sat(APInt(8, 127)));
|
||||
|
||||
EXPECT_EQ(APInt(8, 250), APInt(8, 50).umul_sat(APInt(8, 5)));
|
||||
EXPECT_EQ(APInt(8, 255), APInt(8, 50).umul_sat(APInt(8, 6)));
|
||||
EXPECT_EQ(APInt(8, 255), APInt(8, -128).umul_sat(APInt(8, 3)));
|
||||
EXPECT_EQ(APInt(8, 255), APInt(8, 3).umul_sat(APInt(8, -128)));
|
||||
EXPECT_EQ(APInt(8, 255), APInt(8, -128).umul_sat(APInt(8, -128)));
|
||||
|
||||
EXPECT_EQ(APInt(8, 125), APInt(8, 25).smul_sat(APInt(8, 5)));
|
||||
EXPECT_EQ(APInt(8, 127), APInt(8, 25).smul_sat(APInt(8, 6)));
|
||||
EXPECT_EQ(APInt(8, 127), APInt(8, 127).smul_sat(APInt(8, 127)));
|
||||
EXPECT_EQ(APInt(8, -125), APInt(8, -25).smul_sat(APInt(8, 5)));
|
||||
EXPECT_EQ(APInt(8, -125), APInt(8, 25).smul_sat(APInt(8, -5)));
|
||||
EXPECT_EQ(APInt(8, 125), APInt(8, -25).smul_sat(APInt(8, -5)));
|
||||
EXPECT_EQ(APInt(8, 125), APInt(8, 25).smul_sat(APInt(8, 5)));
|
||||
EXPECT_EQ(APInt(8, -128), APInt(8, -25).smul_sat(APInt(8, 6)));
|
||||
EXPECT_EQ(APInt(8, -128), APInt(8, 25).smul_sat(APInt(8, -6)));
|
||||
EXPECT_EQ(APInt(8, 127), APInt(8, -25).smul_sat(APInt(8, -6)));
|
||||
EXPECT_EQ(APInt(8, 127), APInt(8, 25).smul_sat(APInt(8, 6)));
|
||||
}
|
||||
|
||||
TEST(APIntTest, FromArray) {
|
||||
|
|
Loading…
Reference in New Issue