Skip to content

Conversation

@sunshaoce
Copy link
Contributor

Similar to the implementation in #104411 , the fmin.s/fmax.s instructions follow IEEE 754-2019 semantics, and G_FMINIMUMNUM/G_FMAXIMUMNUM are legal.

Similar to the implementation in llvm#104411
, the `fmin.s`/`fmax.s` instructions follow IEEE 754-2019 semantics, and `G_FMINIMUMNUM`/`G_FMAXIMUMNUM` are legal.
@llvmbot
Copy link
Member

llvmbot commented Sep 6, 2025

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-risc-v

Author: Shaoce SUN (sunshaoce)

Changes

Similar to the implementation in #104411 , the fmin.s/fmax.s instructions follow IEEE 754-2019 semantics, and G_FMINIMUMNUM/G_FMAXIMUMNUM are legal.


Patch is 28.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/157295.diff

8 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp (+6)
  • (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+6)
  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+3-2)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll (+90-32)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll (+90-32)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir (+8-6)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith-f16.mir (+42)
  • (modified) llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-fp-arith.mir (+84)
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index a38d305a8bb52..3c432012c9fd1 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -487,6 +487,10 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
     RTLIBCASE(FMIN_F);
   case TargetOpcode::G_FMAXNUM:
     RTLIBCASE(FMAX_F);
+  case TargetOpcode::G_FMINIMUMNUM:
+    RTLIBCASE(FMINIMUM_NUM_F);
+  case TargetOpcode::G_FMAXIMUMNUM:
+    RTLIBCASE(FMAXIMUM_NUM_F);
   case TargetOpcode::G_FSQRT:
     RTLIBCASE(SQRT_F);
   case TargetOpcode::G_FRINT:
@@ -1307,6 +1311,8 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
   case TargetOpcode::G_FFLOOR:
   case TargetOpcode::G_FMINNUM:
   case TargetOpcode::G_FMAXNUM:
+  case TargetOpcode::G_FMINIMUMNUM:
+  case TargetOpcode::G_FMAXIMUMNUM:
   case TargetOpcode::G_FSQRT:
   case TargetOpcode::G_FRINT:
   case TargetOpcode::G_FNEARBYINT:
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 58d631e569b3a..ea6560407facf 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -775,6 +775,10 @@ llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
     return minimum(C1, C2);
   case TargetOpcode::G_FMAXIMUM:
     return maximum(C1, C2);
+  case TargetOpcode::G_FMINIMUMNUM:
+    return minimumnum(C1, C2);
+  case TargetOpcode::G_FMAXIMUMNUM:
+    return maximumnum(C1, C2);
   case TargetOpcode::G_FMINNUM_IEEE:
   case TargetOpcode::G_FMAXNUM_IEEE:
     // FIXME: These operations were unfortunately named. fminnum/fmaxnum do not
@@ -1758,9 +1762,11 @@ bool llvm::isPreISelGenericFloatingPointOpcode(unsigned Opc) {
   case TargetOpcode::G_FMA:
   case TargetOpcode::G_FMAD:
   case TargetOpcode::G_FMAXIMUM:
+  case TargetOpcode::G_FMAXIMUMNUM:
   case TargetOpcode::G_FMAXNUM:
   case TargetOpcode::G_FMAXNUM_IEEE:
   case TargetOpcode::G_FMINIMUM:
+  case TargetOpcode::G_FMINIMUMNUM:
   case TargetOpcode::G_FMINNUM:
   case TargetOpcode::G_FMINNUM_IEEE:
   case TargetOpcode::G_FMUL:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index ab5c9e17b9a37..78a8ad32c74ec 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -507,8 +507,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
   // FP Operations
 
   // FIXME: Support s128 for rv32 when libcall handling is able to use sret.
-  getActionDefinitionsBuilder(
-      {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM})
+  getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT,
+                               G_FMAXNUM, G_FMINNUM, G_FMAXIMUMNUM,
+                               G_FMINIMUMNUM})
       .legalFor(ST.hasStdExtF(), {s32})
       .legalFor(ST.hasStdExtD(), {s64})
       .legalFor(ST.hasStdExtZfh(), {s16})
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll
index 4eb7646d13a39..12684f30dbee0 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll
@@ -363,6 +363,64 @@ define double @fmax_d(double %a, double %b) nounwind {
   ret double %1
 }
 
+declare double @llvm.minimumnum.f64(double, double)
+
+define double @fminimumnum_d(double %a, double %b) nounwind {
+; CHECKIFD-LABEL: fminimumnum_d:
+; CHECKIFD:       # %bb.0:
+; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa1
+; CHECKIFD-NEXT:    ret
+;
+; RV32I-LABEL: fminimumnum_d:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    call fminimum_num
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: fminimumnum_d:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    call fminimum_num
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+  %1 = call double @llvm.minimumnum.f64(double %a, double %b)
+  ret double %1
+}
+
+declare double @llvm.maximumnum.f64(double, double)
+
+define double @fmaximumnum_d(double %a, double %b) nounwind {
+; CHECKIFD-LABEL: fmaximumnum_d:
+; CHECKIFD:       # %bb.0:
+; CHECKIFD-NEXT:    fmax.d fa0, fa0, fa1
+; CHECKIFD-NEXT:    ret
+;
+; RV32I-LABEL: fmaximumnum_d:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    call fmaximum_num
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: fmaximumnum_d:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    call fmaximum_num
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+  %1 = call double @llvm.maximumnum.f64(double %a, double %b)
+  ret double %1
+}
+
 declare double @llvm.fma.f64(double, double, double)
 
 define double @fmadd_d(double %a, double %b, double %c) nounwind {
@@ -420,8 +478,8 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s2, a2
 ; RV32I-NEXT:    mv s3, a3
 ; RV32I-NEXT:    mv a0, a4
-; RV32I-NEXT:    lui a1, %hi(.LCPI12_0)
-; RV32I-NEXT:    addi a1, a1, %lo(.LCPI12_0)
+; RV32I-NEXT:    lui a1, %hi(.LCPI14_0)
+; RV32I-NEXT:    addi a1, a1, %lo(.LCPI14_0)
 ; RV32I-NEXT:    lw a2, 0(a1)
 ; RV32I-NEXT:    lw a3, 4(a1)
 ; RV32I-NEXT:    mv a1, a5
@@ -450,8 +508,8 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv s1, a1
-; RV64I-NEXT:    lui a0, %hi(.LCPI12_0)
-; RV64I-NEXT:    ld a1, %lo(.LCPI12_0)(a0)
+; RV64I-NEXT:    lui a0, %hi(.LCPI14_0)
+; RV64I-NEXT:    ld a1, %lo(.LCPI14_0)(a0)
 ; RV64I-NEXT:    mv a0, a2
 ; RV64I-NEXT:    call __adddf3
 ; RV64I-NEXT:    li a1, -1
@@ -503,8 +561,8 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s0, a2
 ; RV32I-NEXT:    mv s1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI13_0)
-; RV32I-NEXT:    addi a2, a2, %lo(.LCPI13_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI15_0)
+; RV32I-NEXT:    addi a2, a2, %lo(.LCPI15_0)
 ; RV32I-NEXT:    lw s3, 0(a2)
 ; RV32I-NEXT:    lw s4, 4(a2)
 ; RV32I-NEXT:    mv s5, a5
@@ -548,8 +606,8 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI13_0)
-; RV64I-NEXT:    ld s1, %lo(.LCPI13_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI15_0)
+; RV64I-NEXT:    ld s1, %lo(.LCPI15_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __adddf3
@@ -613,8 +671,8 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv a0, a2
 ; RV32I-NEXT:    mv a1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI14_0)
-; RV32I-NEXT:    addi a2, a2, %lo(.LCPI14_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI16_0)
+; RV32I-NEXT:    addi a2, a2, %lo(.LCPI16_0)
 ; RV32I-NEXT:    lw s3, 0(a2)
 ; RV32I-NEXT:    lw s4, 4(a2)
 ; RV32I-NEXT:    mv s5, a5
@@ -658,8 +716,8 @@ define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI14_0)
-; RV64I-NEXT:    ld s1, %lo(.LCPI14_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI16_0)
+; RV64I-NEXT:    ld s1, %lo(.LCPI16_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __adddf3
@@ -783,8 +841,8 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s0, a2
 ; RV32I-NEXT:    mv s1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI17_0)
