[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp
Evan Cheng
evan.cheng at apple.com
Tue Apr 4 18:47:50 PDT 2006
Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.153 -> 1.154
---
Log message:
Handle v8i16 shuffle that must be broken into a pair of pshufhw / pshuflw.
---
Diffs of the changes: (+55 -2)
X86ISelLowering.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 55 insertions(+), 2 deletions(-)
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.153 llvm/lib/Target/X86/X86ISelLowering.cpp:1.154
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.153 Mon Apr 3 17:30:54 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Apr 4 20:47:37 2006
@@ -1417,7 +1417,7 @@
}
/// isPSHUFHWMask - Return true if the specified VECTOR_SHUFFLE operand
-/// specifies a shuffle of elements that is suitable for input to PSHUFD.
+/// specifies a shuffle of elements that is suitable for input to PSHUFHW.
bool X86::isPSHUFHWMask(SDNode *N) {
assert(N->getOpcode() == ISD::BUILD_VECTOR);
@@ -1447,7 +1447,7 @@
}
/// isPSHUFLWMask - Return true if the specified VECTOR_SHUFFLE operand
-/// specifies a shuffle of elements that is suitable for input to PSHUFD.
+/// specifies a shuffle of elements that is suitable for input to PSHUFLW.
bool X86::isPSHUFLWMask(SDNode *N) {
assert(N->getOpcode() == ISD::BUILD_VECTOR);
@@ -1781,6 +1781,38 @@
return SDOperand();
}
+/// isPSHUFHW_PSHUFLWMask - true if the specified VECTOR_SHUFFLE operand
+/// specifies a 8 element shuffle that can be broken into a pair of
+/// PSHUFHW and PSHUFLW.
+static bool isPSHUFHW_PSHUFLWMask(SDNode *N) {
+ assert(N->getOpcode() == ISD::BUILD_VECTOR);
+
+ if (N->getNumOperands() != 8)
+ return false;
+
+ // Lower quadword shuffled.
+ for (unsigned i = 0; i != 4; ++i) {
+ SDOperand Arg = N->getOperand(i);
+ if (Arg.getOpcode() == ISD::UNDEF) continue;
+ assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
+ unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+ if (Val > 4)
+ return false;
+ }
+
+ // Upper quadword shuffled.
+ for (unsigned i = 4; i != 8; ++i) {
+ SDOperand Arg = N->getOperand(i);
+ if (Arg.getOpcode() == ISD::UNDEF) continue;
+ assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
+ unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+ if (Val < 4 || Val > 7)
+ return false;
+ }
+
+ return true;
+}
+
/// LowerOperation - Provide custom lowering hooks for some operations.
///
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -2590,6 +2622,26 @@
if (X86::isSHUFPMask(PermMask.Val))
return NormalizeVectorShuffle(V1, V2, PermMask, VT, DAG);
+
+ // Handle v8i16 shuffle high / low shuffle node pair.
+ if (VT == MVT::v8i16 && isPSHUFHW_PSHUFLWMask(PermMask.Val)) {
+ MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+ MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+ std::vector<SDOperand> MaskVec;
+ for (unsigned i = 0; i != 4; ++i)
+ MaskVec.push_back(PermMask.getOperand(i));
+ for (unsigned i = 4; i != 8; ++i)
+ MaskVec.push_back(DAG.getConstant(i, BaseVT));
+ SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, MaskVec);
+ V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
+ MaskVec.clear();
+ for (unsigned i = 0; i != 4; ++i)
+ MaskVec.push_back(DAG.getConstant(i, BaseVT));
+ for (unsigned i = 4; i != 8; ++i)
+ MaskVec.push_back(PermMask.getOperand(i));
+ Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, MaskVec);
+ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
+ }
} else {
// Floating point cases in the other order.
if (X86::isSHUFPMask(PermMask.Val))
@@ -2872,6 +2924,7 @@
X86::isPSHUFDMask(Mask.Val) ||
X86::isPSHUFHWMask(Mask.Val) ||
X86::isPSHUFLWMask(Mask.Val) ||
+ isPSHUFHW_PSHUFLWMask(Mask.Val) ||
X86::isSHUFPMask(Mask.Val) ||
X86::isUNPCKLMask(Mask.Val) ||
X86::isUNPCKHMask(Mask.Val));
More information about the llvm-commits
mailing list