[llvm] r233195 - [APInt] Add an isSplat helper and use it in some places.
Benjamin Kramer
benny.kra at googlemail.com
Wed Mar 25 09:49:59 PDT 2015
Author: d0k
Date: Wed Mar 25 11:49:59 2015
New Revision: 233195
URL: http://llvm.org/viewvc/llvm-project?rev=233195&view=rev
Log:
[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.
Modified:
llvm/trunk/include/llvm/ADT/APInt.h
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/lib/Support/APInt.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/trunk/unittests/ADT/APIntTest.cpp
Modified: llvm/trunk/include/llvm/ADT/APInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=233195&r1=233194&r2=233195&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Wed Mar 25 11:49:59 2015
@@ -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
/// @{
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=233195&r1=233194&r2=233195&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Wed Mar 25 11:49:59 2015
@@ -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));
}
Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=233195&r1=233194&r2=233195&view=diff
==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Wed Mar 25 11:49:59 2015
@@ -672,6 +672,14 @@ hash_code llvm::hash_value(const APInt &
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);
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=233195&r1=233194&r2=233195&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 25 11:49:59 2015
@@ -1403,17 +1403,10 @@ SDValue PPC::get_VSPLTI_elt(SDNode *N, u
// 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);
Modified: llvm/trunk/unittests/ADT/APIntTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=233195&r1=233194&r2=233195&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/APIntTest.cpp (original)
+++ llvm/trunk/unittests/ADT/APIntTest.cpp Wed Mar 25 11:49:59 2015
@@ -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
More information about the llvm-commits
mailing list