Exapnd a VECTOR_SHUFFLE to a BUILD_VECTOR if target asks for it to be expanded
authorEvan Cheng <evan.cheng@apple.com>
Wed, 5 Apr 2006 06:07:11 +0000 (06:07 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 5 Apr 2006 06:07:11 +0000 (06:07 +0000)
or custom lowering fails.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27432 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

index 1d624dbc14742ea0566c99f225f82af46b477a27..b0d0b37aa6430e894ad6024d02d60ea7d60e7649 100644 (file)
@@ -933,9 +933,37 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
              "vector shuffle should not be created if not legal!");
       break;
     case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.Val) Result = Tmp1;
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand: {
+      MVT::ValueType VT = Node->getValueType(0);
+      MVT::ValueType EltVT = MVT::getVectorBaseType(VT);
+      MVT::ValueType PtrVT = TLI.getPointerTy();
+      SDOperand Mask = Node->getOperand(2);
+      unsigned NumElems = Mask.getNumOperands();
+      std::vector<SDOperand> Ops;
+      for (unsigned i = 0; i != NumElems; ++i) {
+        SDOperand Arg = Mask.getOperand(i);
+        if (Arg.getOpcode() == ISD::UNDEF) {
+          Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
+        } else {
+          assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
+          unsigned Idx = cast<ConstantSDNode>(Arg)->getValue();
+          if (Idx < NumElems)
+            Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp1,
+                                      DAG.getConstant(Idx, PtrVT)));
+          else
+            Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp2,
+                                      DAG.getConstant(Idx - NumElems, PtrVT)));
+        }
+      }
+      Result = DAG.getNode(ISD::BUILD_VECTOR, VT, Ops);
       break;
+    }
     case TargetLowering::Promote: {
       // Change base type to a different vector type.
       MVT::ValueType OVT = Node->getValueType(0);