aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-04-24 18:01:45 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-04-24 18:01:45 +0000
commitc78d3b43f5156f2a2718886337bc27aac83e8e93 (patch)
treec18d3575135dc4b2d514cf3884a278db12d12431
parent86661f4879c4f18a963f22929b37c3d43a94c799 (diff)
downloadexternal_llvm-c78d3b43f5156f2a2718886337bc27aac83e8e93.zip
external_llvm-c78d3b43f5156f2a2718886337bc27aac83e8e93.tar.gz
external_llvm-c78d3b43f5156f2a2718886337bc27aac83e8e93.tar.bz2
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
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp147
1 files changed, 105 insertions, 42 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 8d52c56..1a11c32 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -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 (EVTBits == 8) {
+ SDOperand V = LowerBuildVectorv16i8(Op, NonZeros,NumNonZero,NumZero, DAG);
+ if (V.Val) return V;
+ }
- if (EVT == MVT::i8)
- V = DAG.getNode(ISD::BIT_CONVERT, VT, V);
- 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) {