-; RV32I-NEXT:    addi a3, a2, %lo(.LCPI17_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI19_0)
+; RV32I-NEXT:    addi a3, a2, %lo(.LCPI19_0)
 ; RV32I-NEXT:    lw a2, 0(a3)
 ; RV32I-NEXT:    lw a3, 4(a3)
 ; RV32I-NEXT:    mv s3, a5
@@ -811,8 +869,8 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI17_0)
-; RV64I-NEXT:    ld a1, %lo(.LCPI17_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI19_0)
+; RV64I-NEXT:    ld a1, %lo(.LCPI19_0)(a1)
 ; RV64I-NEXT:    mv s1, a2
 ; RV64I-NEXT:    call __adddf3
 ; RV64I-NEXT:    li a1, -1
@@ -860,8 +918,8 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv a0, a2
 ; RV32I-NEXT:    mv a1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI18_0)
-; RV32I-NEXT:    addi a3, a2, %lo(.LCPI18_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI20_0)
+; RV32I-NEXT:    addi a3, a2, %lo(.LCPI20_0)
 ; RV32I-NEXT:    lw a2, 0(a3)
 ; RV32I-NEXT:    lw a3, 4(a3)
 ; RV32I-NEXT:    mv s3, a5
@@ -890,8 +948,8 @@ define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI18_0)
-; RV64I-NEXT:    ld a1, %lo(.LCPI18_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI20_0)
+; RV64I-NEXT:    ld a1, %lo(.LCPI20_0)(a1)
 ; RV64I-NEXT:    mv s1, a2
 ; RV64I-NEXT:    call __adddf3
 ; RV64I-NEXT:    li a1, -1
@@ -985,8 +1043,8 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s2, a2
 ; RV32I-NEXT:    mv s3, a3
 ; RV32I-NEXT:    mv a0, a4
-; RV32I-NEXT:    lui a1, %hi(.LCPI20_0)
-; RV32I-NEXT:    addi a1, a1, %lo(.LCPI20_0)
+; RV32I-NEXT:    lui a1, %hi(.LCPI22_0)
+; RV32I-NEXT:    addi a1, a1, %lo(.LCPI22_0)
 ; RV32I-NEXT:    lw a2, 0(a1)
 ; RV32I-NEXT:    lw a3, 4(a1)
 ; RV32I-NEXT:    mv a1, a5
@@ -1020,8 +1078,8 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv s1, a1
-; RV64I-NEXT:    lui a0, %hi(.LCPI20_0)
-; RV64I-NEXT:    ld a1, %lo(.LCPI20_0)(a0)
+; RV64I-NEXT:    lui a0, %hi(.LCPI22_0)
+; RV64I-NEXT:    ld a1, %lo(.LCPI22_0)(a0)
 ; RV64I-NEXT:    mv a0, a2
 ; RV64I-NEXT:    call __adddf3
 ; RV64I-NEXT:    mv s2, a0
@@ -1080,8 +1138,8 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s0, a2
 ; RV32I-NEXT:    mv s1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI21_0)
-; RV32I-NEXT:    addi a2, a2, %lo(.LCPI21_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI23_0)
+; RV32I-NEXT:    addi a2, a2, %lo(.LCPI23_0)
 ; RV32I-NEXT:    lw s3, 0(a2)
 ; RV32I-NEXT:    lw s4, 4(a2)
 ; RV32I-NEXT:    mv s5, a5
