Move the SplatByte helper to APInt and generalize it a bit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175621 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2013-02-20 13:00:06 +00:00
parent 52981c4b60
commit ad4da0fc32
4 changed files with 28 additions and 29 deletions

View File

@ -505,6 +505,17 @@ public:
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
/// \brief Return a value containing V broadcasted over NewLen bits.
static APInt getSplat(unsigned NewLen, const APInt &V) {
assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
APInt Val = V.zextOrSelf(NewLen);
for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
Val |= Val << I;
return Val;
}
/// \brief Determine if two APInts have the same value, after zero-extending
/// one of them (if needed!) to ensure that the bit-widths match.
static bool isSameValue(const APInt &I1, const APInt &I2) {

View File

@ -2539,18 +2539,6 @@ SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) {
}
}
/// SplatByte - Distribute ByteVal over NumBits bits.
// FIXME: Move this helper to a common place.
static APInt SplatByte(unsigned NumBits, uint8_t ByteVal) {
APInt Val = APInt(NumBits, ByteVal);
unsigned Shift = 8;
for (unsigned i = NumBits; i > 8; i >>= 1) {
Val = (Val << Shift) | Val;
Shift <<= 1;
}
return Val;
}
/// ExpandBitCount - Expand the specified bitcount instruction into operations.
///
SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op,
@ -2568,10 +2556,10 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op,
// This is the "best" algorithm from
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
SDValue Mask55 = DAG.getConstant(SplatByte(Len, 0x55), VT);
SDValue Mask33 = DAG.getConstant(SplatByte(Len, 0x33), VT);
SDValue Mask0F = DAG.getConstant(SplatByte(Len, 0x0F), VT);
SDValue Mask01 = DAG.getConstant(SplatByte(Len, 0x01), VT);
SDValue Mask55 = DAG.getConstant(APInt::getSplat(Len, APInt(8, 0x55)), VT);
SDValue Mask33 = DAG.getConstant(APInt::getSplat(Len, APInt(8, 0x33)), VT);
SDValue Mask0F = DAG.getConstant(APInt::getSplat(Len, APInt(8, 0x0F)), VT);
SDValue Mask01 = DAG.getConstant(APInt::getSplat(Len, APInt(8, 0x01)), VT);
// v = v - ((v >> 1) & 0x55555555...)
Op = DAG.getNode(ISD::SUB, dl, VT, Op,

View File

@ -3377,17 +3377,6 @@ SDValue SelectionDAG::getStackArgumentTokenFactor(SDValue Chain) {
&ArgChains[0], ArgChains.size());
}
/// SplatByte - Distribute ByteVal over NumBits bits.
static APInt SplatByte(unsigned NumBits, uint8_t ByteVal) {
APInt Val = APInt(NumBits, ByteVal);
unsigned Shift = 8;
for (unsigned i = NumBits; i > 8; i >>= 1) {
Val = (Val << Shift) | Val;
Shift <<= 1;
}
return Val;
}
/// getMemsetValue - Vectorized representation of the memset value
/// operand.
static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
@ -3396,7 +3385,8 @@ static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
unsigned NumBits = VT.getScalarType().getSizeInBits();
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
APInt Val = SplatByte(NumBits, C->getZExtValue() & 255);
assert(C->getAPIntValue().getBitWidth() == 8);
APInt Val = APInt::getSplat(NumBits, C->getAPIntValue());
if (VT.isInteger())
return DAG.getConstant(Val, VT);
return DAG.getConstantFP(APFloat(DAG.EVTToAPFloatSemantics(VT), Val), VT);
@ -3406,7 +3396,7 @@ static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
if (NumBits > 8) {
// Use a multiplication with 0x010101... to extend the input to the
// required length.
APInt Magic = SplatByte(NumBits, 0x01);
APInt Magic = APInt::getSplat(NumBits, APInt(8, 0x01));
Value = DAG.getNode(ISD::MUL, dl, VT, Value, DAG.getConstant(Magic, VT));
}

View File

@ -522,4 +522,14 @@ TEST(APIntTest, Rotate) {
EXPECT_EQ(Rot, Big.rotr(144));
}
TEST(APIntTest, Splat) {
APInt ValA(8, 0x01);
EXPECT_EQ(ValA, APInt::getSplat(8, ValA));
EXPECT_EQ(APInt(64, 0x0101010101010101ULL), APInt::getSplat(64, ValA));
APInt ValB(3, 5);
EXPECT_EQ(APInt(4, 0xD), APInt::getSplat(4, ValB));
EXPECT_EQ(APInt(15, 0xDB6D), APInt::getSplat(15, ValB));
}
}