diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -16966,6 +16966,15 @@ } assert(VT.is128BitVector() && "Only 128-bit vector types should be left!"); + // This will be just movd/movq/movss/movsd + if (IdxVal == 0 && ISD::isBuildVectorAllZeros(N0.getNode())) { + if (EltVT == MVT::i32 || EltVT == MVT::f32 || EltVT == MVT::f64 || + (EltVT == MVT::i64 && Subtarget.is64Bit())) { + N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, N1); + return getShuffleVectorZeroOrUndef(N1, 0, true, Subtarget, DAG); + } + } + // Transform it so it match pinsr{b,w} which expects a GR32 as its second // argument. SSE41 required for pinsrb. if (VT == MVT::v8i16 || (VT == MVT::v16i8 && Subtarget.hasSSE41())) { diff --git a/llvm/test/CodeGen/X86/vec_insert_first.ll b/llvm/test/CodeGen/X86/vec_insert_first.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/vec_insert_first.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i386-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=X32 +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=X64 +define <2 x i64> @pinsr(i32 %x, i32 %y) { +; X32-LABEL: pinsr: +; X32: # %bb.0: +; X32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X32-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero +; X32-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; X32-NEXT: retl +; +; X64-LABEL: pinsr: +; X64: # %bb.0: +; X64-NEXT: movd %edi, %xmm0 +; X64-NEXT: movd %esi, %xmm1 +; X64-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] +; X64-NEXT: retq + %ins1 = insertelement <4 x i32> , i32 %x, i32 0 + %ins2 = insertelement <4 x i32> , i32 %y, i32 0 + %b1 = bitcast <4 x i32> %ins1 to <2 x i64> + %b2 = bitcast <4 x i32> %ins2 to <2 x i64> + %r = shufflevector <2 x i64> %b1, <2 x i64> %b2, <2 x i32> + ret <2 x i64> %r +}