From 0d7105ce3ca88a5939fecc6805bcf2cf994ab099 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Nov 2024 14:32:40 -0800 Subject: [PATCH 1/3] [RISCV][GISel] Support f32/f64 powi. Need to force libcall legalization to treat the integer argument as signed so that it can be promoted to XLen in call lowering for RV64. Alternatively we could promote the operand before converting to libcall, but going through call lowering is closer to what SelectionDAG does. --- .../CodeGen/GlobalISel/LegalizerHelper.cpp | 3 +- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 2 + .../RISCV/GlobalISel/float-intrinsics.ll | 42 +++++++++++++++++++ .../GlobalISel/legalizer-info-validation.mir | 4 +- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 709eb2525a657..dd424afd0a909 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -1290,9 +1290,10 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) { return UnableToLegalize; } auto Libcall = getRTLibDesc(MI.getOpcode(), Size); - std::initializer_list Args = { + SmallVector Args = { {MI.getOperand(1).getReg(), HLTy, 0}, {MI.getOperand(2).getReg(), ITy, 1}}; + Args[1].Flags[0].setSExt(); LegalizeResult Status = createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), HLTy, 0}, Args, LocObserver, &MI); diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index a4e03be98c696..005d88a173123 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -579,6 +579,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH, G_FTANH}) .libcallFor({s32, s64}); + getActionDefinitionsBuilder(G_FPOWI) + .libcallFor({{s32, s32}}); getActionDefinitionsBuilder(G_VASTART).customFor({p0}); diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-intrinsics.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-intrinsics.ll index 16b0a2fc2f396..7098493b2b56d 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/float-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-intrinsics.ll @@ -48,6 +48,48 @@ define float @sqrt_f32(float %a) nounwind { ret float %1 } +define float @powi_f32(float %a, i32 %b) nounwind { +; RV32IF-LABEL: powi_f32: +; RV32IF: # %bb.0: +; RV32IF-NEXT: addi sp, sp, -16 +; RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IF-NEXT: call __powisf2 +; RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IF-NEXT: addi sp, sp, 16 +; RV32IF-NEXT: ret +; +; RV64IF-LABEL: powi_f32: +; RV64IF: # %bb.0: +; RV64IF-NEXT: addi sp, sp, -16 +; RV64IF-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64IF-NEXT: sext.w a0, a0 +; RV64IF-NEXT: call __powisf2 +; RV64IF-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64IF-NEXT: addi sp, sp, 16 +; RV64IF-NEXT: ret +; +; RV32I-LABEL: powi_f32: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: call __powisf2 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: powi_f32: +; 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 +; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = call float @llvm.powi.f32.i32(float %a, i32 %b) + ret float %1 +} + define float @sin_f32(float %a) nounwind { ; RV32IF-LABEL: sin_f32: ; RV32IF: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir index 719ea38cbb9c5..f14c806607c71 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir @@ -481,8 +481,8 @@ # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FPOWI (opcode {{[0-9]+}}): 2 type indices, 0 imm indices -# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined -# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. the first uncovered type index: 2, OK +# DEBUG-NEXT: .. the first uncovered imm index: 0, OK # DEBUG-NEXT: G_FEXP (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK From 7b62f0018bf659222562530add567e4d7291dbec Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Nov 2024 15:07:48 -0800 Subject: [PATCH 2/3] fixup! clang-format --- llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 005d88a173123..0f1cb8be159b4 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -579,8 +579,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH, G_FTANH}) .libcallFor({s32, s64}); - getActionDefinitionsBuilder(G_FPOWI) - .libcallFor({{s32, s32}}); + getActionDefinitionsBuilder(G_FPOWI).libcallFor({{s32, s32}}); getActionDefinitionsBuilder(G_VASTART).customFor({p0}); From 247ecd6ec315bdbe8c029bec8621b0ddacf5928a Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Nov 2024 15:18:57 -0800 Subject: [PATCH 3/3] fixup! Add f64 support --- .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 2 +- .../RISCV/GlobalISel/double-intrinsics.ll | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp index 0f1cb8be159b4..8de9e3be8d36e 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp @@ -579,7 +579,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) G_FASIN, G_FATAN, G_FATAN2, G_FCOSH, G_FSINH, G_FTANH}) .libcallFor({s32, s64}); - getActionDefinitionsBuilder(G_FPOWI).libcallFor({{s32, s32}}); + getActionDefinitionsBuilder(G_FPOWI).libcallFor({{s32, s32}, {s64, s32}}); getActionDefinitionsBuilder(G_VASTART).customFor({p0}); diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-intrinsics.ll index 79814fd482069..2d00a10dc56b4 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/double-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-intrinsics.ll @@ -39,6 +39,48 @@ define double @sqrt_f64(double %a) nounwind { ret double %1 } +define double @powi_f64(double %a, i32 %b) nounwind { +; RV32IFD-LABEL: powi_f64: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IFD-NEXT: call __powidf2 +; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret +; +; RV64IFD-LABEL: powi_f64: +; RV64IFD: # %bb.0: +; RV64IFD-NEXT: addi sp, sp, -16 +; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64IFD-NEXT: sext.w a0, a0 +; RV64IFD-NEXT: call __powidf2 +; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64IFD-NEXT: addi sp, sp, 16 +; RV64IFD-NEXT: ret +; +; RV32I-LABEL: powi_f64: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: call __powidf2 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: powi_f64: +; 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 __powidf2 +; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = call double @llvm.powi.f64.i32(double %a, i32 %b) + ret double %1 +} + declare double @llvm.sin.f64(double) define double @sin_f64(double %a) nounwind { @@ -1001,11 +1043,11 @@ define i1 @isnan_d_fpclass(double %x) { ; RV32I-NEXT: addi a3, a2, -1 ; RV32I-NEXT: lui a2, 524032 ; RV32I-NEXT: and a1, a1, a3 -; RV32I-NEXT: beq a1, a2, .LBB24_2 +; RV32I-NEXT: beq a1, a2, .LBB25_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: sltu a0, a2, a1 ; RV32I-NEXT: ret -; RV32I-NEXT: .LBB24_2: +; RV32I-NEXT: .LBB25_2: ; RV32I-NEXT: snez a0, a0 ; RV32I-NEXT: ret ;