Added support to LegalizeType for expanding the operands of scalar to vector
authorMon P Wang <wangmp@apple.com>
Mon, 15 Dec 2008 06:57:02 +0000 (06:57 +0000)
committerMon P Wang <wangmp@apple.com>
Mon, 15 Dec 2008 06:57:02 +0000 (06:57 +0000)
and insert vector element.  Modified extract vector element to extend the
result to match the expected promoted type.

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

lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
test/CodeGen/X86/insertelement-legalize.ll [new file with mode: 0644]

index db45e44da937a6d1b02ef3f1c3ae9af1f6029a56..8e864050ed9bcb73b70af896d11ff67c68b88238 100644 (file)
@@ -359,8 +359,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
   if (TLI.isBigEndian())
     std::swap(Lo, Hi);
 
+  // Signed extend to the promoted type.
   SDValue Odd = DAG.getNode(ISD::TRUNCATE, MVT::i1, OldIdx);
-  return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+  SDValue Res = DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+  return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT), Res);
 }
 
 SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
@@ -1938,9 +1940,11 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
       assert(0 && "Do not know how to expand this operator's operand!");
       abort();
 
-    case ISD::BUILD_VECTOR:    Res = ExpandOp_BUILD_VECTOR(N); break;
-    case ISD::BIT_CONVERT:     Res = ExpandOp_BIT_CONVERT(N); break;
-    case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
+    case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
+    case ISD::BIT_CONVERT:       Res = ExpandOp_BIT_CONVERT(N); break;
+    case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
+    case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
+    case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
 
     case ISD::BR_CC:      Res = ExpandIntOp_BR_CC(N); break;
     case ISD::SELECT_CC:  Res = ExpandIntOp_SELECT_CC(N); break;
index 31bf1d1cb60cecb5945583dce4f5eb45ca96d74b..36c89adebc607ec1bb69116443aa484c2db37315 100644 (file)
@@ -613,11 +613,12 @@ private:
   void ExpandRes_VAARG             (SDNode *N, SDValue &Lo, SDValue &Hi);
 
   // Generic Operand Expansion.
-  SDValue ExpandOp_BIT_CONVERT    (SDNode *N);
-  SDValue ExpandOp_BUILD_VECTOR   (SDNode *N);
-  SDValue ExpandOp_EXTRACT_ELEMENT(SDNode *N);
-  SDValue ExpandOp_NormalStore    (SDNode *N, unsigned OpNo);
-
+  SDValue ExpandOp_BIT_CONVERT      (SDNode *N);
+  SDValue ExpandOp_BUILD_VECTOR     (SDNode *N);
+  SDValue ExpandOp_EXTRACT_ELEMENT  (SDNode *N);
+  SDValue ExpandOp_INSERT_VECTOR_ELT(SDNode *N);
+  SDValue ExpandOp_SCALAR_TO_VECTOR (SDNode *N);
+  SDValue ExpandOp_NormalStore      (SDNode *N, unsigned OpNo);
 };
 
 } // end namespace llvm.
index 21a69f578f00c52cb517ddc0187eac3d572e6cef..91fd589db9d004dd7190e6c681bd770d48770e6f 100644 (file)
@@ -280,6 +280,49 @@ SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) {
   return cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() ? Hi : Lo;
 }
 
+SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) {
+  // The vector type is legal but the element type needs expansion.
+  MVT VecVT = N->getValueType(0);
+  unsigned NumElts = VecVT.getVectorNumElements();
+
+  SDValue Val = N->getOperand(1);
+  MVT OldEVT = Val.getValueType();
+  MVT NewEVT = TLI.getTypeToTransformTo(OldEVT);
+
+  assert(OldEVT == VecVT.getVectorElementType() &&
+         "Inserted element type doesn't match vector element type!");
+
+  // Bitconvert to a vector of twice the length with elements of the expanded
+  // type, insert the expanded vector elements, and then convert back.
+  MVT NewVecVT = MVT::getVectorVT(NewEVT, NumElts*2);
+  SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, N->getOperand(0));
+
+  SDValue Lo, Hi;
+  GetExpandedOp(Val, Lo, Hi);
+  if (TLI.isBigEndian())
+    std::swap(Lo, Hi);
+
+  SDValue Idx = N->getOperand(2);
+  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
+  NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Lo, Idx);
+  Idx = DAG.getNode(ISD::ADD,Idx.getValueType(), Idx, DAG.getIntPtrConstant(1));
+  NewVec =  DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Hi, Idx);
+
+  // Convert the new vector to the old vector type.
+  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}
+
+SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) {
+  MVT VT = N->getValueType(0);
+  unsigned NumElts = VT.getVectorNumElements();
+  SmallVector<SDValue, 16> Ops(NumElts);
+  Ops[0] = N->getOperand(0);
+  SDValue UndefVal = DAG.getNode(ISD::UNDEF, Ops[0].getValueType());
+  for (unsigned i = 1; i < NumElts; ++i)
+    Ops[i] = UndefVal;
+  return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts);
+}
+
 SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) {
   assert(ISD::isNormalStore(N) && "This routine only for normal stores!");
   assert(OpNo == 1 && "Can only expand the stored value so far");
diff --git a/test/CodeGen/X86/insertelement-legalize.ll b/test/CodeGen/X86/insertelement-legalize.ll
new file mode 100644 (file)
index 0000000..95e17b4
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc -march=x86 -disable-mmx
+
+; Test to check that we properly legalize an insert vector element
+define void @test(<2 x i64> %val, <2 x i64>* %dst, i64 %x) nounwind {
+entry:
+       %tmp4 = insertelement <2 x i64> %val, i64 %x, i32 0             ; <<2 x i64>> [#uses=1]
+       %add = add <2 x i64> %tmp4, %val                ; <<2 x i64>> [#uses=1]
+       store <2 x i64> %add, <2 x i64>* %dst
+       ret void
+}