@@ -1135,8 +1193,8 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI21_0)
-; RV64I-NEXT:    ld s1, %lo(.LCPI21_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI23_0)
+; RV64I-NEXT:    ld s1, %lo(.LCPI23_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __adddf3
@@ -1205,8 +1263,8 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
 ; RV32I-NEXT:    mv s0, a2
 ; RV32I-NEXT:    mv s1, a3
 ; RV32I-NEXT:    mv s2, a4
-; RV32I-NEXT:    lui a2, %hi(.LCPI22_0)
-; RV32I-NEXT:    addi a2, a2, %lo(.LCPI22_0)
+; RV32I-NEXT:    lui a2, %hi(.LCPI24_0)
+; RV32I-NEXT:    addi a2, a2, %lo(.LCPI24_0)
 ; RV32I-NEXT:    lw s3, 0(a2)
 ; RV32I-NEXT:    lw s4, 4(a2)
 ; RV32I-NEXT:    mv s5, a5
@@ -1251,8 +1309,8 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI22_0)
-; RV64I-NEXT:    ld s1, %lo(.LCPI22_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI24_0)
+; RV64I-NEXT:    ld s1, %lo(.LCPI24_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __adddf3
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll
index fdeda0c273f6d..739f225ad1525 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/float-arith.ll
@@ -311,6 +311,64 @@ define float @fabs_s(float %a, float %b) nounwind {
   ret float %3
 }
 
+declare float @llvm.minimumnum.f32(float, float)
+
+define float @fminimumnum_s(float %a, float %b) nounwind {
+; CHECKIF-LABEL: fminimumnum_s:
+; CHECKIF:       # %bb.0:
+; CHECKIF-NEXT:    fmin.s fa0, fa0, fa1
+; CHECKIF-NEXT:    ret
+;
+; RV32I-LABEL: fminimumnum_s:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    call fminimum_numf
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: fminimumnum_s:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    call fminimum_numf
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+  %1 = call float @llvm.minimumnum.f32(float %a, float %b)
+  ret float %1
+}
+
+declare float @llvm.maximumnum.f32(float, float)
+
+define float @fmaximumnum_s(float %a, float %b) nounwind {
+; CHECKIF-LABEL: fmaximumnum_s:
+; CHECKIF:       # %bb.0:
+; CHECKIF-NEXT:    fmax.s fa0, fa0, fa1
+; CHECKIF-NEXT:    ret
+;
+; RV32I-LABEL: fmaximumnum_s:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    call fmaximum_numf
+; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: fmaximumnum_s:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -16
+; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    call fmaximum_numf
+; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+  %1 = call float @llvm.maximumnum.f32(float %a, float %b)
+  ret float %1
+}
+
 declare float @llvm.minnum.f32(float, float)
 
 define float @fmin_s(float %a, float %b) nounwind {
@@ -414,8 +472,8 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a0
 ; RV32I-NEXT:    mv s1, a1
-; RV32I-NEXT:    lui a0, %hi(.LCPI12_0)
-; RV32I-NEXT:    lw a1, %lo(.LCPI12_0)(a0)
+; RV32I-NEXT:    lui a0, %hi(.LCPI14_0)
+; RV32I-NEXT:    lw a1, %lo(.LCPI14_0)(a0)
 ; RV32I-NEXT:    mv a0, a2
 ; RV32I-NEXT:    call __addsf3
 ; RV32I-NEXT:    lui a2, 524288
@@ -437,8 +495,8 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv s1, a1
-; RV64I-NEXT:    lui a0, %hi(.LCPI12_0)
-; RV64I-NEXT:    lw a1, %lo(.LCPI12_0)(a0)
+; RV64I-NEXT:    lui a0, %hi(.LCPI14_0)
+; RV64I-NEXT:    lw a1, %lo(.LCPI14_0)(a0)
 ; RV64I-NEXT:    mv a0, a2
 ; RV64I-NEXT:    call __addsf3
 ; RV64I-NEXT:    lui a2, 524288
@@ -475,8 +533,8 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a1
-; RV32I-NEXT:    lui a1, %hi(.LCPI13_0)
-; RV32I-NEXT:    lw s1, %lo(.LCPI13_0)(a1)
+; RV32I-NEXT:    lui a1, %hi(.LCPI15_0)
+; RV32I-NEXT:    lw s1, %lo(.LCPI15_0)(a1)
 ; RV32I-NEXT:    mv s2, a2
 ; RV32I-NEXT:    mv a1, s1
 ; RV32I-NEXT:    call __addsf3
@@ -507,8 +565,8 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI13_0)
-; RV64I-NEXT:    lw s1, %lo(.LCPI13_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI15_0)
+; RV64I-NEXT:    lw s1, %lo(.LCPI15_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __addsf3
@@ -556,8 +614,8 @@ define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a0
 ; RV32I-NEXT:    mv a0, a1
-; RV32I-NEXT:    lui a1, %hi(.LCPI14_0)
-; RV32I-NEXT:    lw s1, %lo(.LCPI14_0)(a1)
+; RV32I-NEXT:    lui a1, %hi(.LCPI16_0)
+; RV32I-NEXT:    lw s1, %lo(.LCPI16_0)(a1)
 ; RV32I-NEXT:    mv s2, a2
 ; RV32I-NEXT:    mv a1, s1
 ; RV32I-NEXT:    call __addsf3
@@ -588,8 +646,8 @@ define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI14_0)
-; RV64I-NEXT:    lw s1, %lo(.LCPI14_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI16_0)
+; RV64I-NEXT:    lw s1, %lo(.LCPI16_0)(a1)
 ; RV64I-NEXT:    mv s2, a2
 ; RV64I-NEXT:    mv a1, s1
 ; RV64I-NEXT:    call __addsf3
@@ -720,8 +778,8 @@ define float @fnmsub_s(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a1
-; RV32I-NEXT:    lui a1, %hi(.LCPI17_0)
-; RV32I-NEXT:    lw a1, %lo(.LCPI17_0)(a1)
+; RV32I-NEXT:    lui a1, %hi(.LCPI19_0)
+; RV32I-NEXT:    lw a1, %lo(.LCPI19_0)(a1)
 ; RV32I-NEXT:    mv s1, a2
 ; RV32I-NEXT:    call __addsf3
 ; RV32I-NEXT:    lui a1, 524288
@@ -742,8 +800,8 @@ define float @fnmsub_s(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI17_0)
-; RV64I-NEXT:    lw a1, %lo(.LCPI17_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI19_0)
+; RV64I-NEXT:    lw a1, %lo(.LCPI19_0)(a1)
 ; RV64I-NEXT:    mv s1, a2
 ; RV64I-NEXT:    call __addsf3
 ; RV64I-NEXT:    lui a1, 524288
@@ -778,8 +836,8 @@ define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a0
 ; RV32I-NEXT:    mv a0, a1
-; RV32I-NEXT:    lui a1, %hi(.LCPI18_0)
-; RV32I-NEXT:    lw a1, %lo(.LCPI18_0)(a1)
+; RV32I-NEXT:    lui a1, %hi(.LCPI20_0)
+; RV32I-NEXT:    lw a1, %lo(.LCPI20_0)(a1)
 ; RV32I-NEXT:    mv s1, a2
 ; RV32I-NEXT:    call __addsf3
 ; RV32I-NEXT:    lui a1, 524288
@@ -801,8 +859,8 @@ define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:    lui a1, %hi(.LCPI18_0)
-; RV64I-NEXT:    lw a1, %lo(.LCPI18_0)(a1)
+; RV64I-NEXT:    lui a1, %hi(.LCPI20_0)
+; RV64I-NEXT:    lw a1, %lo(.LCPI20_0)(a1)
 ; RV64I-NEXT:    mv s1, a2
 ; RV64I-NEXT:    call __addsf3
 ; RV64I-NEXT:    lui a1, 524288
@@ -877,8 +935,8 @@ define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
 ; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    mv s0, a0
 ; RV32I-NEXT:    mv s1, a1
-; RV32I-NEXT:    lui a0, %hi(.LCPI20_0)
-; RV32I-NEXT:    lw a1, %lo(.LCPI20_0)(a0)
+; RV32I-NEXT:    lui a0, %hi(.LCPI22_0)
+; RV32I-NEXT:    lw a1, %lo(.LCPI22_0)(a0)
 ; RV32I-NEXT:    mv a0, a2
 ; RV32I-NEXT:    call __addsf3
 ; RV32I-NEXT:    mv s2, a0
@@ -903,8 +961,8 @@ define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    mv s0, a0
 ; RV64I-NEXT:    mv s1, a1
-; RV64I-NEXT:    lui a0, %hi(.LCPI20_0)
-; RV64I-NEXT:    lw a1, %lo(.LCPI20_0)(a0)
+; RV64I-NEXT:    lui a0, %hi(.LCPI22_0)
+; RV64I-NEXT:    lw a1, %lo(.LCPI22_0)(a0)
 ; RV64I-NEXT...
[truncated]

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sunshaoce sunshaoce merged commit 41d7ae8 into llvm:main Sep 11, 2025
9 checks passed
@sunshaoce sunshaoce deleted the pr-fminimumnum branch September 11, 2025 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants