[llvm] MIPS: Fix llvm.{min,max}num for R6 (PR #93125)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Wed May 22 19:34:56 PDT 2024
https://github.com/wzssyqa created https://github.com/llvm/llvm-project/pull/93125
MIPS max.fmt/min.fmt instructions is IEEE2008 compatiable. If either argument is sNaN, the result will be NaN.
So we define fminnum_ieee instead of fminnum in Mips32r6InstrInfo.td. We also should define fcanonicalize. So that we can define fminnum as expand to fcanonicalize and fminnum_ieee.
>From 9bccb247227fe64c9e8666713b40198da93bcef1 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Thu, 23 May 2024 08:53:40 +0800
Subject: [PATCH] MIPS: Fix llvm.{min,max}num for R6
MIPS max.fmt/min.fmt instructions is IEEE2008 compatiable. If either
argument is sNaN, the result will be NaN.
So we define fminnum_ieee instead of fminnum in Mips32r6InstrInfo.td.
We also should define fcanonicalize. So that we can define fminnum
as expand to fcanonicalize and fminnum_ieee.
---
llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 14 +++--
llvm/lib/Target/Mips/MipsISelLowering.cpp | 14 +++--
llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll | 32 +++++++---
llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll | 73 ++++++++++++----------
4 files changed, 82 insertions(+), 51 deletions(-)
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index f609305bfee42..91ffbc4eb77dd 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -1119,18 +1119,24 @@ def : MipsPat<(select i32:$cond, immz, i32:$f),
// llvm.fmin/fmax operations.
let AdditionalPredicates = [NotInMicroMips] in {
- def : MipsPat<(fmaxnum f32:$lhs, f32:$rhs),
+ def : MipsPat<(fmaxnum_ieee f32:$lhs, f32:$rhs),
(MAX_S f32:$lhs, f32:$rhs)>,
ISA_MIPS32R6;
- def : MipsPat<(fmaxnum f64:$lhs, f64:$rhs),
+ def : MipsPat<(fmaxnum_ieee f64:$lhs, f64:$rhs),
(MAX_D f64:$lhs, f64:$rhs)>,
ISA_MIPS32R6;
- def : MipsPat<(fminnum f32:$lhs, f32:$rhs),
+ def : MipsPat<(fminnum_ieee f32:$lhs, f32:$rhs),
(MIN_S f32:$lhs, f32:$rhs)>,
ISA_MIPS32R6;
- def : MipsPat<(fminnum f64:$lhs, f64:$rhs),
+ def : MipsPat<(fminnum_ieee f64:$lhs, f64:$rhs),
(MIN_D f64:$lhs, f64:$rhs)>,
ISA_MIPS32R6;
+ def : MipsPat<(f32 (fcanonicalize f32:$src)),
+ (MIN_S f32:$src, f32:$src)>,
+ ISA_MIPS32R6;
+ def : MipsPat<(f64 (fcanonicalize f64:$src)),
+ (MIN_D f64:$src, f64:$src)>,
+ ISA_MIPS32R6;
}
// Pseudo instructions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 459164fa7a29d..c2be8c80b7a83 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -360,11 +360,15 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
// Lower fmin and fmax operations for MIPS R6.
// Instructions are defined but never used.
- if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {
- setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
- setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
- setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
- setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
+ if (Subtarget.hasMips32r6()) {
+ setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal);
+ setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);
+ setOperationAction(ISD::FMINNUM, MVT::f32, Expand);
+ setOperationAction(ISD::FMAXNUM, MVT::f32, Expand);
+ setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal);
+ setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
+ setOperationAction(ISD::FMINNUM, MVT::f64, Expand);
+ setOperationAction(ISD::FMAXNUM, MVT::f64, Expand);
}
if (Subtarget.isGP64bit()) {
diff --git a/llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll b/llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll
index e14e89916e6dc..2a0ad07474c09 100644
--- a/llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll
+++ b/llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll
@@ -6,13 +6,17 @@
define float @mins(float %x, float %y) {
; MIPS32R6EL-LABEL: mins
; MIPS32R6EL: # %bb.0:
+; MIPS32R6EL-NEXT: min.s $f0, $f14, $f14
+; MIPS32R6EL-NEXT: min.s $f1, $f12, $f12
; MIPS32R6EL-NEXT: jr $ra
-; MIPS32R6EL-NEXT: min.s $f0, $f12, $f14
+; MIPS32R6EL-NEXT: min.s $f0, $f1, $f0
;
; MIPS64R6EL-LABEL: mins
; MIPS64R6EL: # %bb.0:
+; MIPS64R6EL-NEXT: min.s $f0, $f13, $f13
+; MIPS64R6EL-NEXT: min.s $f1, $f12, $f12
; MIPS64R6EL-NEXT: jr $ra
-; MIPS64R6EL-NEXT: min.s $f0, $f12, $f13
+; MIPS64R6EL-NEXT: min.s $f0, $f1, $f0
%r = tail call float @llvm.minnum.f32(float %x, float %y)
ret float %r
@@ -21,13 +25,17 @@ define float @mins(float %x, float %y) {
define float @maxs(float %x, float %y) {
; MIPS32R6EL-LABEL: maxs
; MIPS32R6EL: # %bb.0:
+; MIPS32R6EL-NEXT: min.s $f0, $f14, $f14
+; MIPS32R6EL-NEXT: min.s $f1, $f12, $f12
; MIPS32R6EL-NEXT: jr $ra
-; MIPS32R6EL-NEXT: max.s $f0, $f12, $f14
+; MIPS32R6EL-NEXT: max.s $f0, $f1, $f0
;
; MIPS64R6EL-LABEL: maxs
; MIPS64R6EL: # %bb.0:
+; MIPS64R6EL-NEXT: min.s $f0, $f13, $f13
+; MIPS64R6EL-NEXT: min.s $f1, $f12, $f12
; MIPS64R6EL-NEXT: jr $ra
-; MIPS64R6EL-NEXT: max.s $f0, $f12, $f13
+; MIPS64R6EL-NEXT: max.s $f0, $f1, $f0
%r = tail call float @llvm.maxnum.f32(float %x, float %y)
ret float %r
@@ -36,13 +44,17 @@ define float @maxs(float %x, float %y) {
define double @mind(double %x, double %y) {
; MIPS32R6EL-LABEL: mind
; MIPS32R6EL: # %bb.0:
+; MIPS32R6EL-NEXT: min.d $f0, $f14, $f14
+; MIPS32R6EL-NEXT: min.d $f1, $f12, $f12
; MIPS32R6EL-NEXT: jr $ra
-; MIPS32R6EL-NEXT: min.d $f0, $f12, $f14
+; MIPS32R6EL-NEXT: min.d $f0, $f1, $f0
;
; MIPS64R6EL-LABEL: mind
; MIPS64R6EL: # %bb.0:
+; MIPS64R6EL-NEXT: min.d $f0, $f13, $f13
+; MIPS64R6EL-NEXT: min.d $f1, $f12, $f12
; MIPS64R6EL-NEXT: jr $ra
-; MIPS64R6EL-NEXT: min.d $f0, $f12, $f13
+; MIPS64R6EL-NEXT: min.d $f0, $f1, $f0
%r = tail call double @llvm.minnum.f64(double %x, double %y)
ret double %r
@@ -51,13 +63,17 @@ define double @mind(double %x, double %y) {
define double @maxd(double %x, double %y) {
; MIPS32R6EL-LABEL: maxd
; MIPS32R6EL: # %bb.0:
+; MIPS32R6EL-NEXT: min.d $f0, $f14, $f14
+; MIPS32R6EL-NEXT: min.d $f1, $f12, $f12
; MIPS32R6EL-NEXT: jr $ra
-; MIPS32R6EL-NEXT: max.d $f0, $f12, $f14
+; MIPS32R6EL-NEXT: max.d $f0, $f1, $f0
;
; MIPS64R6EL-LABEL: maxd
; MIPS64R6EL: # %bb.0:
+; MIPS64R6EL-NEXT: min.d $f0, $f13, $f13
+; MIPS64R6EL-NEXT: min.d $f1, $f12, $f12
; MIPS64R6EL-NEXT: jr $ra
-; MIPS64R6EL-NEXT: max.d $f0, $f12, $f13
+; MIPS64R6EL-NEXT: max.d $f0, $f1, $f0
%r = tail call double @llvm.maxnum.f64(double %x, double %y)
ret double %r
diff --git a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
index fe68bee408fc8..42b0f69181ab7 100644
--- a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
+++ b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
@@ -2466,13 +2466,14 @@ define void @fminnum(float %b) {
; MIPSR6-O32-NEXT: lui $2, %hi(_gp_disp)
; MIPSR6-O32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPSR6-O32-NEXT: addu $1, $2, $25
+; MIPSR6-O32-NEXT: min.s $f0, $f12, $f12
; MIPSR6-O32-NEXT: lw $1, %got(g)($1)
; MIPSR6-O32-NEXT: lh $2, 0($1)
-; MIPSR6-O32-NEXT: fill.h $w0, $2
-; MIPSR6-O32-NEXT: fexupr.w $w0, $w0
-; MIPSR6-O32-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-O32-NEXT: mtc1 $2, $f0
-; MIPSR6-O32-NEXT: min.s $f0, $f0, $f12
+; MIPSR6-O32-NEXT: fill.h $w1, $2
+; MIPSR6-O32-NEXT: fexupr.w $w1, $w1
+; MIPSR6-O32-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-O32-NEXT: mtc1 $2, $f1
+; MIPSR6-O32-NEXT: min.s $f0, $f1, $f0
; MIPSR6-O32-NEXT: mfc1 $2, $f0
; MIPSR6-O32-NEXT: fill.w $w0, $2
; MIPSR6-O32-NEXT: fexdo.h $w0, $w0, $w0
@@ -2485,13 +2486,14 @@ define void @fminnum(float %b) {
; MIPSR6-N32-NEXT: lui $1, %hi(%neg(%gp_rel(fminnum)))
; MIPSR6-N32-NEXT: addu $1, $1, $25
; MIPSR6-N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(fminnum)))
+; MIPSR6-N32-NEXT: min.s $f0, $f12, $f12
; MIPSR6-N32-NEXT: lw $1, %got_disp(g)($1)
; MIPSR6-N32-NEXT: lh $2, 0($1)
-; MIPSR6-N32-NEXT: fill.h $w0, $2
-; MIPSR6-N32-NEXT: fexupr.w $w0, $w0
-; MIPSR6-N32-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-N32-NEXT: mtc1 $2, $f0
-; MIPSR6-N32-NEXT: min.s $f0, $f0, $f12
+; MIPSR6-N32-NEXT: fill.h $w1, $2
+; MIPSR6-N32-NEXT: fexupr.w $w1, $w1
+; MIPSR6-N32-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-N32-NEXT: mtc1 $2, $f1
+; MIPSR6-N32-NEXT: min.s $f0, $f1, $f0
; MIPSR6-N32-NEXT: mfc1 $2, $f0
; MIPSR6-N32-NEXT: fill.w $w0, $2
; MIPSR6-N32-NEXT: fexdo.h $w0, $w0, $w0
@@ -2504,20 +2506,20 @@ define void @fminnum(float %b) {
; MIPSR6-N64-NEXT: lui $1, %hi(%neg(%gp_rel(fminnum)))
; MIPSR6-N64-NEXT: daddu $1, $1, $25
; MIPSR6-N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(fminnum)))
+; MIPSR6-N64-NEXT: min.s $f0, $f12, $f12
; MIPSR6-N64-NEXT: ld $1, %got_disp(g)($1)
; MIPSR6-N64-NEXT: lh $2, 0($1)
-; MIPSR6-N64-NEXT: fill.h $w0, $2
-; MIPSR6-N64-NEXT: fexupr.w $w0, $w0
-; MIPSR6-N64-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-N64-NEXT: mtc1 $2, $f0
-; MIPSR6-N64-NEXT: min.s $f0, $f0, $f12
+; MIPSR6-N64-NEXT: fill.h $w1, $2
+; MIPSR6-N64-NEXT: fexupr.w $w1, $w1
+; MIPSR6-N64-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-N64-NEXT: mtc1 $2, $f1
+; MIPSR6-N64-NEXT: min.s $f0, $f1, $f0
; MIPSR6-N64-NEXT: mfc1 $2, $f0
; MIPSR6-N64-NEXT: fill.w $w0, $2
; MIPSR6-N64-NEXT: fexdo.h $w0, $w0, $w0
; MIPSR6-N64-NEXT: copy_u.h $2, $w0[0]
; MIPSR6-N64-NEXT: jr $ra
; MIPSR6-N64-NEXT: sh $2, 0($1)
-;
entry:
%0 = load i16, ptr @g, align 2
%1 = call float @llvm.convert.from.fp16.f32(i16 %0)
@@ -2632,17 +2634,18 @@ define void @fmaxnum(float %b) {
; MIPS64R5-N64-NEXT: daddiu $sp, $sp, 32
;
; MIPSR6-O32-LABEL: fmaxnum:
-; MIPSR6-O32: # %bb.0:
+; MIPSR6-O32: # %bb.0: # %entry
; MIPSR6-O32-NEXT: lui $2, %hi(_gp_disp)
; MIPSR6-O32-NEXT: addiu $2, $2, %lo(_gp_disp)
; MIPSR6-O32-NEXT: addu $1, $2, $25
+; MIPSR6-O32-NEXT: min.s $f0, $f12, $f12
; MIPSR6-O32-NEXT: lw $1, %got(g)($1)
; MIPSR6-O32-NEXT: lh $2, 0($1)
-; MIPSR6-O32-NEXT: fill.h $w0, $2
-; MIPSR6-O32-NEXT: fexupr.w $w0, $w0
-; MIPSR6-O32-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-O32-NEXT: mtc1 $2, $f0
-; MIPSR6-O32-NEXT: max.s $f0, $f0, $f12
+; MIPSR6-O32-NEXT: fill.h $w1, $2
+; MIPSR6-O32-NEXT: fexupr.w $w1, $w1
+; MIPSR6-O32-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-O32-NEXT: mtc1 $2, $f1
+; MIPSR6-O32-NEXT: max.s $f0, $f1, $f0
; MIPSR6-O32-NEXT: mfc1 $2, $f0
; MIPSR6-O32-NEXT: fill.w $w0, $2
; MIPSR6-O32-NEXT: fexdo.h $w0, $w0, $w0
@@ -2651,17 +2654,18 @@ define void @fmaxnum(float %b) {
; MIPSR6-O32-NEXT: sh $2, 0($1)
;
; MIPSR6-N32-LABEL: fmaxnum:
-; MIPSR6-N32: # %bb.0:
+; MIPSR6-N32: # %bb.0: # %entry
; MIPSR6-N32-NEXT: lui $1, %hi(%neg(%gp_rel(fmaxnum)))
; MIPSR6-N32-NEXT: addu $1, $1, $25
; MIPSR6-N32-NEXT: addiu $1, $1, %lo(%neg(%gp_rel(fmaxnum)))
+; MIPSR6-N32-NEXT: min.s $f0, $f12, $f12
; MIPSR6-N32-NEXT: lw $1, %got_disp(g)($1)
; MIPSR6-N32-NEXT: lh $2, 0($1)
-; MIPSR6-N32-NEXT: fill.h $w0, $2
-; MIPSR6-N32-NEXT: fexupr.w $w0, $w0
-; MIPSR6-N32-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-N32-NEXT: mtc1 $2, $f0
-; MIPSR6-N32-NEXT: max.s $f0, $f0, $f12
+; MIPSR6-N32-NEXT: fill.h $w1, $2
+; MIPSR6-N32-NEXT: fexupr.w $w1, $w1
+; MIPSR6-N32-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-N32-NEXT: mtc1 $2, $f1
+; MIPSR6-N32-NEXT: max.s $f0, $f1, $f0
; MIPSR6-N32-NEXT: mfc1 $2, $f0
; MIPSR6-N32-NEXT: fill.w $w0, $2
; MIPSR6-N32-NEXT: fexdo.h $w0, $w0, $w0
@@ -2670,17 +2674,18 @@ define void @fmaxnum(float %b) {
; MIPSR6-N32-NEXT: sh $2, 0($1)
;
; MIPSR6-N64-LABEL: fmaxnum:
-; MIPSR6-N64: # %bb.0:
+; MIPSR6-N64: # %bb.0: # %entry
; MIPSR6-N64-NEXT: lui $1, %hi(%neg(%gp_rel(fmaxnum)))
; MIPSR6-N64-NEXT: daddu $1, $1, $25
; MIPSR6-N64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(fmaxnum)))
+; MIPSR6-N64-NEXT: min.s $f0, $f12, $f12
; MIPSR6-N64-NEXT: ld $1, %got_disp(g)($1)
; MIPSR6-N64-NEXT: lh $2, 0($1)
-; MIPSR6-N64-NEXT: fill.h $w0, $2
-; MIPSR6-N64-NEXT: fexupr.w $w0, $w0
-; MIPSR6-N64-NEXT: copy_s.w $2, $w0[0]
-; MIPSR6-N64-NEXT: mtc1 $2, $f0
-; MIPSR6-N64-NEXT: max.s $f0, $f0, $f12
+; MIPSR6-N64-NEXT: fill.h $w1, $2
+; MIPSR6-N64-NEXT: fexupr.w $w1, $w1
+; MIPSR6-N64-NEXT: copy_s.w $2, $w1[0]
+; MIPSR6-N64-NEXT: mtc1 $2, $f1
+; MIPSR6-N64-NEXT: max.s $f0, $f1, $f0
; MIPSR6-N64-NEXT: mfc1 $2, $f0
; MIPSR6-N64-NEXT: fill.w $w0, $2
; MIPSR6-N64-NEXT: fexdo.h $w0, $w0, $w0
More information about the llvm-commits
mailing list