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.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145099 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 5a03f44..7e35fd2 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3431,6 +3431,41 @@
   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 @@
                               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 @@
     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