diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index aa9da930639a..1d39e54a5b0d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -23937,9 +23937,19 @@ static SDValue PerformTargetShuffleCombine(SDValue N, SelectionDAG &DAG, SDValue Op1 = N.getOperand(1); SDValue Op2 = N.getOperand(2); unsigned InsertPSMask = cast(Op2)->getZExtValue(); - unsigned DstIdx = (InsertPSMask >> 4) & 3; + unsigned DstIdx = (InsertPSMask >> 4) & 0x3; + unsigned ZeroMask = InsertPSMask & 0xF; + + // If we zero out all elements from Op0 then we don't need to reference it. + if (((ZeroMask | (1u << DstIdx)) == 0xF) && !Op0.isUndef()) + return DAG.getNode(X86ISD::INSERTPS, DL, VT, DAG.getUNDEF(VT), Op1, + DAG.getConstant(InsertPSMask, DL, MVT::i8)); + + // If we zero out the element from Op1 then we don't need to reference it. + if ((ZeroMask & (1u << DstIdx)) && !Op1.isUndef()) + return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, DAG.getUNDEF(VT), + DAG.getConstant(InsertPSMask, DL, MVT::i8)); - // Attempt to merge insertps with an inner target shuffle node. SmallVector TargetMask; if (!setTargetShuffleZeroElements(Op0, TargetMask)) return SDValue(); @@ -23979,7 +23989,7 @@ static SDValue PerformTargetShuffleCombine(SDValue N, SelectionDAG &DAG, } if (Updated) - return DAG.getNode(X86ISD::INSERTPS, DL, MVT::v4f32, Op0, Op1, + return DAG.getNode(X86ISD::INSERTPS, DL, VT, Op0, Op1, DAG.getConstant(InsertPSMask, DL, MVT::i8)); return SDValue(); diff --git a/llvm/test/CodeGen/X86/insertps-combine.ll b/llvm/test/CodeGen/X86/insertps-combine.ll index 78bae28762c0..54b5fe444baf 100644 --- a/llvm/test/CodeGen/X86/insertps-combine.ll +++ b/llvm/test/CodeGen/X86/insertps-combine.ll @@ -98,6 +98,38 @@ define <4 x float> @shuffle_v4f32_0z6z(<4 x float> %A, <4 x float> %B) { ret <4 x float> %vecinit4 } +define <4 x float> @insertps_undef_input0(<4 x float> %a0, <4 x float> %a1) { +; SSE-LABEL: insertps_undef_input0: +; SSE: # BB#0: +; SSE-NEXT: insertps {{.*#+}} xmm0 = zero,xmm1[0],zero,zero +; SSE-NEXT: retq +; +; AVX-LABEL: insertps_undef_input0: +; AVX: # BB#0: +; AVX-NEXT: vinsertps {{.*#+}} xmm0 = zero,xmm1[0],zero,zero +; AVX-NEXT: retq + %res0 = fadd <4 x float> %a0, + %res1 = call <4 x float> @llvm.x86.sse41.insertps(<4 x float> %res0, <4 x float> %a1, i8 21) + %res2 = shufflevector <4 x float> %res1, <4 x float> zeroinitializer, <4 x i32> + ret <4 x float> %res2 +} + +define <4 x float> @insertps_undef_input1(<4 x float> %a0, <4 x float> %a1) { +; SSE-LABEL: insertps_undef_input1: +; SSE: # BB#0: +; SSE-NEXT: insertps {{.*#+}} xmm0 = zero,zero,zero,xmm0[3] +; SSE-NEXT: retq +; +; AVX-LABEL: insertps_undef_input1: +; AVX: # BB#0: +; AVX-NEXT: vinsertps {{.*#+}} xmm0 = zero,zero,zero,xmm0[3] +; AVX-NEXT: retq + %res0 = fadd <4 x float> %a1, + %res1 = call <4 x float> @llvm.x86.sse41.insertps(<4 x float> %a0, <4 x float> %res0, i8 21) + %res2 = shufflevector <4 x float> %res1, <4 x float> zeroinitializer, <4 x i32> + ret <4 x float> %res2 +} + define float @extract_zero_insertps_z0z7(<4 x float> %a0, <4 x float> %a1) { ; SSE-LABEL: extract_zero_insertps_z0z7: ; SSE: # BB#0: