[llvm] [APInt] add sfloordiv_ov APInt's member function (PR #84720)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 10 22:11:35 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: long.chen (lipracer)
<details>
<summary>Changes</summary>
for mlir fold to avoid too many overflow state check
---
Full diff: https://github.com/llvm/llvm-project/pull/84720.diff
3 Files Affected:
- (modified) llvm/include/llvm/ADT/APInt.h (+1)
- (modified) llvm/lib/Support/APInt.cpp (+8)
- (modified) llvm/unittests/ADT/APIntTest.cpp (+38)
``````````diff
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 1fc3c7b2236a17..8a085f8b05ebbd 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -996,6 +996,7 @@ class [[nodiscard]] APInt {
APInt sshl_ov(unsigned Amt, bool &Overflow) const;
APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
APInt ushl_ov(unsigned Amt, bool &Overflow) const;
+ APInt sfloordiv_ov(const APInt &RHS, bool &Overflow) const;
// Operations that saturate
APInt sadd_sat(const APInt &RHS) const;
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index e686b976523302..3bff2856cbdc54 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -2022,6 +2022,14 @@ APInt APInt::ushl_ov(unsigned ShAmt, bool &Overflow) const {
return *this << ShAmt;
}
+APInt APInt::sfloordiv_ov(const APInt &RHS, bool &Overflow) const {
+ auto quotient = sdiv_ov(RHS, Overflow);
+ if ((quotient * RHS != *this) && (isNegative() != RHS.isNegative()))
+ return quotient - 1;
+ else
+ return quotient;
+}
+
APInt APInt::sadd_sat(const APInt &RHS) const {
bool Overflow;
APInt Res = sadd_ov(RHS, Overflow);
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 24324822356bf6..5485978934ed07 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/Alignment.h"
#include "gtest/gtest.h"
#include <array>
+#include <limits>
#include <optional>
using namespace llvm;
@@ -2928,6 +2929,43 @@ TEST(APIntTest, smul_ov) {
}
}
+TEST(APIntTest, sfloordiv_ov) {
+ // test negative quotient
+ {
+ APInt divisor(32, -3, true);
+ APInt dividend(32, 2, true);
+ bool Overflow = false;
+ auto quotient = divisor.sfloordiv_ov(dividend, Overflow);
+ EXPECT_FALSE(Overflow);
+ EXPECT_EQ(-2, quotient.getSExtValue());
+ }
+ // test positive quotient
+ {
+ APInt divisor(32, 3, true);
+ APInt dividend(32, 2, true);
+ bool Overflow = false;
+ auto quotient = divisor.sfloordiv_ov(dividend, Overflow);
+ EXPECT_FALSE(Overflow);
+ EXPECT_EQ(1, quotient.getSExtValue());
+ }
+ // test overflow
+ {
+ auto check_overflow_one = [](auto arg) {
+ using IntTy = decltype(arg);
+ APInt divisor(8 * sizeof(arg), std::numeric_limits<IntTy>::lowest(),
+ true);
+ APInt dividend(8 * sizeof(arg), IntTy(-1), true);
+ bool Overflow = false;
+ [[maybe_unused]] auto quotient = divisor.sfloordiv_ov(dividend, Overflow);
+ EXPECT_TRUE(Overflow);
+ };
+ auto check_overflow_all = [&](auto... args) {
+ (void)std::initializer_list<int>{(check_overflow_one(args), 0)...};
+ };
+ std::apply(check_overflow_all, std::tuple<char, short, int, int64_t>());
+ }
+}
+
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/84720
More information about the llvm-commits
mailing list