Skip to content

Commit 199bf42

Browse files
committed
refine
1 parent d1a2ea9 commit 199bf42

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

llvm/include/llvm/ADT/APInt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,11 @@ class [[nodiscard]] APInt {
996996
APInt sshl_ov(unsigned Amt, bool &Overflow) const;
997997
APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
998998
APInt ushl_ov(unsigned Amt, bool &Overflow) const;
999+
1000+
/// Signed integer floor division operation.
1001+
///
1002+
/// Rounds towards negative infinity, i.e. 5 / -2 = -3. Iff minimum value
1003+
/// divided by -1 set Overflow to true.
9991004
APInt sfloordiv_ov(const APInt &RHS, bool &Overflow) const;
10001005

10011006
// Operations that saturate

llvm/lib/Support/APInt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2023,7 +2023,7 @@ APInt APInt::ushl_ov(unsigned ShAmt, bool &Overflow) const {
20232023
}
20242024

20252025
APInt APInt::sfloordiv_ov(const APInt &RHS, bool &Overflow) const {
2026-
auto quotient = sdiv_ov(RHS, Overflow);
2026+
APInt quotient = sdiv_ov(RHS, Overflow);
20272027
if ((quotient * RHS != *this) && (isNegative() != RHS.isNegative()))
20282028
return quotient - 1;
20292029
return quotient;

llvm/unittests/ADT/APIntTest.cpp

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,21 +3068,69 @@ TEST(APIntTest, sfloordiv_ov) {
30683068
EXPECT_FALSE(Overflow);
30693069
EXPECT_EQ(1, quotient.getSExtValue());
30703070
}
3071-
// test overflow
3071+
// int8 test overflow
30723072
{
3073-
auto check_overflow_one = [](auto arg) {
3074-
using IntTy = decltype(arg);
3075-
APInt divisor(8 * sizeof(arg), std::numeric_limits<IntTy>::lowest(),
3076-
true);
3077-
APInt dividend(8 * sizeof(arg), IntTy(-1), true);
3078-
bool Overflow = false;
3079-
[[maybe_unused]] auto quotient = divisor.sfloordiv_ov(dividend, Overflow);
3080-
EXPECT_TRUE(Overflow);
3081-
};
3082-
auto check_overflow_all = [&](auto... args) {
3083-
(void)std::initializer_list<int>{(check_overflow_one(args), 0)...};
3084-
};
3085-
std::apply(check_overflow_all, std::tuple<char, short, int, int64_t>());
3073+
using IntTy = int8_t;
3074+
APInt divisor(8 * sizeof(IntTy), std::numeric_limits<IntTy>::lowest(),
3075+
true);
3076+
APInt dividend(8 * sizeof(IntTy), IntTy(-1), true);
3077+
bool Overflow = false;
3078+
(void)divisor.sfloordiv_ov(dividend, Overflow);
3079+
EXPECT_TRUE(Overflow);
3080+
}
3081+
// int16 test overflow
3082+
{
3083+
using IntTy = int16_t;
3084+
APInt divisor(8 * sizeof(IntTy), std::numeric_limits<IntTy>::lowest(),
3085+
true);
3086+
APInt dividend(8 * sizeof(IntTy), IntTy(-1), true);
3087+
bool Overflow = false;
3088+
(void)divisor.sfloordiv_ov(dividend, Overflow);
3089+
EXPECT_TRUE(Overflow);
3090+
}
3091+
// int32 test overflow
3092+
{
3093+
using IntTy = int32_t;
3094+
APInt divisor(8 * sizeof(IntTy), std::numeric_limits<IntTy>::lowest(),
3095+
true);
3096+
APInt dividend(8 * sizeof(IntTy), IntTy(-1), true);
3097+
bool Overflow = false;
3098+
(void)divisor.sfloordiv_ov(dividend, Overflow);
3099+
EXPECT_TRUE(Overflow);
3100+
}
3101+
// int64 test overflow
3102+
{
3103+
using IntTy = int64_t;
3104+
APInt divisor(8 * sizeof(IntTy), std::numeric_limits<IntTy>::lowest(),
3105+
true);
3106+
APInt dividend(8 * sizeof(IntTy), IntTy(-1), true);
3107+
bool Overflow = false;
3108+
(void)divisor.sfloordiv_ov(dividend, Overflow);
3109+
EXPECT_TRUE(Overflow);
3110+
}
3111+
// test all of int8
3112+
{
3113+
bool Overflow = true;
3114+
for (int i = -128; i < 128; ++i) {
3115+
for (int j = -128; j < 128; ++j) {
3116+
if (j == 0 || (i == -128 && j == -1))
3117+
continue;
3118+
int8_t a = static_cast<int8_t>(i);
3119+
int8_t b = static_cast<int8_t>(j);
3120+
3121+
APInt divisor(8, a, true);
3122+
APInt dividend(8, b, true);
3123+
if (((i >= 0 && j > 0) || (i <= 0 && j < 0)) ||
3124+
(i % j == 0)) // if quotient >= 0 and remain == 0 floordiv
3125+
// equivalent to div
3126+
EXPECT_EQ(divisor.sfloordiv_ov(dividend, Overflow).getSExtValue(),
3127+
a / b);
3128+
else
3129+
EXPECT_EQ(divisor.sfloordiv_ov(dividend, Overflow).getSExtValue(),
3130+
a / b - 1);
3131+
EXPECT_FALSE(Overflow);
3132+
}
3133+
}
30863134
}
30873135
}
30883136

0 commit comments

Comments
 (0)