Skip to content

Commit 2b84fe6

Browse files
authored
RISC-V: Add fminimumnum and fmaximumnum support (#104411)
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.
1 parent d8b6df2 commit 2b84fe6

File tree

7 files changed

+397
-15
lines changed

7 files changed

+397
-15
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -365,12 +365,13 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
365365
setOperationAction(ISD::SELECT, XLenVT, Custom);
366366

367367
static const unsigned FPLegalNodeTypes[] = {
368-
ISD::FMINNUM, ISD::FMAXNUM, ISD::LRINT,
369-
ISD::LLRINT, ISD::LROUND, ISD::LLROUND,
370-
ISD::STRICT_LRINT, ISD::STRICT_LLRINT, ISD::STRICT_LROUND,
371-
ISD::STRICT_LLROUND, ISD::STRICT_FMA, ISD::STRICT_FADD,
372-
ISD::STRICT_FSUB, ISD::STRICT_FMUL, ISD::STRICT_FDIV,
373-
ISD::STRICT_FSQRT, ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS};
368+
ISD::FMINNUM, ISD::FMAXNUM, ISD::FMINIMUMNUM,
369+
ISD::FMAXIMUMNUM, ISD::LRINT, ISD::LLRINT,
370+
ISD::LROUND, ISD::LLROUND, ISD::STRICT_LRINT,
371+
ISD::STRICT_LLRINT, ISD::STRICT_LROUND, ISD::STRICT_LLROUND,
372+
ISD::STRICT_FMA, ISD::STRICT_FADD, ISD::STRICT_FSUB,
373+
ISD::STRICT_FMUL, ISD::STRICT_FDIV, ISD::STRICT_FSQRT,
374+
ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS};
374375

375376
static const ISD::CondCode FPCCToExpand[] = {
376377
ISD::SETOGT, ISD::SETOGE, ISD::SETONE, ISD::SETUEQ, ISD::SETUGT,
@@ -389,15 +390,20 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
389390
setOperationAction(ISD::BITCAST, MVT::i16, Custom);
390391

391392
static const unsigned ZfhminZfbfminPromoteOps[] = {
392-
ISD::FMINNUM, ISD::FMAXNUM, ISD::FADD,
393-
ISD::FSUB, ISD::FMUL, ISD::FMA,
394-
ISD::FDIV, ISD::FSQRT, ISD::FABS,
395-
ISD::FNEG, ISD::STRICT_FMA, ISD::STRICT_FADD,
396-
ISD::STRICT_FSUB, ISD::STRICT_FMUL, ISD::STRICT_FDIV,
397-
ISD::STRICT_FSQRT, ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS,
398-
ISD::SETCC, ISD::FCEIL, ISD::FFLOOR,
399-
ISD::FTRUNC, ISD::FRINT, ISD::FROUND,
400-
ISD::FROUNDEVEN, ISD::SELECT};
393+
ISD::FMINNUM, ISD::FMAXNUM,
394+
ISD::FMAXIMUMNUM, ISD::FMINIMUMNUM,
395+
ISD::FADD, ISD::FSUB,
396+
ISD::FMUL, ISD::FMA,
397+
ISD::FDIV, ISD::FSQRT,
398+
ISD::FABS, ISD::FNEG,
399+
ISD::STRICT_FMA, ISD::STRICT_FADD,
400+
ISD::STRICT_FSUB, ISD::STRICT_FMUL,
401+
ISD::STRICT_FDIV, ISD::STRICT_FSQRT,
402+
ISD::STRICT_FSETCC, ISD::STRICT_FSETCCS,
403+
ISD::SETCC, ISD::FCEIL,
404+
ISD::FFLOOR, ISD::FTRUNC,
405+
ISD::FRINT, ISD::FROUND,
406+
ISD::FROUNDEVEN, ISD::SELECT};
401407

