diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -4098,12 +4098,25 @@ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fpowi."); if (!TLI.getLibcallName(LC)) { // Some targets don't have a powi libcall; use pow instead. - SDValue Exponent = DAG.getNode(ISD::SINT_TO_FP, SDLoc(Node), - Node->getValueType(0), - Node->getOperand(1)); - Results.push_back(DAG.getNode(ISD::FPOW, SDLoc(Node), - Node->getValueType(0), Node->getOperand(0), - Exponent)); + if (Node->isStrictFPOpcode()) { + SDValue Exponent = + DAG.getNode(ISD::STRICT_SINT_TO_FP, SDLoc(Node), + {Node->getValueType(0), Node->getValueType(1)}, + {Node->getOperand(0), Node->getOperand(2)}); + SDValue FPOW = + DAG.getNode(ISD::STRICT_FPOW, SDLoc(Node), + {Node->getValueType(0), Node->getValueType(1)}, + {Exponent.getValue(1), Node->getOperand(1), Exponent}); + Results.push_back(FPOW); + Results.push_back(FPOW.getValue(1)); + } else { + SDValue Exponent = + DAG.getNode(ISD::SINT_TO_FP, SDLoc(Node), Node->getValueType(0), + Node->getOperand(1)); + Results.push_back(DAG.getNode(ISD::FPOW, SDLoc(Node), + Node->getValueType(0), + Node->getOperand(0), Exponent)); + } break; } unsigned Offset = Node->isStrictFPOpcode() ? 1 : 0; diff --git a/llvm/test/CodeGen/X86/float-strict-powi-convert.ll b/llvm/test/CodeGen/X86/float-strict-powi-convert.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/float-strict-powi-convert.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-pc-windows-msvc %s -o - | FileCheck %s -check-prefix=WIN +; RUN: llc -mtriple=x86_64-pc-linux %s -o -| FileCheck %s -check-prefix=UNIX + +declare float @llvm.experimental.constrained.powi.f32.i32(float, i32, metadata, metadata) + +define float @powi_f64(float %a, i32 %b) nounwind strictfp { +; WIN-LABEL: powi_f64: +; WIN: # %bb.0: +; WIN-NEXT: subq $40, %rsp +; WIN-NEXT: cvtsi2ss %edx, %xmm1 +; WIN-NEXT: callq powf +; WIN-NEXT: addq $40, %rsp +; WIN-NEXT: retq +; +; UNIX-LABEL: powi_f64: +; UNIX: # %bb.0: +; UNIX-NEXT: pushq %rax +; UNIX-NEXT: callq __powisf2@PLT +; UNIX-NEXT: popq %rax +; UNIX-NEXT: retq + %1 = call float @llvm.experimental.constrained.powi.f32.i32(float %a, i32 %b, metadata !"round.tonearest", metadata !"fpexcept.ignore") strictfp + ret float %1 +}