diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 62852b17685..48f3bbfac90 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3022,6 +3022,24 @@ static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) { return GeneratePerfectShuffle(PFEntry, V1, V2, DAG, dl); } + // v2f64 and v2i64 shuffles are just register copies. + if (VT == MVT::v2f64 || VT == MVT::v2i64) { + // Do the expansion as f64 since i64 is not legal. + V1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, V1); + V2 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v2f64, V2); + SDValue Val = DAG.getUNDEF(MVT::v2f64); + for (unsigned i = 0; i < 2; ++i) { + if (ShuffleMask[i] < 0) + continue; + SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, + ShuffleMask[i] < 2 ? V1 : V2, + DAG.getConstant(ShuffleMask[i] & 1, MVT::i32)); + Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Val, + Elt, DAG.getConstant(i, MVT::i32)); + } + return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Val); + } + return SDValue(); } diff --git a/test/CodeGen/ARM/2010-05-19-Shuffles.ll b/test/CodeGen/ARM/2010-05-19-Shuffles.ll index 588937e2f8e..587c0afcb71 100644 --- a/test/CodeGen/ARM/2010-05-19-Shuffles.ll +++ b/test/CodeGen/ARM/2010-05-19-Shuffles.ll @@ -12,3 +12,10 @@ define <8 x i8> @f2(<8 x i8> %x) nounwind { <8 x i32> ret <8 x i8> %y } + +define void @f3(<4 x i64>* %xp) nounwind { + %x = load <4 x i64>* %xp + %y = shufflevector <4 x i64> %x, <4 x i64> undef, <4 x i32> + store <4 x i64> %y, <4 x i64>* %xp + ret void +}