diff options
author | David Greene <greened@obbligato.org> | 2011-02-10 16:57:36 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2011-02-10 16:57:36 +0000 |
commit | 74a579d9eb1c822f6dd4689671f9ea100666fa03 (patch) | |
tree | 8801374e41478e539054fe4fcc92012aeda8a06c /lib | |
parent | 8e5d01cd6efa99a26c8584711a7e8abbcf14c333 (diff) | |
download | llvm-74a579d9eb1c822f6dd4689671f9ea100666fa03.tar.gz llvm-74a579d9eb1c822f6dd4689671f9ea100666fa03.tar.bz2 llvm-74a579d9eb1c822f6dd4689671f9ea100666fa03.tar.xz |
[AVX] Implement 256-bit vector lowering for EXTRACT_VECTOR_ELT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125284 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index ea7eef7320..fff006e3b8 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -80,7 +80,9 @@ static SDValue ConcatVectors(SDValue Lower, SDValue Upper, SelectionDAG &DAG); /// Generate a DAG to grab 128-bits from a vector > 128 bits. This /// sets things up to match to an AVX VEXTRACTF128 instruction or a -/// simple subregister reference. +/// simple subregister reference. Idx is an index in the 128 bits we +/// want. It need not be aligned to a 128-bit bounday. That makes +/// lowering EXTRACT_VECTOR_ELT operations easier. static SDValue Extract128BitVector(SDValue Vec, SDValue Idx, SelectionDAG &DAG, @@ -5917,6 +5919,38 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, if (!isa<ConstantSDNode>(Op.getOperand(1))) return SDValue(); + SDValue Vec = Op.getOperand(0); + EVT VecVT = Vec.getValueType(); + + // If this is a 256-bit vector result, first extract the 128-bit + // vector and then extract from the 128-bit vector. + if (VecVT.getSizeInBits() > 128) { + DebugLoc dl = Op.getNode()->getDebugLoc(); + unsigned NumElems = VecVT.getVectorNumElements(); + SDValue Idx = Op.getOperand(1); + + if (!isa<ConstantSDNode>(Idx)) + return SDValue(); + + unsigned ExtractNumElems = NumElems / (VecVT.getSizeInBits() / 128); + unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); + + // Get the 128-bit vector. + bool Upper = IdxVal >= ExtractNumElems; + Vec = Extract128BitVector(Vec, Idx, DAG, dl); + + // Extract from it. + SDValue ScaledIdx = Idx; + if (Upper) + ScaledIdx = DAG.getNode(ISD::SUB, dl, Idx.getValueType(), Idx, + DAG.getConstant(ExtractNumElems, + Idx.getValueType())); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, Op.getValueType(), Vec, + ScaledIdx); + } + + assert(Vec.getValueSizeInBits() <= 128 && "Unexpected vector length"); + if (Subtarget->hasSSE41()) { SDValue Res = LowerEXTRACT_VECTOR_ELT_SSE4(Op, DAG); if (Res.getNode()) |