mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
[APInt] Add an isSplat helper and use it in some places.
To complement getSplat. This is more general than the binary decomposition method as it also handles non-pow2 splat sizes. llvm-svn: 233195
This commit is contained in:
parent
2ed53cd9d5
commit
3deba1d2df
@ -407,6 +407,13 @@ public:
|
||||
: getZExtValue();
|
||||
}
|
||||
|
||||
/// \brief Check if the APInt consists of a repeated bit pattern.
|
||||
///
|
||||
/// e.g. 0x01010101 satisfies isSplat(8).
|
||||
/// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
|
||||
/// width without remainder.
|
||||
bool isSplat(unsigned SplatSizeInBits) const;
|
||||
|
||||
/// @}
|
||||
/// \name Value Generators
|
||||
/// @{
|
||||
|
@ -2348,9 +2348,7 @@ Value *llvm::isBytewiseValue(Value *V) {
|
||||
if (CI->getBitWidth() % 8 == 0) {
|
||||
assert(CI->getBitWidth() > 8 && "8 bits should be handled above!");
|
||||
|
||||
// We can check that all bytes of an integer are equal by making use of a
|
||||
// little trick: rotate by 8 and check if it's still the same value.
|
||||
if (CI->getValue() != CI->getValue().rotl(8))
|
||||
if (!CI->getValue().isSplat(8))
|
||||
return nullptr;
|
||||
return ConstantInt::get(V->getContext(), CI->getValue().trunc(8));
|
||||
}
|
||||
|
@ -672,6 +672,14 @@ hash_code llvm::hash_value(const APInt &Arg) {
|
||||
return hash_combine_range(Arg.pVal, Arg.pVal + Arg.getNumWords());
|
||||
}
|
||||
|
||||
bool APInt::isSplat(unsigned SplatSizeInBits) const {
|
||||
assert(getBitWidth() % SplatSizeInBits == 0 &&
|
||||
"SplatSizeInBits must divide width!");
|
||||
// We can check that all parts of an integer are equal by making use of a
|
||||
// little trick: rotate and check if it's still the same value.
|
||||
return *this == rotl(SplatSizeInBits);
|
||||
}
|
||||
|
||||
/// HiBits - This function returns the high "numBits" bits of this APInt.
|
||||
APInt APInt::getHiBits(unsigned numBits) const {
|
||||
return APIntOps::lshr(*this, BitWidth - numBits);
|
||||
|
@ -1403,17 +1403,10 @@ SDValue PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
|
||||
// immediate field for would be zero, and we prefer to use vxor for it.
|
||||
if (ValSizeInBytes < ByteSize) return SDValue();
|
||||
|
||||
// If the element value is larger than the splat value, cut it in half and
|
||||
// check to see if the two halves are equal. Continue doing this until we
|
||||
// get to ByteSize. This allows us to handle 0x01010101 as 0x01.
|
||||
while (ValSizeInBytes > ByteSize) {
|
||||
ValSizeInBytes >>= 1;
|
||||
|
||||
// If the top half equals the bottom half, we're still ok.
|
||||
if (((Value >> (ValSizeInBytes*8)) & ((1 << (8*ValSizeInBytes))-1)) !=
|
||||
(Value & ((1 << (8*ValSizeInBytes))-1)))
|
||||
return SDValue();
|
||||
}
|
||||
// If the element value is larger than the splat value, check if it consists
|
||||
// of a repeated bit pattern of size ByteSize.
|
||||
if (!APInt(ValSizeInBytes * 8, Value).isSplat(ByteSize * 8))
|
||||
return SDValue();
|
||||
|
||||
// Properly sign extend the value.
|
||||
int MaskVal = SignExtend32(Value, ByteSize * 8);
|
||||
|
@ -678,6 +678,46 @@ TEST(APIntTest, nearestLogBase2) {
|
||||
EXPECT_EQ(A9.nearestLogBase2(), UINT32_MAX);
|
||||
}
|
||||
|
||||
TEST(APIntTest, IsSplat) {
|
||||
APInt A(32, 0x01010101);
|
||||
EXPECT_FALSE(A.isSplat(1));
|
||||
EXPECT_FALSE(A.isSplat(2));
|
||||
EXPECT_FALSE(A.isSplat(4));
|
||||
EXPECT_TRUE(A.isSplat(8));
|
||||
EXPECT_TRUE(A.isSplat(16));
|
||||
EXPECT_TRUE(A.isSplat(32));
|
||||
|
||||
APInt B(24, 0xAAAAAA);
|
||||
EXPECT_FALSE(B.isSplat(1));
|
||||
EXPECT_TRUE(B.isSplat(2));
|
||||
EXPECT_TRUE(B.isSplat(4));
|
||||
EXPECT_TRUE(B.isSplat(8));
|
||||
EXPECT_TRUE(B.isSplat(24));
|
||||
|
||||
APInt C(24, 0xABAAAB);
|
||||
EXPECT_FALSE(C.isSplat(1));
|
||||
EXPECT_FALSE(C.isSplat(2));
|
||||
EXPECT_FALSE(C.isSplat(4));
|
||||
EXPECT_FALSE(C.isSplat(8));
|
||||
EXPECT_TRUE(C.isSplat(24));
|
||||
|
||||
APInt D(32, 0xABBAABBA);
|
||||
EXPECT_FALSE(D.isSplat(1));
|
||||
EXPECT_FALSE(D.isSplat(2));
|
||||
EXPECT_FALSE(D.isSplat(4));
|
||||
EXPECT_FALSE(D.isSplat(8));
|
||||
EXPECT_TRUE(D.isSplat(16));
|
||||
EXPECT_TRUE(D.isSplat(32));
|
||||
|
||||
APInt E(32, 0);
|
||||
EXPECT_TRUE(E.isSplat(1));
|
||||
EXPECT_TRUE(E.isSplat(2));
|
||||
EXPECT_TRUE(E.isSplat(4));
|
||||
EXPECT_TRUE(E.isSplat(8));
|
||||
EXPECT_TRUE(E.isSplat(16));
|
||||
EXPECT_TRUE(E.isSplat(32));
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
// Disable the pragma warning from versions of Clang without -Wself-move
|
||||
#pragma clang diagnostic push
|
||||
|
Loading…
Reference in New Issue
Block a user