summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ADT
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-04-19 02:06:06 +0000
committerFangrui Song <maskray@google.com>2019-04-19 02:06:06 +0000
commitacc7641bcb9df243e7c2e0e8c4636929e21642e8 (patch)
treed83e501952ef4e055f288699cbb06b59aeac0fee /llvm/unittests/ADT
parent9206335e9d100e65f85a73168400875839405f20 (diff)
downloadbcm5719-llvm-acc7641bcb9df243e7c2e0e8c4636929e21642e8.tar.gz
bcm5719-llvm-acc7641bcb9df243e7c2e0e8c4636929e21642e8.zip
[APInt] Optimize umul_ov
Change two costly udiv() calls to lshr(1)*RHS + left-shift + plus On one 64-bit umul_ov benchmark, I measured an obvious improvement: 12.8129s -> 3.6257s Note, there may be some value to special case 64-bit (the most common case) with __builtin_umulll_overflow(). Differential Revision: https://reviews.llvm.org/D60669 llvm-svn: 358730
Diffstat (limited to 'llvm/unittests/ADT')
-rw-r--r--llvm/unittests/ADT/APIntTest.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 6ef5b25f8d4..a92a654ac17 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -2381,6 +2381,42 @@ TEST(APIntTest, RoundingSDiv) {
}
}
+TEST(APIntTest, umul_ov) {
+ const std::pair<uint64_t, uint64_t> Overflows[] = {
+ {0x8000000000000000, 2},
+ {0x5555555555555556, 3},
+ {4294967296, 4294967296},
+ {4294967295, 4294967298},
+ };
+ const std::pair<uint64_t, uint64_t> NonOverflows[] = {
+ {0x7fffffffffffffff, 2},
+ {0x5555555555555555, 3},
+ {4294967295, 4294967297},
+ };
+
+ bool Overflow;
+ for (auto &X : Overflows) {
+ APInt A(64, X.first);
+ APInt B(64, X.second);
+ (void)A.umul_ov(B, Overflow);
+ EXPECT_TRUE(Overflow);
+ }
+ for (auto &X : NonOverflows) {
+ APInt A(64, X.first);
+ APInt B(64, X.second);
+ (void)A.umul_ov(B, Overflow);
+ EXPECT_FALSE(Overflow);
+ }
+
+ for (unsigned Bits = 1; Bits <= 5; ++Bits)
+ for (unsigned A = 0; A != 1u << Bits; ++A)
+ for (unsigned B = 0; B != 1u << Bits; ++B) {
+ APInt C = APInt(Bits, A).umul_ov(APInt(Bits, B), Overflow);
+ APInt D = APInt(2 * Bits, A) * APInt(2 * Bits, B);
+ EXPECT_TRUE(D.getHiBits(Bits).isNullValue() != Overflow);
+ }
+}
+
TEST(APIntTest, SolveQuadraticEquationWrap) {
// Verify that "Solution" is the first non-negative integer that solves
// Ax^2 + Bx + C = "0 or overflow", i.e. that it is a correct solution
OpenPOWER on IntegriCloud