402408
if (Subtarget.hasStdExtZfbfmin()) {
403409
setOperationAction(ISD::BITCAST, MVT::i16, Custom);

llvm/lib/Target/RISCV/RISCVInstrInfoD.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,8 @@ def : Pat<(fneg (any_fma_nsz FPR64IN32X:$rs1, FPR64IN32X:$rs2, FPR64IN32X:$rs3))
392392
foreach Ext = DExts in {
393393
defm : PatFprFpr_m<fminnum, FMIN_D, Ext>;
394394
defm : PatFprFpr_m<fmaxnum, FMAX_D, Ext>;
395+
defm : PatFprFpr_m<fminimumnum, FMIN_D, Ext>;
396+
defm : PatFprFpr_m<fmaximumnum, FMAX_D, Ext>;
395397
defm : PatFprFpr_m<riscv_fmin, FMIN_D, Ext>;
396398
defm : PatFprFpr_m<riscv_fmax, FMAX_D, Ext>;
397399
}

llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ def : Pat<(fneg (any_fma_nsz FPR32INX:$rs1, FPR32INX:$rs2, FPR32INX:$rs3)),
603603
foreach Ext = FExts in {
604604
defm : PatFprFpr_m<fminnum, FMIN_S, Ext>;
605605
defm : PatFprFpr_m<fmaxnum, FMAX_S, Ext>;
606+
defm : PatFprFpr_m<fminimumnum, FMIN_S, Ext>;
607+
defm : PatFprFpr_m<fmaximumnum, FMAX_S, Ext>;
606608
defm : PatFprFpr_m<riscv_fmin, FMIN_S, Ext>;
607609
defm : PatFprFpr_m<riscv_fmax, FMAX_S, Ext>;
608610
}

llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ def : Pat<(fneg (any_fma_nsz FPR16INX:$rs1, FPR16INX:$rs2, FPR16INX:$rs3)),
347347
foreach Ext = ZfhExts in {
348348
defm : PatFprFpr_m<fminnum, FMIN_H, Ext>;
349349
defm : PatFprFpr_m<fmaxnum, FMAX_H, Ext>;
350+
defm : PatFprFpr_m<fminimumnum, FMIN_H, Ext>;
351+
defm : PatFprFpr_m<fmaximumnum, FMAX_H, Ext>;
350352
defm : PatFprFpr_m<riscv_fmin, FMIN_H, Ext>;
351353
defm : PatFprFpr_m<riscv_fmax, FMAX_H, Ext>;
352354
}

llvm/test/CodeGen/RISCV/double-intrinsics.ll

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,3 +1545,89 @@ define i1 @isnan_d_fpclass(double %x) {
15451545
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 3) ; nan
15461546
ret i1 %1
15471547
}
1548+
1549+
declare double @llvm.maximumnum.f64(double, double)
1550+
1551+
define double @maximumnum_double(double %x, double %y) {
1552+
; CHECKIFD-LABEL: maximumnum_double:
1553+
; CHECKIFD: # %bb.0:
1554+
; CHECKIFD-NEXT: fmax.d fa0, fa0, fa1
1555+
; CHECKIFD-NEXT: ret
1556+
;
1557+
; RV32IZFINXZDINX-LABEL: maximumnum_double:
1558+
; RV32IZFINXZDINX: # %bb.0:
1559+
; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2
1560+
; RV32IZFINXZDINX-NEXT: ret
1561+
;
1562+
; RV64IZFINXZDINX-LABEL: maximumnum_double:
1563+
; RV64IZFINXZDINX: # %bb.0:
1564+
; RV64IZFINXZDINX-NEXT: fmax.d a0, a0, a1
1565+
; RV64IZFINXZDINX-NEXT: ret
1566+
;
1567+
; RV32I-LABEL: maximumnum_double:
1568+
; RV32I: # %bb.0:
1569+
; RV32I-NEXT: addi sp, sp, -16
1570+
; RV32I-NEXT: .cfi_def_cfa_offset 16
1571+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1572+
; RV32I-NEXT: .cfi_offset ra, -4
1573+
; RV32I-NEXT: call fmaximum_num
1574+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1575+
; RV32I-NEXT: addi sp, sp, 16
1576+
; RV32I-NEXT: ret
1577+
;
1578+
; RV64I-LABEL: maximumnum_double:
1579+
; RV64I: # %bb.0:
1580+
; RV64I-NEXT: addi sp, sp, -16
1581+
; RV64I-NEXT: .cfi_def_cfa_offset 16
1582+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1583+
; RV64I-NEXT: .cfi_offset ra, -8
1584+
; RV64I-NEXT: call fmaximum_num
1585+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1586+
; RV64I-NEXT: addi sp, sp, 16
1587+
; RV64I-NEXT: ret
1588+
%z = call double @llvm.maximumnum.f64(double %x, double %y)
1589+
ret double %z
1590+
}
1591+
1592+
declare double @llvm.minimumnum.f64(double, double)
1593+
1594+
define double @minimumnum_double(double %x, double %y) {
1595+
; CHECKIFD-LABEL: minimumnum_double:
1596+
; CHECKIFD: # %bb.0:
1597+
; CHECKIFD-NEXT: fmin.d fa0, fa0, fa1
1598+
; CHECKIFD-NEXT: ret
1599+
;
1600+
; RV32IZFINXZDINX-LABEL: minimumnum_double:
1601+
; RV32IZFINXZDINX: # %bb.0:
1602+
; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2
1603+
; RV32IZFINXZDINX-NEXT: ret
1604+
;
1605+
; RV64IZFINXZDINX-LABEL: minimumnum_double:
1606+
; RV64IZFINXZDINX: # %bb.0:
1607+
; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1
1608+
; RV64IZFINXZDINX-NEXT: ret
1609+
;
1610+
; RV32I-LABEL: minimumnum_double:
1611+
; RV32I: # %bb.0:
1612+
; RV32I-NEXT: addi sp, sp, -16
1613+
; RV32I-NEXT: .cfi_def_cfa_offset 16
1614+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1615+
; RV32I-NEXT: .cfi_offset ra, -4
1616+
; RV32I-NEXT: call fminimum_num
1617+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1618+
; RV32I-NEXT: addi sp, sp, 16
1619+
; RV32I-NEXT: ret
1620+
;
1621+
; RV64I-LABEL: minimumnum_double:
1622+
; RV64I: # %bb.0:
1623+
; RV64I-NEXT: addi sp, sp, -16
1624+
; RV64I-NEXT: .cfi_def_cfa_offset 16
1625+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1626+
; RV64I-NEXT: .cfi_offset ra, -8
1627+
; RV64I-NEXT: call fminimum_num
1628+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1629+
; RV64I-NEXT: addi sp, sp, 16
1630+
; RV64I-NEXT: ret
1631+
%z = call double @llvm.minimumnum.f64(double %x, double %y)
1632+
ret double %z
1633+
}

