[llvm] RISC-V: Add fminimumnum and fmaximumnum support (PR #104411)

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 15 19:17:58 PDT 2024


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/104411

>From 0034be3ad9a54f1d62f745c040fcd840365c1132 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Thu, 15 Aug 2024 15:30:38 +0800
Subject: [PATCH 1/3] RISC-V: Add fminimumnum and fmaximumnum support

Since 2.2, `fmin.s/fmax.s` instructions follow the IEEE754-2019, if
F extension is avaiable; and `fmin.d/fmax.d` also follow the
IEEE754-2019 if D extension is avaiable.

So, let's mark them as Legal.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  46 ++-
 llvm/lib/Target/RISCV/RISCVInstrInfoD.td      |   2 +
 llvm/lib/Target/RISCV/RISCVInstrInfoF.td      |   2 +
 .../CodeGen/RISCV/fp-maximumnum-minimumnum.ll | 383 ++++++++++++++++++
 4 files changed, 415 insertions(+), 18 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 911fa45d7173e8..4dc140487c81ce 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -365,12 +365,13 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::SELECT, XLenVT, Custom);
 
   static const unsigned FPLegalNodeTypes[] = {
-      ISD::FMINNUM,        ISD::FMAXNUM,       ISD::LRINT,
-      ISD::LLRINT,         ISD::LROUND,        ISD::LLROUND,
-      ISD::STRICT_LRINT,   ISD::STRICT_LLRINT, ISD::STRICT_LROUND,
-      ISD::STRICT_LLROUND, ISD::STRICT_FMA,    ISD::STRICT_FADD,
-      ISD::STRICT_FSUB,    ISD::STRICT_FMUL,   ISD::STRICT_FDIV,
-      ISD::STRICT_FSQRT,   ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS};
+      ISD::FMINNUM,       ISD::FMAXNUM,       ISD::FMINIMUMNUM,
+      ISD::FMAXIMUMNUM,   ISD::LRINT,         ISD::LLRINT,
+      ISD::LROUND,        ISD::LLROUND,       ISD::STRICT_LRINT,
+      ISD::STRICT_LLRINT, ISD::STRICT_LROUND, ISD::STRICT_LLROUND,
+      ISD::STRICT_FMA,    ISD::STRICT_FADD,   ISD::STRICT_FSUB,
+      ISD::STRICT_FMUL,   ISD::STRICT_FDIV,   ISD::STRICT_FSQRT,
+      ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS};
 
   static const ISD::CondCode FPCCToExpand[] = {
       ISD::SETOGT, ISD::SETOGE, ISD::SETONE, ISD::SETUEQ, ISD::SETUGT,
@@ -389,15 +390,20 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::BITCAST, MVT::i16, Custom);
 
   static const unsigned ZfhminZfbfminPromoteOps[] = {
-      ISD::FMINNUM,      ISD::FMAXNUM,       ISD::FADD,
-      ISD::FSUB,         ISD::FMUL,          ISD::FMA,
-      ISD::FDIV,         ISD::FSQRT,         ISD::FABS,
-      ISD::FNEG,         ISD::STRICT_FMA,    ISD::STRICT_FADD,
-      ISD::STRICT_FSUB,  ISD::STRICT_FMUL,   ISD::STRICT_FDIV,
-      ISD::STRICT_FSQRT, ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS,
-      ISD::SETCC,        ISD::FCEIL,         ISD::FFLOOR,
-      ISD::FTRUNC,       ISD::FRINT,         ISD::FROUND,
-      ISD::FROUNDEVEN,   ISD::SELECT};
+      ISD::FMINNUM,       ISD::FMAXNUM,
+      ISD::FMAXIMUMNUM,   ISD::FMINIMUMNUM,
+      ISD::FADD,          ISD::FSUB,
+      ISD::FMUL,          ISD::FMA,
+      ISD::FDIV,          ISD::FSQRT,
+      ISD::FABS,          ISD::FNEG,
+      ISD::STRICT_FMA,    ISD::STRICT_FADD,
+      ISD::STRICT_FSUB,   ISD::STRICT_FMUL,
+      ISD::STRICT_FDIV,   ISD::STRICT_FSQRT,
+      ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS,
+      ISD::SETCC,         ISD::FCEIL,
+      ISD::FFLOOR,        ISD::FTRUNC,
+      ISD::FRINT,         ISD::FROUND,
+      ISD::FROUNDEVEN,    ISD::SELECT};
 
   if (Subtarget.hasStdExtZfbfmin()) {
     setOperationAction(ISD::BITCAST, MVT::i16, Custom);
@@ -1303,7 +1309,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
         setOperationAction({ISD::FADD, ISD::FSUB, ISD::FMUL, ISD::FDIV,
                             ISD::FNEG, ISD::FABS, ISD::FCOPYSIGN, ISD::FSQRT,
                             ISD::FMA, ISD::FMINNUM, ISD::FMAXNUM,
-                            ISD::IS_FPCLASS, ISD::FMAXIMUM, ISD::FMINIMUM},
+                            ISD::IS_FPCLASS, ISD::FMAXIMUM, ISD::FMINIMUM,
+                            ISD::FMINIMUMNUM, ISD::FMAXIMUMNUM},
                            VT, Custom);
 
         setOperationAction({ISD::FTRUNC, ISD::FCEIL, ISD::FFLOOR, ISD::FROUND,
@@ -1394,7 +1401,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
   setTargetDAGCombine(ISD::SRA);
 
   if (Subtarget.hasStdExtFOrZfinx())
-    setTargetDAGCombine({ISD::FADD, ISD::FMAXNUM, ISD::FMINNUM, ISD::FMUL});
+    setTargetDAGCombine({ISD::FADD, ISD::FMAXNUM, ISD::FMINNUM,
+                         ISD::FMAXIMUMNUM, ISD::FMINIMUMNUM, ISD::FMUL});
 
   if (Subtarget.hasStdExtZbb())
     setTargetDAGCombine({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN});
@@ -16468,7 +16476,9 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
   case ISD::SMAX:
   case ISD::SMIN:
   case ISD::FMAXNUM:
-  case ISD::FMINNUM: {
+  case ISD::FMINNUM:
+  case ISD::FMAXIMUMNUM:
+  case ISD::FMINIMUMNUM: {
     if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
       return V;
     if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
index 35ab277fa35057..57c18791cc43b2 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td
@@ -392,6 +392,8 @@ def : Pat<(fneg (any_fma_nsz FPR64IN32X:$rs1, FPR64IN32X:$rs2, FPR64IN32X:$rs3))
 foreach Ext = DExts in {
   defm : PatFprFpr_m<fminnum, FMIN_D, Ext>;
   defm : PatFprFpr_m<fmaxnum, FMAX_D, Ext>;
+  defm : PatFprFpr_m<fminimumnum, FMIN_D, Ext>;
+  defm : PatFprFpr_m<fmaximumnum, FMAX_D, Ext>;
   defm : PatFprFpr_m<riscv_fmin, FMIN_D, Ext>;
   defm : PatFprFpr_m<riscv_fmax, FMAX_D, Ext>;
 }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
index e6c25e0844fb2c..24a72f480f7885 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td
@@ -603,6 +603,8 @@ def : Pat<(fneg (any_fma_nsz FPR32INX:$rs1, FPR32INX:$rs2, FPR32INX:$rs3)),
 foreach Ext = FExts in {
   defm : PatFprFpr_m<fminnum, FMIN_S, Ext>;
   defm : PatFprFpr_m<fmaxnum, FMAX_S, Ext>;
+  defm : PatFprFpr_m<fminimumnum, FMIN_S, Ext>;
+  defm : PatFprFpr_m<fmaximumnum, FMAX_S, Ext>;
   defm : PatFprFpr_m<riscv_fmin, FMIN_S, Ext>;
   defm : PatFprFpr_m<riscv_fmax, FMAX_S, Ext>;
 }
diff --git a/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll
new file mode 100644
index 00000000000000..6c9d0afafde6a4
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll
@@ -0,0 +1,383 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=riscv32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=RV32F
+; RUN: llc --mtriple=riscv32 --mattr=+d < %s | FileCheck %s --check-prefix=RV32D
+; RUN: llc --mtriple=riscv64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=RV64F
+; RUN: llc --mtriple=riscv64 --mattr=+d < %s | FileCheck %s --check-prefix=RV64D
+
+declare float @llvm.maximumnum.f32(float, float)
+declare double @llvm.maximumnum.f64(double, double)
+declare float @llvm.minimumnum.f32(float, float)
+declare double @llvm.minimumnum.f64(double, double)
+
+define float @maximumnum_float(float %x, float %y) {
+;
+; RV32F-LABEL: maximumnum_float:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmax.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_float:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_float:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmax.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_float:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @maximumnum_float_nsz(float %x, float %y) {
+;
+; RV32F-LABEL: maximumnum_float_nsz:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmax.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_float_nsz:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_float_nsz:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmax.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_float_nsz:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nsz float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @maximumnum_float_nnan(float %x, float %y) {
+;
+; RV32F-LABEL: maximumnum_float_nnan:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmax.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_float_nnan:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_float_nnan:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmax.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_float_nnan:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nnan float @llvm.maximumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+
+define double @maximumnum_double(double %x, double %y) {
+;
+; RV32F-LABEL: maximumnum_double:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fmaximum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_double:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_double:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fmaximum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_double:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @maximumnum_double_nsz(double %x, double %y) {
+;
+; RV32F-LABEL: maximumnum_double_nsz:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fmaximum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_double_nsz:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_double_nsz:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fmaximum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_double_nsz:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nsz double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @maximumnum_double_nnan(double %x, double %y) {
+;
+; RV32F-LABEL: maximumnum_double_nnan:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fmaximum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: maximumnum_double_nnan:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmax.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: maximumnum_double_nnan:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fmaximum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: maximumnum_double_nnan:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmax.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nnan double @llvm.maximumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define float @minimumnum_float(float %x, float %y) {
+;
+; RV32F-LABEL: minimumnum_float:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmin.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_float:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_float:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmin.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_float:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @minimumnum_float_nsz(float %x, float %y) {
+;
+; RV32F-LABEL: minimumnum_float_nsz:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmin.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_float_nsz:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_float_nsz:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmin.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_float_nsz:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nsz float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define float @minimumnum_float_nnan(float %x, float %y) {
+;
+; RV32F-LABEL: minimumnum_float_nnan:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    fmin.s fa0, fa0, fa1
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_float_nnan:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.s fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_float_nnan:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    fmin.s fa0, fa0, fa1
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_float_nnan:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.s fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nnan float @llvm.minimumnum.f32(float %x, float %y)
+  ret float %z
+}
+
+define double @minimumnum_double(double %x, double %y) {
+;
+; RV32F-LABEL: minimumnum_double:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fminimum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_double:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_double:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fminimum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_double:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @minimumnum_double_nsz(double %x, double %y) {
+;
+; RV32F-LABEL: minimumnum_double_nsz:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fminimum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_double_nsz:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_double_nsz:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fminimum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_double_nsz:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nsz double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}
+
+define double @minimumnum_double_nnan(double %x, double %y) {
+;
+; RV32F-LABEL: minimumnum_double_nnan:
+; RV32F:       # %bb.0:
+; RV32F-NEXT:    addi sp, sp, -16
+; RV32F-NEXT:    .cfi_def_cfa_offset 16
+; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32F-NEXT:    .cfi_offset ra, -4
+; RV32F-NEXT:    call fminimum_num
+; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32F-NEXT:    addi sp, sp, 16
+; RV32F-NEXT:    ret
+;
+; RV32D-LABEL: minimumnum_double_nnan:
+; RV32D:       # %bb.0:
+; RV32D-NEXT:    fmin.d fa0, fa0, fa1
+; RV32D-NEXT:    ret
+;
+; RV64F-LABEL: minimumnum_double_nnan:
+; RV64F:       # %bb.0:
+; RV64F-NEXT:    addi sp, sp, -16
+; RV64F-NEXT:    .cfi_def_cfa_offset 16
+; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64F-NEXT:    .cfi_offset ra, -8
+; RV64F-NEXT:    call fminimum_num
+; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64F-NEXT:    addi sp, sp, 16
+; RV64F-NEXT:    ret
+;
+; RV64D-LABEL: minimumnum_double_nnan:
+; RV64D:       # %bb.0:
+; RV64D-NEXT:    fmin.d fa0, fa0, fa1
+; RV64D-NEXT:    ret
+  %z = call nnan double @llvm.minimumnum.f64(double %x, double %y)
+  ret double %z
+}

>From e8e28f35b1ed34251691aa28e23e845847423025 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Thu, 15 Aug 2024 21:41:27 +0800
Subject: [PATCH 2/3] Remove unwanted entry in the scope of vector

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4dc140487c81ce..04397aae159d34 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1309,8 +1309,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
         setOperationAction({ISD::FADD, ISD::FSUB, ISD::FMUL, ISD::FDIV,
                             ISD::FNEG, ISD::FABS, ISD::FCOPYSIGN, ISD::FSQRT,
                             ISD::FMA, ISD::FMINNUM, ISD::FMAXNUM,
-                            ISD::IS_FPCLASS, ISD::FMAXIMUM, ISD::FMINIMUM,
-                            ISD::FMINIMUMNUM, ISD::FMAXIMUMNUM},
+                            ISD::IS_FPCLASS, ISD::FMAXIMUM, ISD::FMINIMUM},
                            VT, Custom);
 
         setOperationAction({ISD::FTRUNC, ISD::FCEIL, ISD::FFLOOR, ISD::FROUND,

>From 65a1262d2df0776b11e27f6db938c8322a739e86 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Fri, 16 Aug 2024 10:17:31 +0800
Subject: [PATCH 3/3] Fix Zfh support

---
 llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td    |   2 +
 .../CodeGen/RISCV/fp-maximumnum-minimumnum.ll | 983 ++++++++++++------
 2 files changed, 669 insertions(+), 316 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
index abdd366741eb04..6c5375bb927c54 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
@@ -347,6 +347,8 @@ def : Pat<(fneg (any_fma_nsz FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3)),
 foreach Ext = ZfhExts in {
   defm : PatFprFpr_m<fminnum, FMIN_H, Ext>;
   defm : PatFprFpr_m<fmaxnum, FMAX_H, Ext>;
+  defm : PatFprFpr_m<fminimumnum, FMIN_H, Ext>;
+  defm : PatFprFpr_m<fmaximumnum, FMAX_H, Ext>;
   defm : PatFprFpr_m<riscv_fmin, FMIN_H, Ext>;
   defm : PatFprFpr_m<riscv_fmax, FMAX_H, Ext>;
 }
diff --git a/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll b/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll
index 6c9d0afafde6a4..1465bae52561c7 100644
--- a/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll
+++ b/llvm/test/CodeGen/RISCV/fp-maximumnum-minimumnum.ll
@@ -1,8 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc --mtriple=riscv32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=RV32F
-; RUN: llc --mtriple=riscv32 --mattr=+d < %s | FileCheck %s --check-prefix=RV32D
-; RUN: llc --mtriple=riscv64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=RV64F
-; RUN: llc --mtriple=riscv64 --mattr=+d < %s | FileCheck %s --check-prefix=RV64D
+; RUN: llc --mtriple=riscv32 --mattr=+f,-d,+zfh < %s | FileCheck %s --check-prefix=RV32FH
+; RUN: llc --mtriple=riscv32 --mattr=+d,+zfh < %s | FileCheck %s --check-prefix=RV32DH
+; RUN: llc --mtriple=riscv64 --mattr=+f,-d,+zfh < %s | FileCheck %s --check-prefix=RV64FH
+; RUN: llc --mtriple=riscv64 --mattr=+d,+zfh < %s | FileCheck %s --check-prefix=RV64DH
+; RUN: llc --mtriple=riscv32 --mattr=+d,-zfh < %s | FileCheck %s --check-prefix=RV32DNH
+; RUN: llc --mtriple=riscv64 --mattr=+d,-zfh < %s | FileCheck %s --check-prefix=RV64DNH
 
 declare float @llvm.maximumnum.f32(float, float)
 declare double @llvm.maximumnum.f64(double, double)
@@ -10,374 +12,723 @@ declare float @llvm.minimumnum.f32(float, float)
 declare double @llvm.minimumnum.f64(double, double)
 
 define float @maximumnum_float(float %x, float %y) {
-;
-; RV32F-LABEL: maximumnum_float:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmax.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_float:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_float:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmax.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_float:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_float:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_float:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_float:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_float:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_float:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_float:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call float @llvm.maximumnum.f32(float %x, float %y)
   ret float %z
 }
 
 define float @maximumnum_float_nsz(float %x, float %y) {
-;
-; RV32F-LABEL: maximumnum_float_nsz:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmax.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_float_nsz:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_float_nsz:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmax.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_float_nsz:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_float_nsz:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_float_nsz:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_float_nsz:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_float_nsz:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_float_nsz:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_float_nsz:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nsz float @llvm.maximumnum.f32(float %x, float %y)
   ret float %z
 }
 
 define float @maximumnum_float_nnan(float %x, float %y) {
-;
-; RV32F-LABEL: maximumnum_float_nnan:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmax.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_float_nnan:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_float_nnan:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmax.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_float_nnan:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_float_nnan:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_float_nnan:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_float_nnan:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_float_nnan:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_float_nnan:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_float_nnan:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nnan float @llvm.maximumnum.f32(float %x, float %y)
   ret float %z
 }
 
 
 define double @maximumnum_double(double %x, double %y) {
-;
-; RV32F-LABEL: maximumnum_double:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fmaximum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_double:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_double:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fmaximum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_double:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_double:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fmaximum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_double:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_double:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fmaximum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_double:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_double:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_double:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call double @llvm.maximumnum.f64(double %x, double %y)
   ret double %z
 }
 
 define double @maximumnum_double_nsz(double %x, double %y) {
-;
-; RV32F-LABEL: maximumnum_double_nsz:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fmaximum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_double_nsz:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_double_nsz:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fmaximum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_double_nsz:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_double_nsz:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fmaximum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_double_nsz:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_double_nsz:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fmaximum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_double_nsz:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_double_nsz:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_double_nsz:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nsz double @llvm.maximumnum.f64(double %x, double %y)
   ret double %z
 }
 
 define double @maximumnum_double_nnan(double %x, double %y) {
-;
-; RV32F-LABEL: maximumnum_double_nnan:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fmaximum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: maximumnum_double_nnan:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmax.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: maximumnum_double_nnan:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fmaximum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: maximumnum_double_nnan:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmax.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: maximumnum_double_nnan:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fmaximum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: maximumnum_double_nnan:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: maximumnum_double_nnan:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fmaximum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: maximumnum_double_nnan:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: maximumnum_double_nnan:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: maximumnum_double_nnan:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmax.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nnan double @llvm.maximumnum.f64(double %x, double %y)
   ret double %z
 }
 
 define float @minimumnum_float(float %x, float %y) {
-;
-; RV32F-LABEL: minimumnum_float:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmin.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_float:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_float:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmin.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_float:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_float:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_float:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_float:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_float:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_float:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_float:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call float @llvm.minimumnum.f32(float %x, float %y)
   ret float %z
 }
 
 define float @minimumnum_float_nsz(float %x, float %y) {
-;
-; RV32F-LABEL: minimumnum_float_nsz:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmin.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_float_nsz:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_float_nsz:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmin.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_float_nsz:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_float_nsz:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_float_nsz:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_float_nsz:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_float_nsz:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_float_nsz:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_float_nsz:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nsz float @llvm.minimumnum.f32(float %x, float %y)
   ret float %z
 }
 
 define float @minimumnum_float_nnan(float %x, float %y) {
-;
-; RV32F-LABEL: minimumnum_float_nnan:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    fmin.s fa0, fa0, fa1
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_float_nnan:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.s fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_float_nnan:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    fmin.s fa0, fa0, fa1
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_float_nnan:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.s fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_float_nnan:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_float_nnan:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_float_nnan:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_float_nnan:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_float_nnan:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_float_nnan:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nnan float @llvm.minimumnum.f32(float %x, float %y)
   ret float %z
 }
 
 define double @minimumnum_double(double %x, double %y) {
-;
-; RV32F-LABEL: minimumnum_double:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fminimum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_double:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_double:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fminimum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_double:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_double:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fminimum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_double:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_double:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fminimum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_double:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_double:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_double:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call double @llvm.minimumnum.f64(double %x, double %y)
   ret double %z
 }
 
 define double @minimumnum_double_nsz(double %x, double %y) {
-;
-; RV32F-LABEL: minimumnum_double_nsz:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fminimum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_double_nsz:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_double_nsz:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fminimum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_double_nsz:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_double_nsz:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fminimum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_double_nsz:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_double_nsz:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fminimum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_double_nsz:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_double_nsz:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_double_nsz:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nsz double @llvm.minimumnum.f64(double %x, double %y)
   ret double %z
 }
 
 define double @minimumnum_double_nnan(double %x, double %y) {
-;
-; RV32F-LABEL: minimumnum_double_nnan:
-; RV32F:       # %bb.0:
-; RV32F-NEXT:    addi sp, sp, -16
-; RV32F-NEXT:    .cfi_def_cfa_offset 16
-; RV32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
-; RV32F-NEXT:    .cfi_offset ra, -4
-; RV32F-NEXT:    call fminimum_num
-; RV32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
-; RV32F-NEXT:    addi sp, sp, 16
-; RV32F-NEXT:    ret
-;
-; RV32D-LABEL: minimumnum_double_nnan:
-; RV32D:       # %bb.0:
-; RV32D-NEXT:    fmin.d fa0, fa0, fa1
-; RV32D-NEXT:    ret
-;
-; RV64F-LABEL: minimumnum_double_nnan:
-; RV64F:       # %bb.0:
-; RV64F-NEXT:    addi sp, sp, -16
-; RV64F-NEXT:    .cfi_def_cfa_offset 16
-; RV64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
-; RV64F-NEXT:    .cfi_offset ra, -8
-; RV64F-NEXT:    call fminimum_num
-; RV64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
-; RV64F-NEXT:    addi sp, sp, 16
-; RV64F-NEXT:    ret
-;
-; RV64D-LABEL: minimumnum_double_nnan:
-; RV64D:       # %bb.0:
-; RV64D-NEXT:    fmin.d fa0, fa0, fa1
-; RV64D-NEXT:    ret
+; RV32FH-LABEL: minimumnum_double_nnan:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    addi sp, sp, -16
+; RV32FH-NEXT:    .cfi_def_cfa_offset 16
+; RV32FH-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32FH-NEXT:    .cfi_offset ra, -4
+; RV32FH-NEXT:    call fminimum_num
+; RV32FH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32FH-NEXT:    addi sp, sp, 16
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_double_nnan:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_double_nnan:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    addi sp, sp, -16
+; RV64FH-NEXT:    .cfi_def_cfa_offset 16
+; RV64FH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64FH-NEXT:    .cfi_offset ra, -8
+; RV64FH-NEXT:    call fminimum_num
+; RV64FH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64FH-NEXT:    addi sp, sp, 16
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_double_nnan:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_double_nnan:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_double_nnan:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    fmin.d fa0, fa0, fa1
+; RV64DNH-NEXT:    ret
   %z = call nnan double @llvm.minimumnum.f64(double %x, double %y)
   ret double %z
 }
+
+define half @minimumnum_half(half %x, half %y) {
+; RV32FH-LABEL: minimumnum_half:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_half:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_half:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_half:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_half:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    addi sp, sp, -32
+; RV32DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV32DNH-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    .cfi_offset ra, -4
+; RV32DNH-NEXT:    .cfi_offset fs0, -16
+; RV32DNH-NEXT:    .cfi_offset fs1, -24
+; RV32DNH-NEXT:    fmv.s fs0, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fa1
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmv.s fs1, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fs0
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV32DNH-NEXT:    call __truncsfhf2
+; RV32DNH-NEXT:    fmv.x.w a0, fa0
+; RV32DNH-NEXT:    lui a1, 1048560
+; RV32DNH-NEXT:    or a0, a0, a1
+; RV32DNH-NEXT:    fmv.w.x fa0, a0
+; RV32DNH-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    addi sp, sp, 32
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_half:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    addi sp, sp, -32
+; RV64DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV64DNH-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    .cfi_offset ra, -8
+; RV64DNH-NEXT:    .cfi_offset fs0, -16
+; RV64DNH-NEXT:    .cfi_offset fs1, -24
+; RV64DNH-NEXT:    fmv.s fs0, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fa1
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmv.s fs1, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fs0
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV64DNH-NEXT:    call __truncsfhf2
+; RV64DNH-NEXT:    fmv.x.w a0, fa0
+; RV64DNH-NEXT:    lui a1, 1048560
+; RV64DNH-NEXT:    or a0, a0, a1
+; RV64DNH-NEXT:    fmv.w.x fa0, a0
+; RV64DNH-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    addi sp, sp, 32
+; RV64DNH-NEXT:    ret
+  %z = call half @llvm.minimumnum.f16(half %x, half %y)
+  ret half %z
+}
+
+define half @minimumnum_half_nsz(half %x, half %y) {
+; RV32FH-LABEL: minimumnum_half_nsz:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_half_nsz:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_half_nsz:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_half_nsz:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_half_nsz:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    addi sp, sp, -32
+; RV32DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV32DNH-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    .cfi_offset ra, -4
+; RV32DNH-NEXT:    .cfi_offset fs0, -16
+; RV32DNH-NEXT:    .cfi_offset fs1, -24
+; RV32DNH-NEXT:    fmv.s fs0, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fa1
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmv.s fs1, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fs0
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV32DNH-NEXT:    call __truncsfhf2
+; RV32DNH-NEXT:    fmv.x.w a0, fa0
+; RV32DNH-NEXT:    lui a1, 1048560
+; RV32DNH-NEXT:    or a0, a0, a1
+; RV32DNH-NEXT:    fmv.w.x fa0, a0
+; RV32DNH-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    addi sp, sp, 32
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_half_nsz:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    addi sp, sp, -32
+; RV64DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV64DNH-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    .cfi_offset ra, -8
+; RV64DNH-NEXT:    .cfi_offset fs0, -16
+; RV64DNH-NEXT:    .cfi_offset fs1, -24
+; RV64DNH-NEXT:    fmv.s fs0, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fa1
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmv.s fs1, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fs0
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV64DNH-NEXT:    call __truncsfhf2
+; RV64DNH-NEXT:    fmv.x.w a0, fa0
+; RV64DNH-NEXT:    lui a1, 1048560
+; RV64DNH-NEXT:    or a0, a0, a1
+; RV64DNH-NEXT:    fmv.w.x fa0, a0
+; RV64DNH-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    addi sp, sp, 32
+; RV64DNH-NEXT:    ret
+  %z = call nsz half @llvm.minimumnum.f16(half %x, half %y)
+  ret half %z
+}
+
+define half @minimumnum_half_nnan(half %x, half %y) {
+; RV32FH-LABEL: minimumnum_half_nnan:
+; RV32FH:       # %bb.0:
+; RV32FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32FH-NEXT:    ret
+;
+; RV32DH-LABEL: minimumnum_half_nnan:
+; RV32DH:       # %bb.0:
+; RV32DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV32DH-NEXT:    ret
+;
+; RV64FH-LABEL: minimumnum_half_nnan:
+; RV64FH:       # %bb.0:
+; RV64FH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64FH-NEXT:    ret
+;
+; RV64DH-LABEL: minimumnum_half_nnan:
+; RV64DH:       # %bb.0:
+; RV64DH-NEXT:    fmin.h fa0, fa0, fa1
+; RV64DH-NEXT:    ret
+;
+; RV32DNH-LABEL: minimumnum_half_nnan:
+; RV32DNH:       # %bb.0:
+; RV32DNH-NEXT:    addi sp, sp, -32
+; RV32DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV32DNH-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV32DNH-NEXT:    .cfi_offset ra, -4
+; RV32DNH-NEXT:    .cfi_offset fs0, -16
+; RV32DNH-NEXT:    .cfi_offset fs1, -24
+; RV32DNH-NEXT:    fmv.s fs0, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fa1
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmv.s fs1, fa0
+; RV32DNH-NEXT:    fmv.s fa0, fs0
+; RV32DNH-NEXT:    call __extendhfsf2
+; RV32DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV32DNH-NEXT:    call __truncsfhf2
+; RV32DNH-NEXT:    fmv.x.w a0, fa0
+; RV32DNH-NEXT:    lui a1, 1048560
+; RV32DNH-NEXT:    or a0, a0, a1
+; RV32DNH-NEXT:    fmv.w.x fa0, a0
+; RV32DNH-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
+; RV32DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV32DNH-NEXT:    addi sp, sp, 32
+; RV32DNH-NEXT:    ret
+;
+; RV64DNH-LABEL: minimumnum_half_nnan:
+; RV64DNH:       # %bb.0:
+; RV64DNH-NEXT:    addi sp, sp, -32
+; RV64DNH-NEXT:    .cfi_def_cfa_offset 32
+; RV64DNH-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs0, 16(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    fsd fs1, 8(sp) # 8-byte Folded Spill
+; RV64DNH-NEXT:    .cfi_offset ra, -8
+; RV64DNH-NEXT:    .cfi_offset fs0, -16
+; RV64DNH-NEXT:    .cfi_offset fs1, -24
+; RV64DNH-NEXT:    fmv.s fs0, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fa1
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmv.s fs1, fa0
+; RV64DNH-NEXT:    fmv.s fa0, fs0
+; RV64DNH-NEXT:    call __extendhfsf2
+; RV64DNH-NEXT:    fmin.s fa0, fa0, fs1
+; RV64DNH-NEXT:    call __truncsfhf2
+; RV64DNH-NEXT:    fmv.x.w a0, fa0
+; RV64DNH-NEXT:    lui a1, 1048560
+; RV64DNH-NEXT:    or a0, a0, a1
+; RV64DNH-NEXT:    fmv.w.x fa0, a0
+; RV64DNH-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs0, 16(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    fld fs1, 8(sp) # 8-byte Folded Reload
+; RV64DNH-NEXT:    addi sp, sp, 32
+; RV64DNH-NEXT:    ret
+  %z = call nnan half @llvm.minimumnum.f16(half %x, half %y)
+  ret half %z
+}
+



More information about the llvm-commits mailing list