diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 1a6be4eb5af1ef..f011249d295040 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -614,6 +614,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FTAN, VT, Action); setOperationAction(ISD::FSQRT, VT, Action); setOperationAction(ISD::FPOW, VT, Action); + setOperationAction(ISD::FPOWI, VT, Action); setOperationAction(ISD::FLOG, VT, Action); setOperationAction(ISD::FLOG2, VT, Action); setOperationAction(ISD::FLOG10, VT, Action); diff --git a/llvm/test/CodeGen/X86/fp16-libcalls.ll b/llvm/test/CodeGen/X86/fp16-libcalls.ll index 933971212f11de..5c6c3653a27f95 100644 --- a/llvm/test/CodeGen/X86/fp16-libcalls.ll +++ b/llvm/test/CodeGen/X86/fp16-libcalls.ll @@ -926,6 +926,77 @@ define void @test_half_pow(half %a0, half %a1, ptr %p0) nounwind { ret void } +define void @test_half_powi(half %a0, i32 %a1, ptr %p0) nounwind { +; F16C-LABEL: test_half_powi: +; F16C: # %bb.0: +; F16C-NEXT: pushq %rbx +; F16C-NEXT: movq %rsi, %rbx +; F16C-NEXT: vpextrw $0, %xmm0, %eax +; F16C-NEXT: vmovd %eax, %xmm0 +; F16C-NEXT: vcvtph2ps %xmm0, %xmm0 +; F16C-NEXT: callq __powisf2@PLT +; F16C-NEXT: vcvtps2ph $4, %xmm0, %xmm0 +; F16C-NEXT: vmovd %xmm0, %eax +; F16C-NEXT: movw %ax, (%rbx) +; F16C-NEXT: popq %rbx +; F16C-NEXT: retq +; +; FP16-LABEL: test_half_powi: +; FP16: # %bb.0: +; FP16-NEXT: pushq %rbx +; FP16-NEXT: movq %rsi, %rbx +; FP16-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm0 +; FP16-NEXT: callq __powisf2@PLT +; FP16-NEXT: vcvtss2sh %xmm0, %xmm0, %xmm0 +; FP16-NEXT: vmovsh %xmm0, (%rbx) +; FP16-NEXT: popq %rbx +; FP16-NEXT: retq +; +; X64-LABEL: test_half_powi: +; X64: # %bb.0: +; X64-NEXT: pushq %rbp +; X64-NEXT: pushq %rbx +; X64-NEXT: pushq %rax +; X64-NEXT: movq %rsi, %rbx +; X64-NEXT: movl %edi, %ebp +; X64-NEXT: callq __extendhfsf2@PLT +; X64-NEXT: movl %ebp, %edi +; X64-NEXT: callq __powisf2@PLT +; X64-NEXT: callq __truncsfhf2@PLT +; X64-NEXT: pextrw $0, %xmm0, %eax +; X64-NEXT: movw %ax, (%rbx) +; X64-NEXT: addq $8, %rsp +; X64-NEXT: popq %rbx +; X64-NEXT: popq %rbp +; X64-NEXT: retq +; +; X86-LABEL: test_half_powi: +; X86: # %bb.0: +; X86-NEXT: pushl %edi +; X86-NEXT: pushl %esi +; X86-NEXT: subl $20, %esp +; X86-NEXT: pinsrw $0, {{[0-9]+}}(%esp), %xmm0 +; X86-NEXT: movl {{[0-9]+}}(%esp), %esi +; X86-NEXT: movl {{[0-9]+}}(%esp), %edi +; X86-NEXT: pextrw $0, %xmm0, %eax +; X86-NEXT: movw %ax, (%esp) +; X86-NEXT: calll __extendhfsf2 +; X86-NEXT: movl %edi, {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll __powisf2 +; X86-NEXT: fstps (%esp) +; X86-NEXT: calll __truncsfhf2 +; X86-NEXT: pextrw $0, %xmm0, %eax +; X86-NEXT: movw %ax, (%esi) +; X86-NEXT: addl $20, %esp +; X86-NEXT: popl %esi +; X86-NEXT: popl %edi +; X86-NEXT: retl + %res = call half @llvm.powi.half(half %a0, i32 %a1) + store half %res, ptr %p0, align 2 + ret void +} + define void @test_half_rint(half %a0, ptr %p0) nounwind { ; F16C-LABEL: test_half_rint: ; F16C: # %bb.0: