diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0179cf181cf..3cbd6d046bc 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9836,8 +9836,35 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) { return N->getOperand(0); // Check if all of the operands are undefs. + EVT VT = N->getValueType(0); if (ISD::allOperandsUndef(N)) - return DAG.getUNDEF(N->getValueType(0)); + return DAG.getUNDEF(VT); + + // Optimize concat_vectors where one of the vectors is undef. + if (N->getNumOperands() == 2 && + N->getOperand(1)->getOpcode() == ISD::UNDEF) { + SDValue In = N->getOperand(0); + assert(In->getValueType(0).isVector() && "Must concat vectors"); + + // Transform: concat_vectors(scalar, undef) -> scalar_to_vector(sclr). + if (In->getOpcode() == ISD::BITCAST && + !In->getOperand(0)->getValueType(0).isVector()) { + SDValue Scalar = In->getOperand(0); + EVT SclTy = Scalar->getValueType(0); + + if (!SclTy.isFloatingPoint() && !SclTy.isInteger()) + return SDValue(); + + EVT NVT = EVT::getVectorVT(*DAG.getContext(), SclTy, + VT.getSizeInBits() / SclTy.getSizeInBits()); + if (!TLI.isTypeLegal(NVT) || !TLI.isTypeLegal(Scalar.getValueType())) + return SDValue(); + + SDLoc dl = SDLoc(N); + SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NVT, Scalar); + return DAG.getNode(ISD::BITCAST, dl, VT, Res); + } + } // Type legalization of vectors and DAG canonicalization of SHUFFLE_VECTOR // nodes often generate nop CONCAT_VECTOR nodes. diff --git a/lib/Target/AArch64/AArch64InstrNEON.td b/lib/Target/AArch64/AArch64InstrNEON.td index 9efbb0d34fe..10dde19318e 100644 --- a/lib/Target/AArch64/AArch64InstrNEON.td +++ b/lib/Target/AArch64/AArch64InstrNEON.td @@ -5130,6 +5130,10 @@ def : Pat<(v1f64 (scalar_to_vector (f64 FPR64:$Rn))), def : Pat<(v1f64 (scalar_to_vector (f64 FPR64:$src))), (FMOVdd $src)>; +def : Pat<(v2f64 (scalar_to_vector (f64 FPR64:$src))), + (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), + (f64 FPR64:$src), sub_64)>; + class NeonI_DUP_Elt @@ -5300,4 +5304,4 @@ def : Pat<(v1i64 (extract_subvector (v2i64 VPR128:$Rn), (i64 0))), def : Pat<(v2f32 (extract_subvector (v4f32 VPR128:$Rn), (i64 0))), (v2f32 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; def : Pat<(v1f64 (extract_subvector (v2f64 VPR128:$Rn), (i64 0))), - (v1f64 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; \ No newline at end of file + (v1f64 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 31ff797960e..0d7818943c8 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1500,7 +1500,6 @@ void X86TargetLowering::resetOperationActions() { } // We have target-specific dag combine patterns for the following nodes: - setTargetDAGCombine(ISD::CONCAT_VECTORS); setTargetDAGCombine(ISD::VECTOR_SHUFFLE); setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); setTargetDAGCombine(ISD::VSELECT); @@ -16155,50 +16154,6 @@ static SDValue PerformShuffleCombine256(SDNode *N, SelectionDAG &DAG, return SDValue(); } -static SDValue PerformConcatCombine(SDNode *N, SelectionDAG &DAG, - TargetLowering::DAGCombinerInfo &DCI, - const X86Subtarget *Subtarget) { - // Creating a v8i16 from a v4i16 argument and an undef runs into trouble in - // type legalization and ends up spilling to the stack. Avoid that by - // creating a vector first and bitcasting the result rather than - // bitcasting the source then creating the vector. Similar problems with - // v8i8. - - // No point in doing this after legalize, so early exit for that. - if (!DCI.isBeforeLegalize()) - return SDValue(); - - EVT VT = N->getValueType(0); - SDValue Op0 = N->getOperand(0); - SDValue Op1 = N->getOperand(1); - const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - if (VT.getSizeInBits() == 128 && N->getNumOperands() == 2 && - Op1->getOpcode() == ISD::UNDEF && - Op0->getOpcode() == ISD::BITCAST && - !TLI.isTypeLegal(Op0->getValueType(0)) && - TLI.isTypeLegal(Op0->getOperand(0)->getValueType(0))) { - if (Op0->getOperand(0)->getValueType(0).isVector()) - return SDValue(); - SDValue Scalar = Op0->getOperand(0); - // Any legal type here will be a simple value type. - MVT SVT = Scalar->getValueType(0).getSimpleVT(); - // As a special case, bail out on MMX values. - if (SVT == MVT::x86mmx) - return SDValue(); - EVT NVT = MVT::getVectorVT(SVT, 2); - // If the result vector type isn't legal, this transform won't really - // help, so bail on that, too. - if (!TLI.isTypeLegal(NVT)) - return SDValue(); - SDLoc dl = SDLoc(N); - SDValue Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NVT, Scalar); - Res = DAG.getNode(ISD::BITCAST, dl, VT, Res); - return Res; - } - - return SDValue(); -} - /// PerformShuffleCombine - Performs several different shuffle combines. static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, @@ -19077,7 +19032,6 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, case X86ISD::VPERMILP: case X86ISD::VPERM2X128: case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, DCI,Subtarget); - case ISD::CONCAT_VECTORS: return PerformConcatCombine(N, DAG, DCI, Subtarget); case ISD::FMA: return PerformFMACombine(N, DAG, Subtarget); }