diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -818,6 +818,10 @@ setTargetDAGCombine(ISD::MGATHER); setTargetDAGCombine(ISD::MSCATTER); } + if (Subtarget.is64Bit()) { + setTargetDAGCombine(ISD::FPOWI); + setTargetDAGCombine(ISD::STRICT_FPOWI); + } } EVT RISCVTargetLowering::getSetCCResultType(const DataLayout &DL, @@ -5919,6 +5923,23 @@ Index, MGSN->getScale()}, MGSN->getMemOperand(), NewIndexTy, MSN->isTruncatingStore()); } + case ISD::FPOWI: + case ISD::STRICT_FPOWI: { + if (!DCI.isBeforeLegalize()) + break; + // FIXME: It should be possible to lower these to RTLIB::POWI libcalls. Now + // we instead rewrite into using FPOW in case the type of the exponent isn't + // legal (to avoid that TypeLegalization promotes the exponent in FPOWI to + // i64, as FPOWI has undefined result if the exponent is larger than i32). + if (Subtarget.is64Bit()) { + SDValue Exponent = DAG.getNode(ISD::SINT_TO_FP, SDLoc(N), + N->getValueType(0), + N->getOperand(1)); + return DAG.getNode(ISD::FPOW, SDLoc(N), + N->getValueType(0), N->getOperand(0), Exponent); + } + break; + } } return SDValue(); diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/double-intrinsics.ll --- a/llvm/test/CodeGen/RISCV/double-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/double-intrinsics.ll @@ -46,8 +46,9 @@ ; RV64IFD: # %bb.0: ; RV64IFD-NEXT: addi sp, sp, -16 ; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; RV64IFD-NEXT: sext.w a1, a1 -; RV64IFD-NEXT: call __powidf2@plt +; RV64IFD-NEXT: fcvt.d.w ft0, a1 +; RV64IFD-NEXT: fmv.x.d a1, ft0 +; RV64IFD-NEXT: call pow@plt ; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64IFD-NEXT: addi sp, sp, 16 ; RV64IFD-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/float-intrinsics.ll b/llvm/test/CodeGen/RISCV/float-intrinsics.ll --- a/llvm/test/CodeGen/RISCV/float-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/float-intrinsics.ll @@ -44,8 +44,9 @@ ; RV64IF: # %bb.0: ; RV64IF-NEXT: addi sp, sp, -16 ; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; RV64IF-NEXT: sext.w a1, a1 -; RV64IF-NEXT: call __powisf2@plt +; RV64IF-NEXT: fcvt.s.w ft0, a1 +; RV64IF-NEXT: fmv.x.w a1, ft0 +; RV64IF-NEXT: call powf@plt ; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64IF-NEXT: addi sp, sp, 16 ; RV64IF-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll b/llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll --- a/llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll +++ b/llvm/test/CodeGen/RISCV/rv64i-single-softfloat.ll @@ -670,8 +670,14 @@ ; RV64I: # %bb.0: ; RV64I-NEXT: addi sp, sp, -16 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill -; RV64I-NEXT: sext.w a1, a1 -; RV64I-NEXT: call __powisf2@plt +; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64I-NEXT: mv s0, a0 +; RV64I-NEXT: sext.w a0, a1 +; RV64I-NEXT: call __floatsisf@plt +; RV64I-NEXT: mv a1, a0 +; RV64I-NEXT: mv a0, s0 +; RV64I-NEXT: call powf@plt +; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 16 ; RV64I-NEXT: ret