1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

Don't allocate in APInt::slt. NFC.

APInt::slt was copying the LHS and RHS in to temporaries then making
them unsigned so that it could use an unsigned comparision.  It did
this even on the paths which were trivial to give results for, such
as the sign bit of the LHS being set while RHS was not set.

This changes the logic to return out immediately in the trivial cases,
and use an unsigned comparison in the remaining cases.  But this time,
just use the unsigned comparison directly without creating any temporaries.

This works because, for example:
  true = (-2 slt -1) = (0xFE ult 0xFF)

Also added some tests explicitly for slt with APInt's larger than 64-bits
so that this new code is tested.

Using the memory for 'opt -O2 verify-uselistorder.lto.opt.bc -o opt.bc'
(see r236629 for details), this reduces the number of allocations from
26.8M to 23.9M.

llvm-svn: 270881
This commit is contained in:
Pete Cooper 2016-05-26 17:40:07 +00:00
parent 89a8ea9137
commit a4a912aae4
2 changed files with 36 additions and 24 deletions

View File

@ -542,32 +542,16 @@ bool APInt::slt(const APInt& RHS) const {
return lhsSext < rhsSext;
}
APInt lhs(*this);
APInt rhs(RHS);
bool lhsNeg = isNegative();
bool rhsNeg = rhs.isNegative();
if (lhsNeg) {
// Sign bit is set so perform two's complement to make it positive
lhs.flipAllBits();
++lhs;
}
if (rhsNeg) {
// Sign bit is set so perform two's complement to make it positive
rhs.flipAllBits();
++rhs;
}
bool rhsNeg = RHS.isNegative();
// Now we have unsigned values to compare so do the comparison if necessary
// based on the negativeness of the values.
if (lhsNeg)
if (rhsNeg)
return lhs.ugt(rhs);
else
return true;
else if (rhsNeg)
return false;
else
return lhs.ult(rhs);
// If the sign bits don't match, then (LHS < RHS) if LHS is negative
if (lhsNeg != rhsNeg)
return lhsNeg;
// Otherwise we can just use an unsigned comparision, because even negative
// numbers compare correctly this way if both have the same signed-ness.
return ult(RHS);
}
void APInt::setBit(unsigned bitPosition) {

View File

@ -388,6 +388,34 @@ TEST(APIntTest, compareWithHalfInt64Max) {
EXPECT_TRUE( a.sge(edgeM1));
}
TEST(APIntTest, compareLargeIntegers) {
// Make sure all the combinations of signed comparisons work with big ints.
auto One = APInt{128, static_cast<uint64_t>(1), true};
auto Two = APInt{128, static_cast<uint64_t>(2), true};
auto MinusOne = APInt{128, static_cast<uint64_t>(-1), true};
auto MinusTwo = APInt{128, static_cast<uint64_t>(-2), true};
EXPECT_TRUE(!One.slt(One));
EXPECT_TRUE(!Two.slt(One));
EXPECT_TRUE(MinusOne.slt(One));
EXPECT_TRUE(MinusTwo.slt(One));
EXPECT_TRUE(One.slt(Two));
EXPECT_TRUE(!Two.slt(Two));
EXPECT_TRUE(MinusOne.slt(Two));
EXPECT_TRUE(MinusTwo.slt(Two));
EXPECT_TRUE(!One.slt(MinusOne));
EXPECT_TRUE(!Two.slt(MinusOne));
EXPECT_TRUE(!MinusOne.slt(MinusOne));
EXPECT_TRUE(MinusTwo.slt(MinusOne));
EXPECT_TRUE(!One.slt(MinusTwo));
EXPECT_TRUE(!Two.slt(MinusTwo));
EXPECT_TRUE(!MinusOne.slt(MinusTwo));
EXPECT_TRUE(!MinusTwo.slt(MinusTwo));
}
// Tests different div/rem varaints using scheme (a * b + c) / a
void testDiv(APInt a, APInt b, APInt c) {