diff options
| author | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2011-11-23 10:23:16 +0000 |
|---|---|---|
| committer | Elena Demikhovsky <elena.demikhovsky@intel.com> | 2011-11-23 10:23:16 +0000 |
| commit | 779ba6d7b72bb52d6f46d273bed0ae45af075b12 (patch) | |
| tree | a735dd3d8fa2fb35615703b99b143d9e98bedd82 /llvm/lib | |
| parent | 8c68f1f3c8990ee8424c601d1587d0f11a1735b9 (diff) | |
| download | bcm5719-llvm-779ba6d7b72bb52d6f46d273bed0ae45af075b12.tar.gz bcm5719-llvm-779ba6d7b72bb52d6f46d273bed0ae45af075b12.zip | |
I added several lines in X86 code generator that allow to choose
VSHUFPS/VSHUFPD instructions while lowering VECTOR_SHUFFLE node. I check a commuted VSHUFP mask.
The patch was reviewed by Bruno.
llvm-svn: 145099
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 5a03f444bd8..7e35fd24a0b 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3431,6 +3431,41 @@ static unsigned getShuffleVSHUFPDYImmediate(SDNode *N) { return Mask; } +/// CommuteVectorShuffleMask - Change values in a shuffle permute mask assuming +/// the two vector operands have swapped position. +static void CommuteVectorShuffleMask(SmallVectorImpl<int> &Mask, EVT VT) { + unsigned NumElems = VT.getVectorNumElements(); + for (unsigned i = 0; i != NumElems; ++i) { + int idx = Mask[i]; + if (idx < 0) + continue; + else if (idx < (int)NumElems) + Mask[i] = idx + NumElems; + else + Mask[i] = idx - NumElems; + } +} + +/// isCommutedVSHUFP() - Return true if swapping operands will +/// allow to use the "vshufpd" or "vshufps" instruction +/// for 256-bit vectors +static bool isCommutedVSHUFPMask(const SmallVectorImpl<int> &Mask, EVT VT, + const X86Subtarget *Subtarget) { + + unsigned NumElems = VT.getVectorNumElements(); + if ((VT.getSizeInBits() != 256) || ((NumElems != 4) && (NumElems != 8))) + return false; + + SmallVector<int, 8> CommutedMask; + for (unsigned i = 0; i < NumElems; ++i) + CommutedMask.push_back(Mask[i]); + + CommuteVectorShuffleMask(CommutedMask, VT); + return (NumElems == 4) ? isVSHUFPDYMask(CommutedMask, VT, Subtarget): + isVSHUFPSYMask(CommutedMask, VT, Subtarget); +} + + /// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to 128-bit /// SHUFPS and SHUFPD. @@ -4233,21 +4268,6 @@ static SDValue CommuteVectorShuffle(ShuffleVectorSDNode *SVOp, SVOp->getOperand(0), &MaskVec[0]); } -/// CommuteVectorShuffleMask - Change values in a shuffle permute mask assuming -/// the two vector operands have swapped position. -static void CommuteVectorShuffleMask(SmallVectorImpl<int> &Mask, EVT VT) { - unsigned NumElems = VT.getVectorNumElements(); - for (unsigned i = 0; i != NumElems; ++i) { - int idx = Mask[i]; - if (idx < 0) - continue; - else if (idx < (int)NumElems) - Mask[i] = idx + NumElems; - else - Mask[i] = idx - NumElems; - } -} - /// ShouldXformToMOVHLPS - Return true if the node should be transformed to /// match movhlps. The lower half elements should come from upper half of /// V1 (and in order), and the upper half elements should come from the upper @@ -6986,6 +7006,17 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const { return getTargetShuffleNode(getSHUFPOpcode(VT), dl, VT, V1, V2, getShuffleVSHUFPDYImmediate(SVOp), DAG); + // Try to swap operands in the node to match x86 shuffle ops + if (isCommutedVSHUFPMask(M, VT, Subtarget)) { + // Now we need to commute operands. + SVOp = cast<ShuffleVectorSDNode>(CommuteVectorShuffle(SVOp, DAG)); + V1 = SVOp->getOperand(0); + V2 = SVOp->getOperand(1); + unsigned Immediate = (NumElems == 4) ? getShuffleVSHUFPDYImmediate(SVOp): + getShuffleVSHUFPSYImmediate(SVOp); + return getTargetShuffleNode(getSHUFPOpcode(VT), dl, VT, V1, V2, Immediate, DAG); + } + //===--------------------------------------------------------------------===// // Since no target specific shuffle was selected for this generic one, // lower it into other known shuffles. FIXME: this isn't true yet, but |