llvm/test/CodeGen/RISCV/float-intrinsics.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,3 +2185,99 @@ define i1 @isnotfinite_fpclass(float %x) {
21852185
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 519) ; ox207 = "inf|nan"
21862186
ret i1 %1
21872187
}
2188+
2189+
declare float @llvm.maximumnum.f32(float, float)
2190+
2191+
define float @maximumnum_float(float %x, float %y) {
2192+
; RV32IF-LABEL: maximumnum_float:
2193+
; RV32IF: # %bb.0:
2194+
; RV32IF-NEXT: fmax.s fa0, fa0, fa1
2195+
; RV32IF-NEXT: ret
2196+
;
2197+
; RV32IZFINX-LABEL: maximumnum_float:
2198+
; RV32IZFINX: # %bb.0:
2199+
; RV32IZFINX-NEXT: fmax.s a0, a0, a1
2200+
; RV32IZFINX-NEXT: ret
2201+
;
2202+
; RV64IF-LABEL: maximumnum_float:
2203+
; RV64IF: # %bb.0:
2204+
; RV64IF-NEXT: fmax.s fa0, fa0, fa1
2205+
; RV64IF-NEXT: ret
2206+
;
2207+
; RV64IZFINX-LABEL: maximumnum_float:
2208+
; RV64IZFINX: # %bb.0:
2209+
; RV64IZFINX-NEXT: fmax.s a0, a0, a1
2210+
; RV64IZFINX-NEXT: ret
2211+
;
2212+
; RV32I-LABEL: maximumnum_float:
2213+
; RV32I: # %bb.0:
2214+
; RV32I-NEXT: addi sp, sp, -16
2215+
; RV32I-NEXT: .cfi_def_cfa_offset 16
2216+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2217+
; RV32I-NEXT: .cfi_offset ra, -4
2218+
; RV32I-NEXT: call fmaximum_numf
2219+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2220+
; RV32I-NEXT: addi sp, sp, 16
2221+
; RV32I-NEXT: ret
2222+
;
2223+
; RV64I-LABEL: maximumnum_float:
2224+
; RV64I: # %bb.0:
2225+
; RV64I-NEXT: addi sp, sp, -16
2226+
; RV64I-NEXT: .cfi_def_cfa_offset 16
2227+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
2228+
; RV64I-NEXT: .cfi_offset ra, -8
2229+
; RV64I-NEXT: call fmaximum_numf
2230+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
2231+
; RV64I-NEXT: addi sp, sp, 16
2232+
; RV64I-NEXT: ret
2233+
%z = call float @llvm.maximumnum.f32(float %x, float %y)
2234+
ret float %z
2235+
}
2236+
2237+
declare float @llvm.minimumnum.f32(float, float)
2238+
2239+
define float @minimumnum_float(float %x, float %y) {
2240+
; RV32IF-LABEL: minimumnum_float:
2241+
; RV32IF: # %bb.0:
2242+
; RV32IF-NEXT: fmin.s fa0, fa0, fa1
2243+
; RV32IF-NEXT: ret
2244+
;
2245+
; RV32IZFINX-LABEL: minimumnum_float:
2246+
; RV32IZFINX: # %bb.0:
2247+
; RV32IZFINX-NEXT: fmin.s a0, a0, a1
2248+
; RV32IZFINX-NEXT: ret
2249+
;
2250+
; RV64IF-LABEL: minimumnum_float:
2251+
; RV64IF: # %bb.0:
2252+
; RV64IF-NEXT: fmin.s fa0, fa0, fa1
2253+
; RV64IF-NEXT: ret
2254+
;
2255+
; RV64IZFINX-LABEL: minimumnum_float:
2256+
; RV64IZFINX: # %bb.0:
2257+
; RV64IZFINX-NEXT: fmin.s a0, a0, a1
2258+
; RV64IZFINX-NEXT: ret
2259+
;
2260+
; RV32I-LABEL: minimumnum_float:
2261+
; RV32I: # %bb.0:
2262+
; RV32I-NEXT: addi sp, sp, -16
2263+
; RV32I-NEXT: .cfi_def_cfa_offset 16
2264+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2265+
; RV32I-NEXT: .cfi_offset ra, -4
2266+
; RV32I-NEXT: call fminimum_numf
2267+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2268+
; RV32I-NEXT: addi sp, sp, 16
2269+
; RV32I-NEXT: ret
2270+
;
2271+
; RV64I-LABEL: minimumnum_float:
2272+
; RV64I: # %bb.0:
2273+
; RV64I-NEXT: addi sp, sp, -16
2274+
; RV64I-NEXT: .cfi_def_cfa_offset 16
2275+
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
2276+
; RV64I-NEXT: .cfi_offset ra, -8
2277+
; RV64I-NEXT: call fminimum_numf
2278+
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
2279+
; RV64I-NEXT: addi sp, sp, 16
2280+
; RV64I-NEXT: ret
2281+
%z = call float @llvm.minimumnum.f32(float %x, float %y)
2282+
ret float %z
2283+
}

0 commit comments

Comments
 (0)