diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 3ff4da4a28a..f500adfa25e 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -280,7 +280,28 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL, } // Vector/Vector bitcast. - return DAG.getNode(ISD::BITCAST, DL, ValueVT, Val); + if (ValueVT.getSizeInBits() == PartVT.getSizeInBits()) + return DAG.getNode(ISD::BITCAST, DL, ValueVT, Val); + + assert(PartVT.getVectorNumElements() == ValueVT.getVectorNumElements() && + "Cannot handle this kind of promotion"); + // Promoted vector extract + unsigned NumElts = ValueVT.getVectorNumElements(); + SmallVector NewOps; + for (unsigned i = 0; i < NumElts; ++i) { + SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, + PartVT.getScalarType(), Val ,DAG.getIntPtrConstant(i)); + SDValue Cast; + + bool Smaller = ValueVT.bitsLE(PartVT); + + Cast = DAG.getNode((Smaller ? ISD::TRUNCATE : ISD::ANY_EXTEND), + DL, ValueVT.getScalarType(), Ext); + + NewOps.push_back(Cast); + } + return DAG.getNode(ISD::BUILD_VECTOR, DL, ValueVT, + &NewOps[0], NewOps.size()); } // Trivial bitcast if the types are the same size and the destination @@ -452,7 +473,24 @@ static void getCopyToPartsVector(SelectionDAG &DAG, DebugLoc DL, //SDValue UndefElts = DAG.getUNDEF(VectorTy); //Val = DAG.getNode(ISD::CONCAT_VECTORS, DL, PartVT, Val, UndefElts); - } else { + } else if (PartVT.isVector() && + PartVT.getVectorElementType().bitsGE( + ValueVT.getVectorElementType())&& + PartVT.getVectorNumElements() == ValueVT.getVectorNumElements()) { + + // Promoted vector extract + unsigned NumElts = ValueVT.getVectorNumElements(); + SmallVector NewOps; + for (unsigned i = 0; i < NumElts; ++i) { + SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, + ValueVT.getScalarType(), Val ,DAG.getIntPtrConstant(i)); + SDValue Cast = DAG.getNode(ISD::ANY_EXTEND, + DL, PartVT.getScalarType(), Ext); + NewOps.push_back(Cast); + } + Val = DAG.getNode(ISD::BUILD_VECTOR, DL, PartVT, + &NewOps[0], NewOps.size()); + } else{ // Vector -> scalar conversion. assert(ValueVT.getVectorElementType() == PartVT && ValueVT.getVectorNumElements() == 1 && diff --git a/test/CodeGen/Generic/basic-promote-integers.ll b/test/CodeGen/Generic/basic-promote-integers.ll new file mode 100644 index 00000000000..13402bfd58f --- /dev/null +++ b/test/CodeGen/Generic/basic-promote-integers.ll @@ -0,0 +1,20 @@ +; Test that vectors are scalarized/lowered correctly +; (with both legalization methods). +; RUN: llc -march=x86 -promote-elements < %s +; RUN: llc -march=x86 < %s + +; A simple test to check copyToParts and copyFromParts + +define <4 x i64> @test_param_0(<4 x i64> %A, <2 x i32> %B, <4 x i8> %C) { + ret <4 x i64> %A +} + +define <2 x i32> @test_param_1(<4 x i64> %A, <2 x i32> %B, <4 x i8> %C) { + ret <2 x i32> %B +} + +define <4 x i8> @test_param_2(<4 x i64> %A, <2 x i32> %B, <4 x i8> %C) { + ret <4 x i8> %C +} + +