Support legalizing insert_vector_elt on targets where the element
type is not legal.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47048 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index d2aae91..2b8d47b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1263,8 +1263,16 @@
break;
case ISD::INSERT_VECTOR_ELT:
Tmp1 = LegalizeOp(Node->getOperand(0)); // InVec
- Tmp2 = LegalizeOp(Node->getOperand(1)); // InVal
Tmp3 = LegalizeOp(Node->getOperand(2)); // InEltNo
+
+ // The type of the value to insert may not be legal, even though the vector
+ // type is legal. Legalize/Promote accordingly. We do not handle Expand
+ // here.
+ switch (getTypeAction(Node->getOperand(1).getValueType())) {
+ default: assert(0 && "Cannot expand insert element operand");
+ case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); break;
+ case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break;
+ }
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
switch (TLI.getOperationAction(ISD::INSERT_VECTOR_ELT,
@@ -1283,30 +1291,35 @@
// If the insert index is a constant, codegen this as a scalar_to_vector,
// then a shuffle that inserts it into the right position in the vector.
if (ConstantSDNode *InsertPos = dyn_cast<ConstantSDNode>(Tmp3)) {
- SDOperand ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR,
- Tmp1.getValueType(), Tmp2);
-
- unsigned NumElts = MVT::getVectorNumElements(Tmp1.getValueType());
- MVT::ValueType ShufMaskVT = MVT::getIntVectorWithNumElements(NumElts);
- MVT::ValueType ShufMaskEltVT = MVT::getVectorElementType(ShufMaskVT);
-
- // We generate a shuffle of InVec and ScVec, so the shuffle mask should
- // be 0,1,2,3,4,5... with the appropriate element replaced with elt 0 of
- // the RHS.
- SmallVector<SDOperand, 8> ShufOps;
- for (unsigned i = 0; i != NumElts; ++i) {
- if (i != InsertPos->getValue())
- ShufOps.push_back(DAG.getConstant(i, ShufMaskEltVT));
- else
- ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT));
+ // SCALAR_TO_VECTOR requires that the type of the value being inserted
+ // match the element type of the vector being created.
+ if (Tmp2.getValueType() ==
+ MVT::getVectorElementType(Op.getValueType())) {
+ SDOperand ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR,
+ Tmp1.getValueType(), Tmp2);
+
+ unsigned NumElts = MVT::getVectorNumElements(Tmp1.getValueType());
+ MVT::ValueType ShufMaskVT = MVT::getIntVectorWithNumElements(NumElts);
+ MVT::ValueType ShufMaskEltVT = MVT::getVectorElementType(ShufMaskVT);
+
+ // We generate a shuffle of InVec and ScVec, so the shuffle mask
+ // should be 0,1,2,3,4,5... with the appropriate element replaced with
+ // elt 0 of the RHS.
+ SmallVector<SDOperand, 8> ShufOps;
+ for (unsigned i = 0; i != NumElts; ++i) {
+ if (i != InsertPos->getValue())
+ ShufOps.push_back(DAG.getConstant(i, ShufMaskEltVT));
+ else
+ ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT));
+ }
+ SDOperand ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMaskVT,
+ &ShufOps[0], ShufOps.size());
+
+ Result = DAG.getNode(ISD::VECTOR_SHUFFLE, Tmp1.getValueType(),
+ Tmp1, ScVec, ShufMask);
+ Result = LegalizeOp(Result);
+ break;
}
- SDOperand ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMaskVT,
- &ShufOps[0], ShufOps.size());
-
- Result = DAG.getNode(ISD::VECTOR_SHUFFLE, Tmp1.getValueType(),
- Tmp1, ScVec, ShufMask);
- Result = LegalizeOp(Result);
- break;
}
// If the target doesn't support this, we have to spill the input vector
@@ -1316,7 +1329,7 @@
// permute it into place, if the idx is a constant and if the idx is
// supported by the target.
MVT::ValueType VT = Tmp1.getValueType();
- MVT::ValueType EltVT = Tmp2.getValueType();
+ MVT::ValueType EltVT = MVT::getVectorElementType(VT);
MVT::ValueType IdxVT = Tmp3.getValueType();
MVT::ValueType PtrVT = TLI.getPointerTy();
SDOperand StackPtr = DAG.CreateStackTemporary(VT);
@@ -1337,8 +1350,8 @@
Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
// Store the scalar value.
- Ch = DAG.getStore(Ch, Tmp2, StackPtr2,
- PseudoSourceValue::getFixedStack(), SPFI);
+ Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
+ PseudoSourceValue::getFixedStack(), SPFI, EltVT);
// Load the updated vector.
Result = DAG.getLoad(VT, Ch, StackPtr,
PseudoSourceValue::getFixedStack(), SPFI);