Files
clang-p2996/llvm/test/CodeGen/Mips/fp-maximumnum-minimumnum.ll
YunQiang Su fb9e685fc4 Intrinsic: introduce minimumnum and maximumnum for IR and SelectionDAG (#96649)
C23 introduced new functions fminimum_num and fmaximum_num, and they
follow the minimumNumber and maximumNumber of IEEE754-2019. Let's
introduce new intrinsics to support them.

This patch introduces support only support for scalar values. The
support of
  vector (vp, vp.reduce, vector.reduce),
  experimental.constrained
will be added in future patches.

With this patch, MIPSr6 and LoongArch can work out of box with
fcanonical and fmax/fmin.

Aarch64/PowerPC64 can use the same login as MIPSr6 and LoongArch, while
they have no fcanonical support yet.
I will add it in future patches.

The FMIN/FMAX of RISC-V instructions follows the
minimumNumber/maximumNumber of IEEE754-2019. We can just add it in
future patch.

Background

https://discourse.llvm.org/t/rfc-fix-llvm-min-f-and-llvm-max-f-intrinsics/79735
Currently we have fminnum/fmaxnum, which have different behavior on
different platform for NUM vs sNaN:
   1) Fallback to fmin(3)/fmax(3): return qNaN.
   2) ARM64/ARM32+Neon: same as libc.
   3) MIPSr6/LoongArch/RISC-V: return NUM.

And the fix of fminnum/fmaxnum to follow minNUM/maxNUM of IEEE754-2008
will submit as separated patches.
2024-08-15 14:09:36 +08:00

133 lines
4.2 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc --mtriple=mipsisa32r6 < %s | FileCheck %s --check-prefix=MIPS32R6
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) {
; MIPS32R6-LABEL: maximumnum_float:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.s $f0, $f14, $f14
; MIPS32R6-NEXT: min.s $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.s $f0, $f1, $f0
%z = call float @llvm.maximumnum.f32(float %x, float %y)
ret float %z
}
define float @maximumnum_float_nsz(float %x, float %y) {
; MIPS32R6-LABEL: maximumnum_float_nsz:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.s $f0, $f14, $f14
; MIPS32R6-NEXT: min.s $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.s $f0, $f1, $f0
%z = call nsz float @llvm.maximumnum.f32(float %x, float %y)
ret float %z
}
define float @maximumnum_float_nnan(float %x, float %y) {
; MIPS32R6-LABEL: maximumnum_float_nnan:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.s $f0, $f12, $f14
%z = call nnan float @llvm.maximumnum.f32(float %x, float %y)
ret float %z
}
define double @maximumnum_double(double %x, double %y) {
; MIPS32R6-LABEL: maximumnum_double:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.d $f0, $f14, $f14
; MIPS32R6-NEXT: min.d $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.d $f0, $f1, $f0
%z = call double @llvm.maximumnum.f64(double %x, double %y)
ret double %z
}
define double @maximumnum_double_nsz(double %x, double %y) {
; MIPS32R6-LABEL: maximumnum_double_nsz:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.d $f0, $f14, $f14
; MIPS32R6-NEXT: min.d $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.d $f0, $f1, $f0
%z = call nsz double @llvm.maximumnum.f64(double %x, double %y)
ret double %z
}
define double @maximumnum_double_nnan(double %x, double %y) {
; MIPS32R6-LABEL: maximumnum_double_nnan:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: max.d $f0, $f12, $f14
%z = call nnan double @llvm.maximumnum.f64(double %x, double %y)
ret double %z
}
define float @minimumnum_float(float %x, float %y) {
; MIPS32R6-LABEL: minimumnum_float:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.s $f0, $f14, $f14
; MIPS32R6-NEXT: min.s $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.s $f0, $f1, $f0
%z = call float @llvm.minimumnum.f32(float %x, float %y)
ret float %z
}
define float @minimumnum_float_nsz(float %x, float %y) {
; MIPS32R6-LABEL: minimumnum_float_nsz:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.s $f0, $f14, $f14
; MIPS32R6-NEXT: min.s $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.s $f0, $f1, $f0
%z = call nsz float @llvm.minimumnum.f32(float %x, float %y)
ret float %z
}
define float @minimumnum_float_nnan(float %x, float %y) {
; MIPS32R6-LABEL: minimumnum_float_nnan:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.s $f0, $f12, $f14
%z = call nnan float @llvm.minimumnum.f32(float %x, float %y)
ret float %z
}
define double @minimumnum_double(double %x, double %y) {
; MIPS32R6-LABEL: minimumnum_double:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.d $f0, $f14, $f14
; MIPS32R6-NEXT: min.d $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.d $f0, $f1, $f0
%z = call double @llvm.minimumnum.f64(double %x, double %y)
ret double %z
}
define double @minimumnum_double_nsz(double %x, double %y) {
; MIPS32R6-LABEL: minimumnum_double_nsz:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: min.d $f0, $f14, $f14
; MIPS32R6-NEXT: min.d $f1, $f12, $f12
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.d $f0, $f1, $f0
%z = call nsz double @llvm.minimumnum.f64(double %x, double %y)
ret double %z
}
define double @minimumnum_double_nnan(double %x, double %y) {
; MIPS32R6-LABEL: minimumnum_double_nnan:
; MIPS32R6: # %bb.0:
; MIPS32R6-NEXT: jr $ra
; MIPS32R6-NEXT: min.d $f0, $f12, $f14
%z = call nnan double @llvm.minimumnum.f64(double %x, double %y)
ret double %z
}