diff options
author | Mon P Wang <wangmp@apple.com> | 2008-12-23 04:03:27 +0000 |
---|---|---|
committer | Mon P Wang <wangmp@apple.com> | 2008-12-23 04:03:27 +0000 |
commit | 62c75ea397bdb3b4de7138a1d67311310da01f40 (patch) | |
tree | 2ccb7956e4027c1376ec029b1304ad80e358bdc5 | |
parent | e6ec25543f05eff353fa6b55ed8d85e702b1dd31 (diff) | |
download | external_llvm-62c75ea397bdb3b4de7138a1d67311310da01f40.zip external_llvm-62c75ea397bdb3b4de7138a1d67311310da01f40.tar.gz external_llvm-62c75ea397bdb3b4de7138a1d67311310da01f40.tar.bz2 |
Fixed code generation for v8i16 and v16i8 splats on X86.
Fixed lowering of v8i16 shuffles for v8i16 when we fall back to extract/insert.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61365 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 6ad9bd2..96ad2eb 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2554,6 +2554,23 @@ static bool isSplatMask(SDNode *N) { return cast<ConstantSDNode>(ElementBase)->getZExtValue() < NumElems; } +/// getSplatMaskEltNo - Given a splat mask, return the index to the element +/// we want to splat. +static SDValue getSplatMaskEltNo(SDNode *N) { + assert(isSplatMask(N) && "Not a splat mask"); + unsigned NumElems = N->getNumOperands(); + SDValue ElementBase; + unsigned i = 0; + for (; i != NumElems; ++i) { + SDValue Elt = N->getOperand(i); + if (isa<ConstantSDNode>(Elt)) + return Elt; + } + assert(0 && " No splat value found!"); + return SDValue(); +} + + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element and it's a 2 or 4 element mask. bool X86::isSplatMask(SDNode *N) { @@ -3000,15 +3017,26 @@ static SDValue PromoteSplat(SDValue Op, SelectionDAG &DAG, bool HasSSE2) { return Op; SDValue V1 = Op.getOperand(0); SDValue Mask = Op.getOperand(2); - unsigned NumElems = Mask.getNumOperands(); + unsigned MaskNumElems = Mask.getNumOperands(); + unsigned NumElems = MaskNumElems; // Special handling of v4f32 -> v4i32. if (VT != MVT::v4f32) { - Mask = getUnpacklMask(NumElems, DAG); + // Find which element we want to splat. + SDNode* EltNoNode = getSplatMaskEltNo(Mask.getNode()).getNode(); + unsigned EltNo = cast<ConstantSDNode>(EltNoNode)->getZExtValue(); + // unpack elements to the correct location while (NumElems > 4) { + if (EltNo < NumElems/2) { + Mask = getUnpacklMask(MaskNumElems, DAG); + } else { + Mask = getUnpackhMask(MaskNumElems, DAG); + EltNo -= NumElems/2; + } V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1, Mask); NumElems >>= 1; } - Mask = getZeroVector(MVT::v4i32, true, DAG); + SDValue Cst = DAG.getConstant(EltNo, MVT::i32); + Mask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst, Cst, Cst, Cst); } V1 = DAG.getNode(ISD::BIT_CONVERT, PVT, V1); @@ -3661,8 +3689,10 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2, ++V2InOrder; } else if (EltIdx < 8) { V1Elts.push_back(Elt); + V2Elts.push_back(DAG.getConstant(i+8, MaskEVT)); ++V1FromV1; } else { + V1Elts.push_back(Elt); V2Elts.push_back(DAG.getConstant(EltIdx-8, MaskEVT)); ++V2FromV2; } |