mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 21:35:07 +00:00
A little bit more build_vector enhancement for v8i16 cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27959 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
86661f4879
commit
c78d3b43f5
@ -2154,6 +2154,78 @@ static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
|
||||
return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
|
||||
}
|
||||
|
||||
/// LowerBuildVectorv16i8 - Custom lower build_vector of v16i8.
|
||||
///
|
||||
static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
|
||||
unsigned NumNonZero, unsigned NumZero,
|
||||
SelectionDAG &DAG) {
|
||||
if (NumNonZero > 8)
|
||||
return SDOperand();
|
||||
|
||||
SDOperand V(0, 0);
|
||||
bool First = true;
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
bool ThisIsNonZero = (NonZeros & (1 << i)) != 0;
|
||||
if (ThisIsNonZero && First) {
|
||||
if (NumZero)
|
||||
V = getZeroVector(MVT::v8i16, DAG);
|
||||
else
|
||||
V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
|
||||
First = false;
|
||||
}
|
||||
|
||||
if ((i & 1) != 0) {
|
||||
SDOperand ThisElt(0, 0), LastElt(0, 0);
|
||||
bool LastIsNonZero = (NonZeros & (1 << (i-1))) != 0;
|
||||
if (LastIsNonZero) {
|
||||
LastElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i-1));
|
||||
}
|
||||
if (ThisIsNonZero) {
|
||||
ThisElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i));
|
||||
ThisElt = DAG.getNode(ISD::SHL, MVT::i16,
|
||||
ThisElt, DAG.getConstant(8, MVT::i8));
|
||||
if (LastIsNonZero)
|
||||
ThisElt = DAG.getNode(ISD::OR, MVT::i16, ThisElt, LastElt);
|
||||
} else
|
||||
ThisElt = LastElt;
|
||||
|
||||
if (ThisElt.Val)
|
||||
V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, ThisElt,
|
||||
DAG.getConstant(i/2, MVT::i32));
|
||||
}
|
||||
}
|
||||
|
||||
return DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, V);
|
||||
}
|
||||
|
||||
/// LowerBuildVectorv16i8 - Custom lower build_vector of v8i16.
|
||||
///
|
||||
static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
|
||||
unsigned NumNonZero, unsigned NumZero,
|
||||
SelectionDAG &DAG) {
|
||||
if (NumNonZero > 4)
|
||||
return SDOperand();
|
||||
|
||||
SDOperand V(0, 0);
|
||||
bool First = true;
|
||||
for (unsigned i = 0; i < 8; ++i) {
|
||||
bool isNonZero = (NonZeros & (1 << i)) != 0;
|
||||
if (isNonZero) {
|
||||
if (First) {
|
||||
if (NumZero)
|
||||
V = getZeroVector(MVT::v8i16, DAG);
|
||||
else
|
||||
V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
|
||||
First = false;
|
||||
}
|
||||
V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, Op.getOperand(i),
|
||||
DAG.getConstant(i, MVT::i32));
|
||||
}
|
||||
}
|
||||
|
||||
return V;
|
||||
}
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
@ -3152,38 +3224,49 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return SDOperand();
|
||||
}
|
||||
case ISD::BUILD_VECTOR: {
|
||||
// All zero's are handled with pxor.
|
||||
if (ISD::isBuildVectorAllZeros(Op.Val))
|
||||
return Op;
|
||||
|
||||
// All one's are handled with pcmpeqd.
|
||||
if (ISD::isBuildVectorAllOnes(Op.Val))
|
||||
return Op;
|
||||
|
||||
unsigned NumElems = Op.getNumOperands();
|
||||
if (NumElems == 2)
|
||||
return SDOperand();
|
||||
|
||||
unsigned Half = NumElems/2;
|
||||
MVT::ValueType VT = Op.getValueType();
|
||||
MVT::ValueType EVT = MVT::getVectorBaseType(VT);
|
||||
unsigned EVTBits = MVT::getSizeInBits(EVT);
|
||||
|
||||
// Let legalizer expand 2-widde build_vector's.
|
||||
if (EVTBits == 64)
|
||||
return SDOperand();
|
||||
|
||||
unsigned NumElems = Op.getNumOperands();
|
||||
unsigned NumZero = 0;
|
||||
unsigned NumNonZero = 0;
|
||||
unsigned NonZeros = 0;
|
||||
std::set<SDOperand> Values;
|
||||
for (unsigned i = 0; i < NumElems; ++i) {
|
||||
SDOperand Elt = Op.getOperand(i);
|
||||
Values.insert(Elt);
|
||||
if (isZeroNode(Elt))
|
||||
NumZero++;
|
||||
else if (Elt.getOpcode() != ISD::UNDEF)
|
||||
NonZeros |= (1 << i);
|
||||
if (Elt.getOpcode() != ISD::UNDEF) {
|
||||
Values.insert(Elt);
|
||||
if (isZeroNode(Elt))
|
||||
NumZero++;
|
||||
else {
|
||||
NonZeros |= (1 << i);
|
||||
NumNonZero++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned NumNonZero = CountPopulation_32(NonZeros);
|
||||
if (NumNonZero == 0)
|
||||
return Op;
|
||||
// Must be a mix of zero and undef. Return a zero vector.
|
||||
return getZeroVector(VT, DAG);
|
||||
|
||||
// Splat is obviously ok. Let legalizer expand it to a shuffle.
|
||||
if (Values.size() == 1)
|
||||
return SDOperand();
|
||||
|
||||
// If element VT is >= 32 bits, turn it into a number of shuffles.
|
||||
// Special case for single non-zero element.
|
||||
if (NumNonZero == 1) {
|
||||
unsigned Idx = CountTrailingZeros_32(NonZeros);
|
||||
SDOperand Item = Op.getOperand(Idx);
|
||||
@ -3193,7 +3276,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
return getShuffleVectorZeroOrUndef(Item, VT, NumElems, Idx,
|
||||
NumZero > 0, DAG);
|
||||
|
||||
if (MVT::getSizeInBits(EVT) >= 32) {
|
||||
if (EVTBits == 32) {
|
||||
// Turn it into a shuffle of zero and zero-extended scalar to vector.
|
||||
Item = getShuffleVectorZeroOrUndef(Item, VT, NumElems, 0, NumZero > 0,
|
||||
DAG);
|
||||
@ -3209,37 +3292,17 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
}
|
||||
|
||||
// If element VT is < 32 bits, convert it to inserts into a zero vector.
|
||||
if (MVT::getSizeInBits(EVT) <= 16) {
|
||||
if (NumNonZero <= Half) {
|
||||
SDOperand V(0, 0);
|
||||
|
||||
for (unsigned i = 0; i < NumNonZero; ++i) {
|
||||
unsigned Idx = CountTrailingZeros_32(NonZeros);
|
||||
NonZeros ^= (1 << Idx);
|
||||
SDOperand Item = Op.getOperand(Idx);
|
||||
if (i == 0) {
|
||||
if (NumZero)
|
||||
V = getZeroVector(MVT::v8i16, DAG);
|
||||
else
|
||||
V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
|
||||
}
|
||||
if (EVT == MVT::i8) {
|
||||
Item = DAG.getNode(ISD::ANY_EXTEND, MVT::i16, Item);
|
||||
if ((Idx % 2) != 0)
|
||||
Item = DAG.getNode(ISD::SHL, MVT::i16,
|
||||
Item, DAG.getConstant(8, MVT::i8));
|
||||
Idx /= 2;
|
||||
}
|
||||
V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, Item,
|
||||
DAG.getConstant(Idx, MVT::i32));
|
||||
}
|
||||
|
||||
if (EVT == MVT::i8)
|
||||
V = DAG.getNode(ISD::BIT_CONVERT, VT, V);
|
||||
return V;
|
||||
}
|
||||
if (EVTBits == 8) {
|
||||
SDOperand V = LowerBuildVectorv16i8(Op, NonZeros,NumNonZero,NumZero, DAG);
|
||||
if (V.Val) return V;
|
||||
}
|
||||
|
||||
if (EVTBits == 16) {
|
||||
SDOperand V = LowerBuildVectorv8i16(Op, NonZeros,NumNonZero,NumZero, DAG);
|
||||
if (V.Val) return V;
|
||||
}
|
||||
|
||||
// If element VT is == 32 bits, turn it into a number of shuffles.
|
||||
std::vector<SDOperand> V(NumElems);
|
||||
if (NumElems == 4 && NumZero > 0) {
|
||||
for (unsigned i = 0; i < 4; ++i) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user