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

Kane Wang via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 00:19:29 PDT 2026


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

>From 65869dc262d937a237467d173fd0321a4fc1d577 Mon Sep 17 00:00:00 2001
From: Kane Wang <wangqiang1 at kylinos.cn>
Date: Tue, 29 Sep 2026 16:34:12 +0800
Subject: [PATCH] [RISCV] Use Zfhmin for G_FPEXT from f16 to f32

fcvt.s.h is available with Zfhmin. Use the __extendhfsf2 libcall without
it.
---
 .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp |  3 +-
 .../CodeGen/RISCV/GlobalISel/half-convert.ll  | 82 +++++++++++++++++++
 2 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index ff62ee25236f21..9566310bd9693a 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 3338be0aad09d2..36e840df39f232 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
+}



More information about the llvm-commits mailing list