mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-27 06:54:30 +00:00
[APInt] Keep the original bit width in quotient and remainder
Some trivial cases in udivrem were handled by directly assigning 0 or 1 to APInt objects. This would set the bit width to 1, instead of the bit width of the inputs. A potentially undesirable side effect of that is that with the bit width of 1, 1 equals -1. Differential Revision: https://reviews.llvm.org/D49554 llvm-svn: 337478
This commit is contained in:
parent
53d54bbc8f
commit
5d9659bfb9
@ -1735,25 +1735,25 @@ void APInt::udivrem(const APInt &LHS, const APInt &RHS,
|
||||
|
||||
// Check the degenerate cases
|
||||
if (lhsWords == 0) {
|
||||
Quotient = 0; // 0 / Y ===> 0
|
||||
Remainder = 0; // 0 % Y ===> 0
|
||||
Quotient = APInt(BitWidth, 0); // 0 / Y ===> 0
|
||||
Remainder = APInt(BitWidth, 0); // 0 % Y ===> 0
|
||||
return;
|
||||
}
|
||||
|
||||
if (rhsBits == 1) {
|
||||
Quotient = LHS; // X / 1 ===> X
|
||||
Remainder = 0; // X % 1 ===> 0
|
||||
Quotient = LHS; // X / 1 ===> X
|
||||
Remainder = APInt(BitWidth, 0); // X % 1 ===> 0
|
||||
}
|
||||
|
||||
if (lhsWords < rhsWords || LHS.ult(RHS)) {
|
||||
Remainder = LHS; // X % Y ===> X, iff X < Y
|
||||
Quotient = 0; // X / Y ===> 0, iff X < Y
|
||||
Remainder = LHS; // X % Y ===> X, iff X < Y
|
||||
Quotient = APInt(BitWidth, 0); // X / Y ===> 0, iff X < Y
|
||||
return;
|
||||
}
|
||||
|
||||
if (LHS == RHS) {
|
||||
Quotient = 1; // X / X ===> 1
|
||||
Remainder = 0; // X % X ===> 0;
|
||||
Quotient = APInt(BitWidth, 1); // X / X ===> 1
|
||||
Remainder = APInt(BitWidth, 0); // X % X ===> 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1801,25 +1801,26 @@ void APInt::udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
|
||||
|
||||
// Check the degenerate cases
|
||||
if (lhsWords == 0) {
|
||||
Quotient = 0; // 0 / Y ===> 0
|
||||
Remainder = 0; // 0 % Y ===> 0
|
||||
Quotient = APInt(BitWidth, 0); // 0 / Y ===> 0
|
||||
Remainder = 0; // 0 % Y ===> 0
|
||||
return;
|
||||
}
|
||||
|
||||
if (RHS == 1) {
|
||||
Quotient = LHS; // X / 1 ===> X
|
||||
Remainder = 0; // X % 1 ===> 0
|
||||
Quotient = LHS; // X / 1 ===> X
|
||||
Remainder = 0; // X % 1 ===> 0
|
||||
return;
|
||||
}
|
||||
|
||||
if (LHS.ult(RHS)) {
|
||||
Remainder = LHS.getZExtValue(); // X % Y ===> X, iff X < Y
|
||||
Quotient = 0; // X / Y ===> 0, iff X < Y
|
||||
Remainder = LHS.getZExtValue(); // X % Y ===> X, iff X < Y
|
||||
Quotient = APInt(BitWidth, 0); // X / Y ===> 0, iff X < Y
|
||||
return;
|
||||
}
|
||||
|
||||
if (LHS == RHS) {
|
||||
Quotient = 1; // X / X ===> 1
|
||||
Remainder = 0; // X % X ===> 0;
|
||||
Quotient = APInt(BitWidth, 1); // X / X ===> 1
|
||||
Remainder = 0; // X % X ===> 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1060,6 +1060,38 @@ TEST(APIntTest, divremuint) {
|
||||
APInt{1024, 1});
|
||||
}
|
||||
|
||||
TEST(APIntTest, divrem_simple) {
|
||||
// Test simple cases.
|
||||
APInt A(65, 2), B(65, 2);
|
||||
APInt Q, R;
|
||||
|
||||
// X / X
|
||||
APInt::sdivrem(A, B, Q, R);
|
||||
EXPECT_EQ(Q, APInt(65, 1));
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
APInt::udivrem(A, B, Q, R);
|
||||
EXPECT_EQ(Q, APInt(65, 1));
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
|
||||
// 0 / X
|
||||
APInt O(65, 0);
|
||||
APInt::sdivrem(O, B, Q, R);
|
||||
EXPECT_EQ(Q, APInt(65, 0));
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
APInt::udivrem(O, B, Q, R);
|
||||
EXPECT_EQ(Q, APInt(65, 0));
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
|
||||
// X / 1
|
||||
APInt I(65, 1);
|
||||
APInt::sdivrem(A, I, Q, R);
|
||||
EXPECT_EQ(Q, A);
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
APInt::udivrem(A, I, Q, R);
|
||||
EXPECT_EQ(Q, A);
|
||||
EXPECT_EQ(R, APInt(65, 0));
|
||||
}
|
||||
|
||||
TEST(APIntTest, fromString) {
|
||||
EXPECT_EQ(APInt(32, 0), APInt(32, "0", 2));
|
||||
EXPECT_EQ(APInt(32, 1), APInt(32, "1", 2));
|
||||
|
Loading…
x
Reference in New Issue
Block a user