[PATCH] D54332: [APInt] Add methods for saturated add and sub
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 9 09:59:15 PST 2018
nikic created this revision.
nikic added a reviewer: RKSimon.
Herald added subscribers: llvm-commits, kristina, dexonsmith.
This adds the sadd_sat, uadd_sat, ssub_sat, usub_sat methods for performing saturating additions and subtractions to APInt.
Split out from https://reviews.llvm.org/D54237.
Repository:
rL LLVM
https://reviews.llvm.org/D54332
Files:
include/llvm/ADT/APInt.h
lib/Support/APInt.cpp
unittests/ADT/APIntTest.cpp
Index: unittests/ADT/APIntTest.cpp
===================================================================
--- unittests/ADT/APIntTest.cpp
+++ unittests/ADT/APIntTest.cpp
@@ -1176,6 +1176,30 @@
EXPECT_EQ(APInt(32, uint64_t(-72LL)), APInt(32, "-20", 36));
}
+TEST(APIntTest, SaturatingMath) {
+ APInt AP_10 = APInt(8, 10);
+ APInt AP_100 = APInt(8, 100);
+ APInt AP_200 = APInt(8, 200);
+
+ EXPECT_EQ(APInt(8, 200), AP_100.uadd_sat(AP_100));
+ EXPECT_EQ(APInt(8, 255), AP_100.uadd_sat(AP_200));
+ EXPECT_EQ(APInt(8, 255), APInt(8, 255).uadd_sat(APInt(8, 255)));
+
+ EXPECT_EQ(APInt(8, 110), AP_10.sadd_sat(AP_100));
+ EXPECT_EQ(APInt(8, 127), AP_100.sadd_sat(AP_100));
+ EXPECT_EQ(APInt(8, -128), (-AP_100).sadd_sat(-AP_100));
+ EXPECT_EQ(APInt(8, -128), APInt(8, -128).sadd_sat(APInt(8, -128)));
+
+ EXPECT_EQ(APInt(8, 90), AP_100.usub_sat(AP_10));
+ EXPECT_EQ(APInt(8, 0), AP_100.usub_sat(AP_200));
+ EXPECT_EQ(APInt(8, 0), APInt(8, 0).usub_sat(APInt(8, 255)));
+
+ EXPECT_EQ(APInt(8, -90), AP_10.ssub_sat(AP_100));
+ 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)));
+}
+
TEST(APIntTest, FromArray) {
EXPECT_EQ(APInt(32, uint64_t(1)), APInt(32, ArrayRef<uint64_t>(1)));
}
Index: lib/Support/APInt.cpp
===================================================================
--- lib/Support/APInt.cpp
+++ lib/Support/APInt.cpp
@@ -1947,7 +1947,43 @@
return *this << ShAmt;
}
+APInt APInt::sadd_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = sadd_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+ return isNegative() ? APInt::getSignedMinValue(BitWidth)
+ : APInt::getSignedMaxValue(BitWidth);
+}
+
+APInt APInt::uadd_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = uadd_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return APInt::getMaxValue(BitWidth);
+}
+
+APInt APInt::ssub_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = ssub_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return isNegative() ? APInt::getSignedMinValue(BitWidth)
+ : APInt::getSignedMaxValue(BitWidth);
+}
+
+APInt APInt::usub_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = usub_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return APInt(BitWidth, 0);
+}
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
Index: include/llvm/ADT/APInt.h
===================================================================
--- include/llvm/ADT/APInt.h
+++ include/llvm/ADT/APInt.h
@@ -1105,6 +1105,12 @@
APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
+ // Operations that saturate
+ APInt sadd_sat(const APInt &RHS) const;
+ APInt uadd_sat(const APInt &RHS) const;
+ APInt ssub_sat(const APInt &RHS) const;
+ APInt usub_sat(const APInt &RHS) const;
+
/// Array-indexing support.
///
/// \returns the bit value at bitPosition
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54332.173369.patch
Type: text/x-patch
Size: 3096 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181109/c22d0a35/attachment.bin>
More information about the llvm-commits
mailing list