[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp

Evan Cheng evan.cheng at apple.com
Wed Apr 19 15:48:29 PDT 2006



Changes in directory llvm/lib/Target/X86:

X86ISelLowering.cpp updated: 1.174 -> 1.175
---
Log message:

- Added support to do aribitrary 4 wide shuffle with no more than three
  instructions.
- Fixed a commute vector_shuff bug.


---
Diffs of the changes:  (+54 -7)

 X86ISelLowering.cpp |   61 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 54 insertions(+), 7 deletions(-)


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.174 llvm/lib/Target/X86/X86ISelLowering.cpp:1.175
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.174	Wed Apr 19 15:35:22 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Wed Apr 19 17:48:17 2006
@@ -1882,7 +1882,10 @@
 
   for (unsigned i = 0; i != NumElems; ++i) {
     SDOperand Arg = Mask.getOperand(i);
-    if (Arg.getOpcode() == ISD::UNDEF) continue;
+    if (Arg.getOpcode() == ISD::UNDEF) {
+      MaskVec.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+      continue;
+    }
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
     unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
     if (Val < NumElems)
@@ -2883,6 +2886,55 @@
       }
     }
 
+    if (NumElems == 4) {
+      // Break it into (shuffle shuffle_hi, shuffle_lo).
+      MVT::ValueType MaskVT = PermMask.getValueType();
+      MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
+      std::map<unsigned, std::pair<int, int> > Locs;
+      std::vector<SDOperand> LoMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
+      std::vector<SDOperand> HiMask(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
+      std::vector<SDOperand> *MaskPtr = &LoMask;
+      unsigned MaskIdx = 0;
+      unsigned LoIdx = 0;
+      unsigned HiIdx = NumElems/2;
+      for (unsigned i = 0; i != NumElems; ++i) {
+        if (i == NumElems/2) {
+          MaskPtr = &HiMask;
+          MaskIdx = 1;
+          LoIdx = 0;
+          HiIdx = NumElems/2;
+        }
+        SDOperand Elt = PermMask.getOperand(i);
+        if (Elt.getOpcode() == ISD::UNDEF) {
+          Locs[i] = std::make_pair(-1, -1);
+        } else if (cast<ConstantSDNode>(Elt)->getValue() < NumElems) {
+          Locs[i] = std::make_pair(MaskIdx, LoIdx);
+          (*MaskPtr)[LoIdx] = Elt;
+          LoIdx++;
+        } else {
+          Locs[i] = std::make_pair(MaskIdx, HiIdx);
+          (*MaskPtr)[HiIdx] = Elt;
+          HiIdx++;
+        }
+      }
+
+      SDOperand LoShuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
+                                DAG.getNode(ISD::BUILD_VECTOR, MaskVT, LoMask));
+      SDOperand HiShuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2,
+                                DAG.getNode(ISD::BUILD_VECTOR, MaskVT, HiMask));
+      std::vector<SDOperand> MaskOps;
+      for (unsigned i = 0; i != NumElems; ++i) {
+        if (Locs[i].first == -1) {
+          MaskOps.push_back(DAG.getNode(ISD::UNDEF, MaskEVT));
+        } else {
+          unsigned Idx = Locs[i].first * NumElems + Locs[i].second;
+          MaskOps.push_back(DAG.getConstant(Idx, MaskEVT));
+        }
+      }
+      return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, LoShuffle, HiShuffle,
+                         DAG.getNode(ISD::BUILD_VECTOR, MaskVT, MaskOps));
+    }
+
     return SDOperand();
   }
   case ISD::BUILD_VECTOR: {
@@ -3286,14 +3338,9 @@
 X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
   // Only do shuffles on 128-bit vector types for now.
   if (MVT::getSizeInBits(VT) == 64) return false;
-  return (Mask.Val->getNumOperands() == 2 ||
+  return (Mask.Val->getNumOperands() <= 4 ||
           isSplatMask(Mask.Val)  ||
-          X86::isMOVSMask(Mask.Val)   ||
-          X86::isMOVSHDUPMask(Mask.Val) ||
-          X86::isMOVSLDUPMask(Mask.Val) ||
-          X86::isPSHUFDMask(Mask.Val) ||
           isPSHUFHW_PSHUFLWMask(Mask.Val) ||
-          X86::isSHUFPMask(Mask.Val)  ||
           X86::isUNPCKLMask(Mask.Val) ||
           X86::isUNPCKL_v_undef_Mask(Mask.Val) ||
           X86::isUNPCKHMask(Mask.Val));






More information about the llvm-commits mailing list