[llvm] [RISCV] Use Zfhmin for G_FPEXT from f16 to f32 (PR #227225)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 02:01:59 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-globalisel

Author: Kane Wang (ReVe1uv)

<details>
<summary>Changes</summary>

fcvt.s.h is available with Zfhmin. Use the __extendhfsf2 libcall without it.

---
Full diff: https://github.com/llvm/llvm-project/pull/227225.diff


2 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+2-1) 
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/half-convert.ll (+82) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index ff62ee25236f2..9566310bd9693 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -605,8 +605,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
       .libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
   getActionDefinitionsBuilder(G_FPEXT)
       .legalFor(ST.hasStdExtD(), {{s64, s32}})
-      .legalFor(ST.hasStdExtZfh(), {{s32, s16}})
+      .legalFor(ST.hasStdExtZfhmin(), {{s32, s16}})
       .legalFor(ST.hasStdExtZfh() && ST.hasStdExtD(), {{s64, s16}})
+      .libcallFor(!ST.hasStdExtZfhmin(), {{s32, s16}})
       .libcallFor({{s64, s32}})
       .libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
 
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/half-convert.ll b/llvm/test/CodeGen/RISCV/GlobalISel/half-convert.ll
index 3338be0aad09d..36e840df39f23 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/half-convert.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/half-convert.ll
@@ -3,6 +3,10 @@
 ; RUN:   -target-abi=ilp32d < %s | FileCheck %s --check-prefixes=RV32
 ; RUN: llc -mtriple=riscv64 -global-isel -mattr=+f,+d,+zfh \
 ; RUN:   -target-abi=lp64d < %s | FileCheck %s --check-prefixes=RV64
+; RUN: llc -mtriple=riscv32 -global-isel -mattr=+f,+d,+zfhmin \
+; RUN:   -target-abi=ilp32d < %s | FileCheck %s --check-prefixes=RV32ZFHMIN
+; RUN: llc -mtriple=riscv64 -global-isel -mattr=+f,+d,+zfhmin \
+; RUN:   -target-abi=lp64d < %s | FileCheck %s --check-prefixes=RV64ZFHMIN
 ; RUN: llc -mtriple=riscv32 -global-isel -mattr=+f,+d \
 ; RUN:   -target-abi=ilp32d < %s | FileCheck %s --check-prefixes=RV32NOZFH
 ; RUN: llc -mtriple=riscv64 -global-isel -mattr=+f,+d \
@@ -20,6 +24,24 @@ define i64 @fptoui_i64_f16(half %x) nounwind {
 ; RV64-NEXT:    fcvt.lu.h a0, fa0, rtz
 ; RV64-NEXT:    ret
 ;
+; RV32ZFHMIN-LABEL: fptoui_i64_f16:
+; RV32ZFHMIN:       # %bb.0:
+; RV32ZFHMIN-NEXT:    addi sp, sp, -16
+; RV32ZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32ZFHMIN-NEXT:    call __fixunshfdi
+; RV32ZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32ZFHMIN-NEXT:    addi sp, sp, 16
+; RV32ZFHMIN-NEXT:    ret
+;
+; RV64ZFHMIN-LABEL: fptoui_i64_f16:
+; RV64ZFHMIN:       # %bb.0:
+; RV64ZFHMIN-NEXT:    addi sp, sp, -16
+; RV64ZFHMIN-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64ZFHMIN-NEXT:    call __fixunshfdi
+; RV64ZFHMIN-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64ZFHMIN-NEXT:    addi sp, sp, 16
+; RV64ZFHMIN-NEXT:    ret
+;
 ; RV32NOZFH-LABEL: fptoui_i64_f16:
 ; RV32NOZFH:       # %bb.0:
 ; RV32NOZFH-NEXT:    addi sp, sp, -16
@@ -53,6 +75,24 @@ define i64 @fptosi_i64_f16(half %x) nounwind {
 ; RV64-NEXT:    fcvt.l.h a0, fa0, rtz
 ; RV64-NEXT:    ret
 ;
+; RV32ZFHMIN-LABEL: fptosi_i64_f16:
+; RV32ZFHMIN:       # %bb.0:
+; RV32ZFHMIN-NEXT:    addi sp, sp, -16
+; RV32ZFHMIN-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32ZFHMIN-NEXT:    call __fixhfdi
+; RV32ZFHMIN-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32ZFHMIN-NEXT:    addi sp, sp, 16
+; RV32ZFHMIN-NEXT:    ret
+;
+; RV64ZFHMIN-LABEL: fptosi_i64_f16:
+; RV64ZFHMIN:       # %bb.0:
+; RV64ZFHMIN-NEXT:    addi sp, sp, -16
+; RV64ZFHMIN-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64ZFHMIN-NEXT:    call __fixhfdi
+; RV64ZFHMIN-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64ZFHMIN-NEXT:    addi sp, sp, 16
+; RV64ZFHMIN-NEXT:    ret
+;
 ; RV32NOZFH-LABEL: fptosi_i64_f16:
 ; RV32NOZFH:       # %bb.0:
 ; RV32NOZFH-NEXT:    addi sp, sp, -16
@@ -73,3 +113,45 @@ define i64 @fptosi_i64_f16(half %x) nounwind {
   %a = fptosi half %x to i64
   ret i64 %a
 }
+
+define float @fpext_f16_to_f32(half %x) nounwind {
+; RV32-LABEL: fpext_f16_to_f32:
+; RV32:       # %bb.0:
+; RV32-NEXT:    fcvt.s.h fa0, fa0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: fpext_f16_to_f32:
+; RV64:       # %bb.0:
+; RV64-NEXT:    fcvt.s.h fa0, fa0
+; RV64-NEXT:    ret
+;
+; RV32ZFHMIN-LABEL: fpext_f16_to_f32:
+; RV32ZFHMIN:       # %bb.0:
+; RV32ZFHMIN-NEXT:    fcvt.s.h fa0, fa0
+; RV32ZFHMIN-NEXT:    ret
+;
+; RV64ZFHMIN-LABEL: fpext_f16_to_f32:
+; RV64ZFHMIN:       # %bb.0:
+; RV64ZFHMIN-NEXT:    fcvt.s.h fa0, fa0
+; RV64ZFHMIN-NEXT:    ret
+;
+; RV32NOZFH-LABEL: fpext_f16_to_f32:
+; RV32NOZFH:       # %bb.0:
+; RV32NOZFH-NEXT:    addi sp, sp, -16
+; RV32NOZFH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32NOZFH-NEXT:    call __extendhfsf2
+; RV32NOZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32NOZFH-NEXT:    addi sp, sp, 16
+; RV32NOZFH-NEXT:    ret
+;
+; RV64NOZFH-LABEL: fpext_f16_to_f32:
+; RV64NOZFH:       # %bb.0:
+; RV64NOZFH-NEXT:    addi sp, sp, -16
+; RV64NOZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64NOZFH-NEXT:    call __extendhfsf2
+; RV64NOZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64NOZFH-NEXT:    addi sp, sp, 16
+; RV64NOZFH-NEXT:    ret
+  %a = fpext half %x to float
+  ret float %a
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/227225


More information about the llvm-commits mailing list