[llvm] [MIPS] Fix the opcode of max.fmt and mina.fmt and make them matchable by ISel (PR #85609)
Cinhi Young via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 18 01:00:52 PDT 2024
https://github.com/Cyanoxygen updated https://github.com/llvm/llvm-project/pull/85609
>From e5e991b2accd7838bca6a753e35d846a2e46f45a Mon Sep 17 00:00:00 2001
From: Cyan <cyanoxygen at aosc.io>
Date: Wed, 13 Mar 2024 17:03:35 +0800
Subject: [PATCH 1/2] [MIPS] Fix the func opcode for mina.fmt and max.fmt
- The opcode of the mina.fmt and max.fmt is documented wrong, the
object code compiled from the same assembly with LLVM behaves
differently than one compiled with GCC and Binutils.
- Modify the opcodes to match Binutils. The actual opcodes are as follows:
{5,3}| bits {2,0} of func
| ... | 100 | 101 | 110 | 111
-----+-----+-----+-----+-----+-----
010 | ... | min | mina| max | maxa
---
llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 24 +++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index 9c29acbd0d8a88..f609305bfee429 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -153,15 +153,15 @@ class SELNEZ_ENC : SPECIAL_3R_FM<0b00000, 0b110111>;
class LWPC_ENC : PCREL19_FM<OPCODE2_LWPC>;
-class MAX_S_ENC : COP1_3R_FM<0b011101, FIELD_FMT_S>;
-class MAX_D_ENC : COP1_3R_FM<0b011101, FIELD_FMT_D>;
+class MAX_S_ENC : COP1_3R_FM<0b011110, FIELD_FMT_S>;
+class MAX_D_ENC : COP1_3R_FM<0b011110, FIELD_FMT_D>;
class MIN_S_ENC : COP1_3R_FM<0b011100, FIELD_FMT_S>;
class MIN_D_ENC : COP1_3R_FM<0b011100, FIELD_FMT_D>;
class MAXA_S_ENC : COP1_3R_FM<0b011111, FIELD_FMT_S>;
class MAXA_D_ENC : COP1_3R_FM<0b011111, FIELD_FMT_D>;
-class MINA_S_ENC : COP1_3R_FM<0b011110, FIELD_FMT_S>;
-class MINA_D_ENC : COP1_3R_FM<0b011110, FIELD_FMT_D>;
+class MINA_S_ENC : COP1_3R_FM<0b011101, FIELD_FMT_S>;
+class MINA_D_ENC : COP1_3R_FM<0b011101, FIELD_FMT_D>;
class SELEQZ_S_ENC : COP1_3R_FM<0b010100, FIELD_FMT_S>;
class SELEQZ_D_ENC : COP1_3R_FM<0b010100, FIELD_FMT_D>;
@@ -1117,6 +1117,22 @@ def : MipsPat<(select i32:$cond, immz, i32:$f),
ISA_MIPS32R6;
}
+// llvm.fmin/fmax operations.
+let AdditionalPredicates = [NotInMicroMips] in {
+ def : MipsPat<(fmaxnum f32:$lhs, f32:$rhs),
+ (MAX_S f32:$lhs, f32:$rhs)>,
+ ISA_MIPS32R6;
+ def : MipsPat<(fmaxnum f64:$lhs, f64:$rhs),
+ (MAX_D f64:$lhs, f64:$rhs)>,
+ ISA_MIPS32R6;
+ def : MipsPat<(fminnum f32:$lhs, f32:$rhs),
+ (MIN_S f32:$lhs, f32:$rhs)>,
+ ISA_MIPS32R6;
+ def : MipsPat<(fminnum f64:$lhs, f64:$rhs),
+ (MIN_D f64:$lhs, f64:$rhs)>,
+ ISA_MIPS32R6;
+}
+
// Pseudo instructions
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT], hasPostISelHook = 1 in {
>From e13fc65a584773be98606b8133fd0cd1237f187b Mon Sep 17 00:00:00 2001
From: Cyan <cyanoxygen at aosc.io>
Date: Mon, 18 Mar 2024 15:29:11 +0800
Subject: [PATCH 2/2] [MIPS] match llvm.{min,max}num with {min,max}.fmt for R6
- The behavior is similar to UCOMISD on x86, which is also used to
compare two fp values, specifically on handling of NaNs.
---
llvm/lib/Target/Mips/MipsISelLowering.cpp | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 7e5f148e7bf4e7..3cdbdbf3ccd099 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -358,6 +358,15 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ // Lower fmin and fmax operations for MIPS R6.
+ // Instructions are defined but never used.
+ if (Subtarget.hasMips32r6()) {
+ 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.isGP64bit()) {
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
setOperationAction(ISD::BlockAddress, MVT::i64, Custom);
More information about the llvm-commits
mailing list