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 @@ -594,7 +594,7 @@ // Half type will be promoted by default. setOperationAction(ISD::FABS, MVT::f16, Promote); setOperationAction(ISD::FNEG, MVT::f16, Promote); - setOperationAction(ISD::FCOPYSIGN, MVT::f16, Promote); + setOperationAction(ISD::FCOPYSIGN, MVT::f16, Expand); setOperationAction(ISD::FADD, MVT::f16, Promote); setOperationAction(ISD::FSUB, MVT::f16, Promote); setOperationAction(ISD::FMUL, MVT::f16, Promote); 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 @@ -1227,6 +1227,41 @@ ret void } +define half @fcopysign(half %x, half %y) { +; CHECK-LIBCALL-LABEL: fcopysign: +; CHECK-LIBCALL: # %bb.0: +; CHECK-LIBCALL-NEXT: pextrw $0, %xmm1, %eax +; CHECK-LIBCALL-NEXT: andl $-32768, %eax # imm = 0x8000 +; CHECK-LIBCALL-NEXT: pextrw $0, %xmm0, %ecx +; CHECK-LIBCALL-NEXT: andl $32767, %ecx # imm = 0x7FFF +; CHECK-LIBCALL-NEXT: orl %eax, %ecx +; CHECK-LIBCALL-NEXT: pinsrw $0, %ecx, %xmm0 +; CHECK-LIBCALL-NEXT: retq +; +; BWON-F16C-LABEL: fcopysign: +; BWON-F16C: # %bb.0: +; BWON-F16C-NEXT: vpextrw $0, %xmm1, %eax +; BWON-F16C-NEXT: andl $-32768, %eax # imm = 0x8000 +; BWON-F16C-NEXT: vpextrw $0, %xmm0, %ecx +; BWON-F16C-NEXT: andl $32767, %ecx # imm = 0x7FFF +; BWON-F16C-NEXT: orl %eax, %ecx +; BWON-F16C-NEXT: vpinsrw $0, %ecx, %xmm0, %xmm0 +; BWON-F16C-NEXT: retq +; +; CHECK-I686-LABEL: fcopysign: +; CHECK-I686: # %bb.0: +; CHECK-I686-NEXT: movl $-32768, %eax # imm = 0x8000 +; CHECK-I686-NEXT: andl {{[0-9]+}}(%esp), %eax +; CHECK-I686-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; CHECK-I686-NEXT: andl $32767, %ecx # imm = 0x7FFF +; CHECK-I686-NEXT: orl %eax, %ecx +; CHECK-I686-NEXT: pinsrw $0, %ecx, %xmm0 +; CHECK-I686-NEXT: retl + %a = call half @llvm.copysign.f16(half %x, half %y) + ret half %a +} + declare half @llvm.fabs.f16(half) +declare half @llvm.copysign.f16(half, half) attributes #0 = { nounwind }