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 @@ -44181,6 +44181,15 @@ N0 = DAG.getBitcast(MVT::i8, N0); return DAG.getNode(ISD::TRUNCATE, dl, VT, N0); } + + // Combine bitcast(extract_vector_elt vXi16, N) to + // extract_vector_elt(bitcast(vXi16), N). + if (VT == MVT::f16 && N0.getOpcode() == ISD::EXTRACT_VECTOR_ELT) { + SDValue N00 = N0.getOperand(0); + EVT NVT = N00.getValueType().changeVectorElementType(MVT::f16); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f16, + DAG.getBitcast(NVT, N00), N0.getOperand(1)); + } } else { // If we're bitcasting from iX to vXi1, see if the integer originally // began as a vXi1 and whether we can remove the bitcast entirely. diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll --- a/llvm/test/CodeGen/X86/half.ll +++ b/llvm/test/CodeGen/X86/half.ll @@ -1361,24 +1361,18 @@ ; CHECK-LIBCALL-LABEL: pr61271: ; CHECK-LIBCALL: # %bb.0: ; CHECK-LIBCALL-NEXT: pminsw %xmm1, %xmm0 -; CHECK-LIBCALL-NEXT: movd %xmm0, %eax -; CHECK-LIBCALL-NEXT: pinsrw $0, %eax, %xmm0 ; CHECK-LIBCALL-NEXT: retq ; ; BWON-F16C-LABEL: pr61271: ; BWON-F16C: # %bb.0: ; BWON-F16C-NEXT: vpminsw %xmm1, %xmm0, %xmm0 -; BWON-F16C-NEXT: vmovd %xmm0, %eax -; BWON-F16C-NEXT: vpinsrw $0, %eax, %xmm0, %xmm0 ; BWON-F16C-NEXT: retq ; ; CHECK-I686-LABEL: pr61271: ; CHECK-I686: # %bb.0: -; CHECK-I686-NEXT: pinsrw $0, {{[0-9]+}}(%esp), %xmm0 ; CHECK-I686-NEXT: pinsrw $0, {{[0-9]+}}(%esp), %xmm1 -; CHECK-I686-NEXT: pminsw %xmm0, %xmm1 -; CHECK-I686-NEXT: movd %xmm1, %eax -; CHECK-I686-NEXT: pinsrw $0, %eax, %xmm0 +; CHECK-I686-NEXT: pinsrw $0, {{[0-9]+}}(%esp), %xmm0 +; CHECK-I686-NEXT: pminsw %xmm1, %xmm0 ; CHECK-I686-NEXT: retl %3 = call fast half @llvm.minnum.f16(half %0, half %1) ret half %3