[llvm] [mips][micromips] Add mayRaiseFPException to appropriate instructions, mark all instructions that read FCSR (FCR31) rounding bits as doing so (PR #170322)
Erik Enikeev via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 2 08:32:02 PST 2025
https://github.com/Varnike created https://github.com/llvm/llvm-project/pull/170322
None
>From 48e11800ce7a37cd2ab4cb01e6fb66c6c6d1971f Mon Sep 17 00:00:00 2001
From: Erik Enikeev <evonatarius at gmail.com>
Date: Thu, 18 Sep 2025 15:06:09 +0300
Subject: [PATCH] [mips][micromips] Add mayRaiseFPException to appropriate
instructions, mark all instructions that read FCSR (FCR31) rounding bits as
doing so
---
.../lib/Target/Mips/MicroMips32r6InstrInfo.td | 233 +++++++++--------
llvm/lib/Target/Mips/MicroMipsInstrFPU.td | 243 ++++++++++--------
llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 120 +++++----
llvm/lib/Target/Mips/MipsInstrFPU.td | 152 ++++++-----
llvm/lib/Target/Mips/MipsRegisterInfo.cpp | 2 +
.../float_arithmetic_operations.mir | 184 +++++++------
.../instruction-select/fpext_and_fptrunc.mir | 38 +--
.../GlobalISel/instruction-select/fsqrt.mir | 38 +--
.../instruction-select/sitofp_and_uitofp.mir | 77 +++---
llvm/test/CodeGen/Mips/fp-strict-fp-ops.ll | 110 ++++++++
10 files changed, 706 insertions(+), 491 deletions(-)
create mode 100644 llvm/test/CodeGen/Mips/fp-strict-fp-ops.ll
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index 197cd8ac5579b..dc47f1d3d9dad 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -976,38 +976,41 @@ multiclass CMP_CC_MMR6<bits<6> format, string Typestr,
!strconcat("cmp.ule.", Typestr), format, FIELD_CMP_COND_ULE>,
CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, Itin, setule>, HARDFLOAT,
ISA_MICROMIPS32R6;
- def CMP_SAF_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.saf.", Typestr), format, FIELD_CMP_COND_SAF>,
- CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SUN_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.sun.", Typestr), format, FIELD_CMP_COND_SUN>,
- CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SEQ_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.seq.", Typestr), format, FIELD_CMP_COND_SEQ>,
- CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SUEQ_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.sueq.", Typestr), format, FIELD_CMP_COND_SUEQ>,
- CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SLT_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.slt.", Typestr), format, FIELD_CMP_COND_SLT>,
- CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SULT_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.sult.", Typestr), format, FIELD_CMP_COND_SULT>,
- CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SLE_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.sle.", Typestr), format, FIELD_CMP_COND_SLE>,
- CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
- def CMP_SULE_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
- !strconcat("cmp.sule.", Typestr), format, FIELD_CMP_COND_SULE>,
- CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd, Itin>, HARDFLOAT,
- ISA_MICROMIPS32R6;
+
+ let mayRaiseFPException = 1 in {
+ def CMP_SAF_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.saf.", Typestr), format, FIELD_CMP_COND_SAF>,
+ CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SUN_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.sun.", Typestr), format, FIELD_CMP_COND_SUN>,
+ CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SEQ_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.seq.", Typestr), format, FIELD_CMP_COND_SEQ>,
+ CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SUEQ_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.sueq.", Typestr), format, FIELD_CMP_COND_SUEQ>,
+ CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SLT_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.slt.", Typestr), format, FIELD_CMP_COND_SLT>,
+ CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SULT_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.sult.", Typestr), format, FIELD_CMP_COND_SULT>,
+ CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SLE_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.sle.", Typestr), format, FIELD_CMP_COND_SLE>,
+ CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ def CMP_SULE_#NAME : R6MMR6Rel, POOL32F_CMP_FM<
+ !strconcat("cmp.sule.", Typestr), format, FIELD_CMP_COND_SULE>,
+ CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd, Itin>, HARDFLOAT,
+ ISA_MICROMIPS32R6;
+ }
}
class ABSS_FT_MMR6_DESC_BASE<string instr_asm, RegisterOperand DstRC,
@@ -1453,78 +1456,90 @@ let DecoderMethod = "DecodeMemMMImm16" in {
def SW_MMR6 : StdMMR6Rel, SW_MMR6_DESC, SW_MMR6_ENC, ISA_MICROMIPS32R6;
}
/// Floating Point Instructions
-def FADD_S_MMR6 : StdMMR6Rel, FADD_S_MMR6_ENC, FADD_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FSUB_S_MMR6 : StdMMR6Rel, FSUB_S_MMR6_ENC, FSUB_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FMUL_S_MMR6 : StdMMR6Rel, FMUL_S_MMR6_ENC, FMUL_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FDIV_S_MMR6 : StdMMR6Rel, FDIV_S_MMR6_ENC, FDIV_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MADDF_S_MMR6 : R6MMR6Rel, MADDF_S_MMR6_ENC, MADDF_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MADDF_D_MMR6 : R6MMR6Rel, MADDF_D_MMR6_ENC, MADDF_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MSUBF_S_MMR6 : R6MMR6Rel, MSUBF_S_MMR6_ENC, MSUBF_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MSUBF_D_MMR6 : R6MMR6Rel, MSUBF_D_MMR6_ENC, MSUBF_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
+let mayRaiseFPException = 1, Uses = [FCR31] in {
+ def FADD_S_MMR6 : StdMMR6Rel, FADD_S_MMR6_ENC, FADD_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FSUB_S_MMR6 : StdMMR6Rel, FSUB_S_MMR6_ENC, FSUB_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FMUL_S_MMR6 : StdMMR6Rel, FMUL_S_MMR6_ENC, FMUL_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FDIV_S_MMR6 : StdMMR6Rel, FDIV_S_MMR6_ENC, FDIV_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def MADDF_S_MMR6 : R6MMR6Rel, MADDF_S_MMR6_ENC, MADDF_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def MADDF_D_MMR6 : R6MMR6Rel, MADDF_D_MMR6_ENC, MADDF_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def MSUBF_S_MMR6 : R6MMR6Rel, MSUBF_S_MMR6_ENC, MSUBF_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def MSUBF_D_MMR6 : R6MMR6Rel, MSUBF_D_MMR6_ENC, MSUBF_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+}
+
def FMOV_S_MMR6 : StdMMR6Rel, FMOV_S_MMR6_ENC, FMOV_S_MMR6_DESC,
ISA_MICROMIPS32R6;
def FMOV_D_MMR6 : StdMMR6Rel, FMOV_D_MMR6_ENC, FMOV_D_MMR6_DESC,
ISA_MICROMIPS32R6;
def FNEG_S_MMR6 : StdMMR6Rel, FNEG_S_MMR6_ENC, FNEG_S_MMR6_DESC,
ISA_MICROMIPS32R6;
-def MAX_S_MMR6 : R6MMR6Rel, MAX_S_MMR6_ENC, MAX_S_MMR6_DESC, ISA_MICROMIPS32R6;
-def MAX_D_MMR6 : R6MMR6Rel, MAX_D_MMR6_ENC, MAX_D_MMR6_DESC, ISA_MICROMIPS32R6;
-def MIN_S_MMR6 : R6MMR6Rel, MIN_S_MMR6_ENC, MIN_S_MMR6_DESC, ISA_MICROMIPS32R6;
-def MIN_D_MMR6 : R6MMR6Rel, MIN_D_MMR6_ENC, MIN_D_MMR6_DESC, ISA_MICROMIPS32R6;
-def MAXA_S_MMR6 : R6MMR6Rel, MAXA_S_MMR6_ENC, MAXA_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MAXA_D_MMR6 : R6MMR6Rel, MAXA_D_MMR6_ENC, MAXA_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MINA_S_MMR6 : R6MMR6Rel, MINA_S_MMR6_ENC, MINA_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def MINA_D_MMR6 : R6MMR6Rel, MINA_D_MMR6_ENC, MINA_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_L_S_MMR6 : StdMMR6Rel, CVT_L_S_MMR6_ENC, CVT_L_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_L_D_MMR6 : StdMMR6Rel, CVT_L_D_MMR6_ENC, CVT_L_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_W_S_MMR6 : StdMMR6Rel, CVT_W_S_MMR6_ENC, CVT_W_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_D_L_MMR6 : StdMMR6Rel, CVT_D_L_MMR6_ENC, CVT_D_L_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_S_W_MMR6 : StdMMR6Rel, CVT_S_W_MMR6_ENC, CVT_S_W_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CVT_S_L_MMR6 : StdMMR6Rel, CVT_S_L_MMR6_ENC, CVT_S_L_MMR6_DESC,
- ISA_MICROMIPS32R6;
-defm S_MMR6 : CMP_CC_MMR6<0b000101, "s", FGR32Opnd, II_CMP_CC_S>;
-defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGR64Opnd, II_CMP_CC_D>;
-def FLOOR_L_S_MMR6 : StdMMR6Rel, FLOOR_L_S_MMR6_ENC, FLOOR_L_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FLOOR_L_D_MMR6 : StdMMR6Rel, FLOOR_L_D_MMR6_ENC, FLOOR_L_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FLOOR_W_S_MMR6 : StdMMR6Rel, FLOOR_W_S_MMR6_ENC, FLOOR_W_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def FLOOR_W_D_MMR6 : StdMMR6Rel, FLOOR_W_D_MMR6_ENC, FLOOR_W_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def CEIL_L_S_MMR6 : StdMMR6Rel, CEIL_L_S_MMR6_ENC, CEIL_L_S_MMR6_DESC,
+
+let mayRaiseFPException = 1 in {
+ def MAX_S_MMR6 : R6MMR6Rel, MAX_S_MMR6_ENC, MAX_S_MMR6_DESC, ISA_MICROMIPS32R6;
+ def MAX_D_MMR6 : R6MMR6Rel, MAX_D_MMR6_ENC, MAX_D_MMR6_DESC, ISA_MICROMIPS32R6;
+ def MIN_S_MMR6 : R6MMR6Rel, MIN_S_MMR6_ENC, MIN_S_MMR6_DESC, ISA_MICROMIPS32R6;
+ def MIN_D_MMR6 : R6MMR6Rel, MIN_D_MMR6_ENC, MIN_D_MMR6_DESC, ISA_MICROMIPS32R6;
+ def MAXA_S_MMR6 : R6MMR6Rel, MAXA_S_MMR6_ENC, MAXA_S_MMR6_DESC,
ISA_MICROMIPS32R6;
-def CEIL_L_D_MMR6 : StdMMR6Rel, CEIL_L_D_MMR6_ENC, CEIL_L_D_MMR6_DESC,
+ def MAXA_D_MMR6 : R6MMR6Rel, MAXA_D_MMR6_ENC, MAXA_D_MMR6_DESC,
ISA_MICROMIPS32R6;
-def CEIL_W_S_MMR6 : StdMMR6Rel, CEIL_W_S_MMR6_ENC, CEIL_W_S_MMR6_DESC,
+ def MINA_S_MMR6 : R6MMR6Rel, MINA_S_MMR6_ENC, MINA_S_MMR6_DESC,
ISA_MICROMIPS32R6;
-def CEIL_W_D_MMR6 : StdMMR6Rel, CEIL_W_D_MMR6_ENC, CEIL_W_D_MMR6_DESC,
+ def MINA_D_MMR6 : R6MMR6Rel, MINA_D_MMR6_ENC, MINA_D_MMR6_DESC,
ISA_MICROMIPS32R6;
-def TRUNC_L_S_MMR6 : StdMMR6Rel, TRUNC_L_S_MMR6_ENC, TRUNC_L_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def TRUNC_L_D_MMR6 : StdMMR6Rel, TRUNC_L_D_MMR6_ENC, TRUNC_L_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def TRUNC_W_S_MMR6 : StdMMR6Rel, TRUNC_W_S_MMR6_ENC, TRUNC_W_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def TRUNC_W_D_MMR6 : StdMMR6Rel, TRUNC_W_D_MMR6_ENC, TRUNC_W_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
+
+ let Uses = [FCR31] in {
+ def CVT_L_S_MMR6 : StdMMR6Rel, CVT_L_S_MMR6_ENC, CVT_L_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CVT_L_D_MMR6 : StdMMR6Rel, CVT_L_D_MMR6_ENC, CVT_L_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CVT_W_S_MMR6 : StdMMR6Rel, CVT_W_S_MMR6_ENC, CVT_W_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CVT_D_L_MMR6 : StdMMR6Rel, CVT_D_L_MMR6_ENC, CVT_D_L_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CVT_S_W_MMR6 : StdMMR6Rel, CVT_S_W_MMR6_ENC, CVT_S_W_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CVT_S_L_MMR6 : StdMMR6Rel, CVT_S_L_MMR6_ENC, CVT_S_L_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ }
+}
+
+defm S_MMR6 : CMP_CC_MMR6<0b000101, "s", FGR32Opnd, II_CMP_CC_S>;
+defm D_MMR6 : CMP_CC_MMR6<0b010101, "d", FGR64Opnd, II_CMP_CC_D>;
+let mayRaiseFPException = 1 in {
+ def FLOOR_L_S_MMR6 : StdMMR6Rel, FLOOR_L_S_MMR6_ENC, FLOOR_L_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FLOOR_L_D_MMR6 : StdMMR6Rel, FLOOR_L_D_MMR6_ENC, FLOOR_L_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FLOOR_W_S_MMR6 : StdMMR6Rel, FLOOR_W_S_MMR6_ENC, FLOOR_W_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def FLOOR_W_D_MMR6 : StdMMR6Rel, FLOOR_W_D_MMR6_ENC, FLOOR_W_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CEIL_L_S_MMR6 : StdMMR6Rel, CEIL_L_S_MMR6_ENC, CEIL_L_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CEIL_L_D_MMR6 : StdMMR6Rel, CEIL_L_D_MMR6_ENC, CEIL_L_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CEIL_W_S_MMR6 : StdMMR6Rel, CEIL_W_S_MMR6_ENC, CEIL_W_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def CEIL_W_D_MMR6 : StdMMR6Rel, CEIL_W_D_MMR6_ENC, CEIL_W_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def TRUNC_L_S_MMR6 : StdMMR6Rel, TRUNC_L_S_MMR6_ENC, TRUNC_L_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def TRUNC_L_D_MMR6 : StdMMR6Rel, TRUNC_L_D_MMR6_ENC, TRUNC_L_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def TRUNC_W_S_MMR6 : StdMMR6Rel, TRUNC_W_S_MMR6_ENC, TRUNC_W_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def TRUNC_W_D_MMR6 : StdMMR6Rel, TRUNC_W_D_MMR6_ENC, TRUNC_W_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+}
def SB_MMR6 : StdMMR6Rel, SB_MMR6_DESC, SB_MMR6_ENC, ISA_MICROMIPS32R6;
def SH_MMR6 : StdMMR6Rel, SH_MMR6_DESC, SH_MMR6_ENC, ISA_MICROMIPS32R6;
def LW_MMR6 : StdMMR6Rel, LW_MMR6_DESC, LW_MMR6_ENC, ISA_MICROMIPS32R6;
@@ -1562,18 +1577,24 @@ def JALRC_HB_MMR6 : R6MMR6Rel, JALRC_HB_MMR6_ENC, JALRC_HB_MMR6_DESC,
def EXT_MMR6 : StdMMR6Rel, EXT_MMR6_ENC, EXT_MMR6_DESC, ISA_MICROMIPS32R6;
def INS_MMR6 : StdMMR6Rel, INS_MMR6_ENC, INS_MMR6_DESC, ISA_MICROMIPS32R6;
def JALRC_MMR6 : R6MMR6Rel, JALRC_MMR6_ENC, JALRC_MMR6_DESC, ISA_MICROMIPS32R6;
-def RINT_S_MMR6 : StdMMR6Rel, RINT_S_MMR6_ENC, RINT_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def RINT_D_MMR6 : StdMMR6Rel, RINT_D_MMR6_ENC, RINT_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def ROUND_L_S_MMR6 : StdMMR6Rel, ROUND_L_S_MMR6_ENC, ROUND_L_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def ROUND_L_D_MMR6 : StdMMR6Rel, ROUND_L_D_MMR6_ENC, ROUND_L_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def ROUND_W_S_MMR6 : StdMMR6Rel, ROUND_W_S_MMR6_ENC, ROUND_W_S_MMR6_DESC,
- ISA_MICROMIPS32R6;
-def ROUND_W_D_MMR6 : StdMMR6Rel, ROUND_W_D_MMR6_ENC, ROUND_W_D_MMR6_DESC,
- ISA_MICROMIPS32R6;
+
+let mayRaiseFPException = 1 in {
+ let Uses = [FCR31] in {
+ def RINT_S_MMR6 : StdMMR6Rel, RINT_S_MMR6_ENC, RINT_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def RINT_D_MMR6 : StdMMR6Rel, RINT_D_MMR6_ENC, RINT_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ }
+ def ROUND_L_S_MMR6 : StdMMR6Rel, ROUND_L_S_MMR6_ENC, ROUND_L_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def ROUND_L_D_MMR6 : StdMMR6Rel, ROUND_L_D_MMR6_ENC, ROUND_L_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def ROUND_W_S_MMR6 : StdMMR6Rel, ROUND_W_S_MMR6_ENC, ROUND_W_S_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+ def ROUND_W_D_MMR6 : StdMMR6Rel, ROUND_W_D_MMR6_ENC, ROUND_W_D_MMR6_DESC,
+ ISA_MICROMIPS32R6;
+}
+
def SEL_S_MMR6 : R6MMR6Rel, SEL_S_MMR6_ENC, SEL_S_MMR6_DESC, ISA_MICROMIPS32R6;
def SEL_D_MMR6 : R6MMR6Rel, SEL_D_MMR6_ENC, SEL_D_MMR6_DESC, ISA_MICROMIPS32R6;
def SELEQZ_S_MMR6 : R6MMR6Rel, SELEQZ_S_MMR6_ENC, SELEQZ_S_MMR6_DESC,
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index d5fc30cef695c..22890dc35baa3 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
@@ -22,23 +22,25 @@ multiclass ADDS_MMM<string opstr, InstrItinClass Itin, bit IsComm,
}
}
-def FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>,
- ADDS_FM_MM<0, 0x30>, ISA_MICROMIPS;
-def FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>,
- ADDS_FM_MM<0, 0xf0>, ISA_MICROMIPS;
-def FMUL_S_MM : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>,
- ADDS_FM_MM<0, 0xb0>, ISA_MICROMIPS;
-def FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>,
- ADDS_FM_MM<0, 0x70>, ISA_MICROMIPS;
-
-defm FADD : ADDS_MMM<"add.d", II_ADD_D, 1, fadd>,
- ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS;
-defm FDIV : ADDS_MMM<"div.d", II_DIV_D, 0, fdiv>,
- ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS;
-defm FMUL : ADDS_MMM<"mul.d", II_MUL_D, 1, fmul>,
- ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS;
-defm FSUB : ADDS_MMM<"sub.d", II_SUB_D, 0, fsub>,
- ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS;
+let mayRaiseFPException = 1, Uses = [FCR31] in {
+ def FADD_S_MM : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, fadd>,
+ ADDS_FM_MM<0, 0x30>, ISA_MICROMIPS;
+ def FDIV_S_MM : MMRel, ADDS_FT<"div.s", FGR32Opnd, II_DIV_S, 0, fdiv>,
+ ADDS_FM_MM<0, 0xf0>, ISA_MICROMIPS;
+ def FMUL_S_MM : MMRel, ADDS_FT<"mul.s", FGR32Opnd, II_MUL_S, 1, fmul>,
+ ADDS_FM_MM<0, 0xb0>, ISA_MICROMIPS;
+ def FSUB_S_MM : MMRel, ADDS_FT<"sub.s", FGR32Opnd, II_SUB_S, 0, fsub>,
+ ADDS_FM_MM<0, 0x70>, ISA_MICROMIPS;
+
+ defm FADD : ADDS_MMM<"add.d", II_ADD_D, 1, fadd>,
+ ADDS_FM_MM<1, 0x30>, ISA_MICROMIPS;
+ defm FDIV : ADDS_MMM<"div.d", II_DIV_D, 0, fdiv>,
+ ADDS_FM_MM<1, 0xf0>, ISA_MICROMIPS;
+ defm FMUL : ADDS_MMM<"mul.d", II_MUL_D, 1, fmul>,
+ ADDS_FM_MM<1, 0xb0>, ISA_MICROMIPS;
+ defm FSUB : ADDS_MMM<"sub.d", II_SUB_D, 0, fsub>,
+ ADDS_FM_MM<1, 0x70>, ISA_MICROMIPS;
+}
let DecoderNamespace = "MicroMips" in {
def LWXC1_MM : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>,
@@ -75,11 +77,13 @@ let DecoderNamespace = "MicroMips" in {
BC1F_FM_MM<0x1c>, ISA_MICROMIPS32_NOT_MIPS32R6;
def BC1T_MM : MMRel, BC1F_FT<"bc1t", brtarget_mm, II_BC1T, MIPS_BRANCH_T>,
BC1F_FM_MM<0x1d>, ISA_MICROMIPS32_NOT_MIPS32R6;
+
+ let mayRaiseFPException = 1, Uses = [FCR31] in
def CVT_W_S_MM : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
ROUND_W_FM_MM<0, 0x24>, ISA_MICROMIPS;
}
-let DecoderNamespace = "MicroMips" in {
+let DecoderNamespace = "MicroMips", mayRaiseFPException = 1 in {
def ROUND_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"round.w.s", FGR32Opnd,
FGR32Opnd, II_ROUND>,
ROUND_W_FM_MM<0, 0xec>, ISA_MICROMIPS;
@@ -94,15 +98,17 @@ let DecoderNamespace = "MicroMips" in {
def TRUNC_W_MM : MMRel, ABSS_FT<"trunc.w.d", FGR32Opnd, AFGR64Opnd, II_TRUNC>,
ROUND_W_FM_MM<1, 0xac>, ISA_MICROMIPS, FGR_32;
- def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>,
- ROUND_W_FM_MM<0, 0x4>, ISA_MICROMIPS, FGR_64;
- def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>,
- ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64;
+ let Uses = [FCR31] in {
+ def CVT_L_S_MM : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>,
+ ROUND_W_FM_MM<0, 0x4>, ISA_MICROMIPS, FGR_64;
+ def CVT_L_D64_MM : MMRel, ABSS_FT<"cvt.l.d", FGR64Opnd, FGR64Opnd, II_CVT>,
+ ROUND_W_FM_MM<1, 0x4>, ISA_MICROMIPS, FGR_64;
- def CVT_W_D32_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
- ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32;
+ def CVT_W_D32_MM : MMRel, ABSS_FT<"cvt.w.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
+ ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_32;
+ }
}
-let DecoderNamespace = "MicroMipsFP64" in {
+let DecoderNamespace = "MicroMipsFP64", mayRaiseFPException = 1, Uses = [FCR31] in {
def CVT_W_D64_MM : ABSS_FT<"cvt.w.d", FGR32Opnd, FGR64Opnd, II_CVT>,
ROUND_W_FM_MM<1, 0x24>, ISA_MICROMIPS, FGR_64;
}
@@ -119,6 +125,7 @@ multiclass ABSS_MMM<string opstr, InstrItinClass Itin,
}
}
+let mayRaiseFPException = 1, Uses = [FCR31] in
defm FSQRT : ABSS_MMM<"sqrt.d", II_SQRT_D, fsqrt>, ROUND_W_FM_MM<1, 0x28>;
defm FABS : ABSS_MMM<"abs.d", II_SQRT_D, fabs>, ABS_FM_MM<1, 0xd>;
@@ -134,14 +141,14 @@ def FMOV_S_MM : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>,
def FNEG_S_MM : MMRel, ABSS_FT<"neg.s", FGR32Opnd, FGR32Opnd, II_NEG, fneg>,
ABS_FM_MM<0, 0x2d>, ISA_MICROMIPS;
-let DecoderNamespace = "MicroMips" in {
+let DecoderNamespace = "MicroMips", mayRaiseFPException = 1, Uses = [FCR31] in {
def CVT_D32_S_MM : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_32;
def CVT_D32_W_MM : MMRel, ABSS_FT<"cvt.d.w", AFGR64Opnd, FGR32Opnd, II_CVT>,
ABS_FM_MM<1, 0x4d>, ISA_MICROMIPS, FGR_32;
}
-let DecoderNamespace = "MicroMipsFP64" in {
+let DecoderNamespace = "MicroMipsFP64", mayRaiseFPException = 1, Uses = [FCR31] in {
def CVT_D64_S_MM : ABSS_FT<"cvt.d.s", FGR64Opnd, FGR32Opnd, II_CVT>,
ABS_FM_MM<0, 0x4d>, ISA_MICROMIPS, FGR_64;
def CVT_D64_W_MM : ABSS_FT<"cvt.d.w", FGR64Opnd, FGR32Opnd, II_CVT>,
@@ -150,7 +157,7 @@ let DecoderNamespace = "MicroMipsFP64" in {
ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_64;
}
-let DecoderNamespace = "MicroMips" in {
+let DecoderNamespace = "MicroMips", mayRaiseFPException = 1, Uses = [FCR31] in {
def CVT_S_D32_MM : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
ABS_FM_MM<0, 0x6d>, ISA_MICROMIPS, FGR_32;
def CVT_S_W_MM : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>,
@@ -194,41 +201,44 @@ let DecoderNamespace = "MicroMips" in {
def MTC1_MM : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd,
II_MTC1, bitconvert>, MFC1_FM_MM<0xa0>,
ISA_MICROMIPS;
-
- def MADD_S_MM : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S>,
- MADDS_FM_MM<0x1>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4;
- def MSUB_S_MM : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S>,
- MADDS_FM_MM<0x21>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4;
- let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in {
- def NMADD_S_MM : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S>,
- MADDS_FM_MM<0x2>, ISA_MICROMIPS32_NOT_MIPS32R6;
- def NMSUB_S_MM : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S>,
- MADDS_FM_MM<0x22>, ISA_MICROMIPS32_NOT_MIPS32R6;
- }
- def MADD_D32_MM : MMRel, MADDS_FT<"madd.d", AFGR64Opnd, II_MADD_D>,
- MADDS_FM_MM<0x9>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32,
- MADD4;
- def MSUB_D32_MM : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D>,
- MADDS_FM_MM<0x29>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32,
- MADD4;
- let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in {
- def NMADD_D32_MM : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D>,
- MADDS_FM_MM<0xa>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
- def NMSUB_D32_MM : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D>,
- MADDS_FM_MM<0x2a>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
+ let mayRaiseFPException = 1, Uses = [FCR31] in {
+ def MADD_S_MM : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S>,
+ MADDS_FM_MM<0x1>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4;
+ def MSUB_S_MM : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S>,
+ MADDS_FM_MM<0x21>, ISA_MICROMIPS32_NOT_MIPS32R6, MADD4;
+ def MADD_D32_MM : MMRel, MADDS_FT<"madd.d", AFGR64Opnd, II_MADD_D>,
+ MADDS_FM_MM<0x9>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32,
+ MADD4;
+ def MSUB_D32_MM : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D>,
+ MADDS_FM_MM<0x29>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32,
+ MADD4;
+
+ let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in {
+ def NMADD_S_MM : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S>,
+ MADDS_FM_MM<0x2>, ISA_MICROMIPS32_NOT_MIPS32R6;
+ def NMSUB_S_MM : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S>,
+ MADDS_FM_MM<0x22>, ISA_MICROMIPS32_NOT_MIPS32R6;
+ def NMADD_D32_MM : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D>,
+ MADDS_FM_MM<0xa>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
+ def NMSUB_D32_MM : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D>,
+ MADDS_FM_MM<0x2a>, ISA_MICROMIPS32_NOT_MIPS32R6, FGR_32;
+ }
}
- def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd,
- II_FLOOR>, ROUND_W_FM_MM<0, 0x2c>,
- ISA_MICROMIPS;
- def TRUNC_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd,
- FGR32Opnd, II_TRUNC>,
- ROUND_W_FM_MM<0, 0xac>, ISA_MICROMIPS;
- def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
- ROUND_W_FM_MM<0, 0x6c>, ISA_MICROMIPS;
+ let mayRaiseFPException = 1 in {
+ def FLOOR_W_S_MM : MMRel, ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd,
+ II_FLOOR>, ROUND_W_FM_MM<0, 0x2c>,
+ ISA_MICROMIPS;
+ def TRUNC_W_S_MM : MMRel, StdMMR6Rel, ABSS_FT<"trunc.w.s", FGR32Opnd,
+ FGR32Opnd, II_TRUNC>,
+ ROUND_W_FM_MM<0, 0xac>, ISA_MICROMIPS;
+ def CEIL_W_S_MM : MMRel, ABSS_FT<"ceil.w.s", FGR32Opnd, FGR32Opnd, II_CEIL>,
+ ROUND_W_FM_MM<0, 0x6c>, ISA_MICROMIPS;
+ let Uses = [FCR31] in
+ def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S,
+ fsqrt>, ROUND_W_FM_MM<0, 0x28>, ISA_MICROMIPS;
+ }
- def FSQRT_S_MM : MMRel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd, II_SQRT_S,
- fsqrt>, ROUND_W_FM_MM<0, 0x28>, ISA_MICROMIPS;
def MTHC1_D32_MM : MMRel,
MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>,
@@ -251,30 +261,33 @@ let DecoderNamespace = "MicroMips" in {
MFC1_FM_MM<0x40>, ISA_MICROMIPS;
def CTC1_MM : MMRel, MTC1_FT<"ctc1", CCROpnd, GPR32Opnd, II_CTC1>,
MFC1_FM_MM<0x60>, ISA_MICROMIPS;
- def RECIP_S_MM : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd,
+
+ let mayRaiseFPException = 1, Uses = [FCR31] in {
+ def RECIP_S_MM : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd,
+ II_RECIP_S>,
+ ROUND_W_FM_MM<0b0, 0b01001000>, ISA_MICROMIPS;
+ def RECIP_D32_MM : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_32 {
+ let BaseOpcode = "RECIP_D32";
+ }
+ let DecoderNamespace = "MicroMipsFP64" in
+ def RECIP_D64_MM : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_64;
+ def RSQRT_S_MM : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd,
II_RECIP_S>,
- ROUND_W_FM_MM<0b0, 0b01001000>, ISA_MICROMIPS;
- def RECIP_D32_MM : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd,
+ ROUND_W_FM_MM<0b0, 0b00001000>, ISA_MICROMIPS;
+ def RSQRT_D32_MM : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd,
II_RECIP_D>,
- ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_32 {
- let BaseOpcode = "RECIP_D32";
+ ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_32 {
+ let BaseOpcode = "RSQRT_D32";
+ }
+ let DecoderNamespace = "MicroMipsFP64" in
+ def RSQRT_D64_MM : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
+ II_RECIP_D>,
+ ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_64;
}
- let DecoderNamespace = "MicroMipsFP64" in
- def RECIP_D64_MM : MMRel, ABSS_FT<"recip.d", FGR64Opnd, FGR64Opnd,
- II_RECIP_D>,
- ROUND_W_FM_MM<0b1, 0b01001000>, ISA_MICROMIPS, FGR_64;
- def RSQRT_S_MM : MMRel, ABSS_FT<"rsqrt.s", FGR32Opnd, FGR32Opnd,
- II_RECIP_S>,
- ROUND_W_FM_MM<0b0, 0b00001000>, ISA_MICROMIPS;
- def RSQRT_D32_MM : MMRel, ABSS_FT<"rsqrt.d", AFGR64Opnd, AFGR64Opnd,
- II_RECIP_D>,
- ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_32 {
- let BaseOpcode = "RSQRT_D32";
- }
- let DecoderNamespace = "MicroMipsFP64" in
- def RSQRT_D64_MM : MMRel, ABSS_FT<"rsqrt.d", FGR64Opnd, FGR64Opnd,
- II_RECIP_D>,
- ROUND_W_FM_MM<0b1, 0b00001000>, ISA_MICROMIPS, FGR_64;
}
let DecoderNamespace = "MicroMips", DecoderMethod = "DecodeFMemMMR2" in {
@@ -342,39 +355,41 @@ multiclass C_COND_MM<string TypeStr, RegisterOperand RC, bits<2> fmt,
C_COND_FM_MM<fmt, 7> {
let BaseOpcode = "c.ule."#NAME;
}
- def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 8> {
- let BaseOpcode = "c.sf."#NAME;
- let isCommutable = 1;
- }
- def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 9> {
- let BaseOpcode = "c.ngle."#NAME;
- }
- def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 10> {
- let BaseOpcode = "c.seq."#NAME;
- let isCommutable = 1;
- }
- def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 11> {
- let BaseOpcode = "c.ngl."#NAME;
- }
- def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 12> {
- let BaseOpcode = "c.lt."#NAME;
- }
- def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 13> {
- let BaseOpcode = "c.nge."#NAME;
- }
- def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 14> {
- let BaseOpcode = "c.le."#NAME;
- }
- def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
- C_COND_FM_MM<fmt, 15> {
- let BaseOpcode = "c.ngt."#NAME;
+ let mayRaiseFPException = 1 in {
+ def C_SF_#NAME#_MM : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 8> {
+ let BaseOpcode = "c.sf."#NAME;
+ let isCommutable = 1;
+ }
+ def C_NGLE_#NAME#_MM : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 9> {
+ let BaseOpcode = "c.ngle."#NAME;
+ }
+ def C_SEQ_#NAME#_MM : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 10> {
+ let BaseOpcode = "c.seq."#NAME;
+ let isCommutable = 1;
+ }
+ def C_NGL_#NAME#_MM : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 11> {
+ let BaseOpcode = "c.ngl."#NAME;
+ }
+ def C_LT_#NAME#_MM : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 12> {
+ let BaseOpcode = "c.lt."#NAME;
+ }
+ def C_NGE_#NAME#_MM : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 13> {
+ let BaseOpcode = "c.nge."#NAME;
+ }
+ def C_LE_#NAME#_MM : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 14> {
+ let BaseOpcode = "c.le."#NAME;
+ }
+ def C_NGT_#NAME#_MM : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
+ C_COND_FM_MM<fmt, 15> {
+ let BaseOpcode = "c.ngt."#NAME;
+ }
}
}
let DecoderNamespace = "MicroMips" in {
diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
index fead376b8c338..853da4c23db2b 100644
--- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td
@@ -265,46 +265,48 @@ multiclass CMP_CC_M <FIELD_CMP_FORMAT Format, string Typestr,
setule>,
MipsR6Arch<!strconcat("cmp.ule.", Typestr)>,
ISA_MIPS32R6, HARDFLOAT;
- def CMP_SAF_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SAF>,
- CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.saf.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SUN_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SUN>,
- CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.sun.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SEQ_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SEQ>,
- CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.seq.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SUEQ_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SUEQ>,
- CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.sueq.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SLT_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SLT>,
- CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.slt.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SULT_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SULT>,
- CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.sult.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SLE_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SLE>,
- CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.sle.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
- def CMP_SULE_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
- FIELD_CMP_COND_SULE>,
- CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd, Itin>,
- MipsR6Arch<!strconcat("cmp.sule.", Typestr)>,
- ISA_MIPS32R6, HARDFLOAT;
+ let mayRaiseFPException = 1 in {
+ def CMP_SAF_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SAF>,
+ CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.saf.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SUN_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SUN>,
+ CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.sun.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SEQ_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SEQ>,
+ CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.seq.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SUEQ_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SUEQ>,
+ CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.sueq.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SLT_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SLT>,
+ CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.slt.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SULT_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SULT>,
+ CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.sult.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SLE_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SLE>,
+ CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.sle.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ def CMP_SULE_#NAME : R6MMR6Rel, COP1_CMP_CONDN_FM<Format,
+ FIELD_CMP_COND_SULE>,
+ CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd, Itin>,
+ MipsR6Arch<!strconcat("cmp.sule.", Typestr)>,
+ ISA_MIPS32R6, HARDFLOAT;
+ }
}
}
@@ -941,32 +943,38 @@ let AdditionalPredicates = [NotInMicroMips] in {
}
def LWPC : R6MMR6Rel, LWPC_ENC, LWPC_DESC, ISA_MIPS32R6;
let AdditionalPredicates = [NotInMicroMips] in {
- def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MAXA_D : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MAXA_S : MAXA_S_ENC, MAXA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MAX_D : MAX_D_ENC, MAX_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MAX_S : MAX_S_ENC, MAX_S_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MINA_D : MINA_D_ENC, MINA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MINA_S : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ let mayRaiseFPException = 1 in {
+ let Uses = [FCR31] in {
+ def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ }
+
+ def MAXA_D : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MAXA_S : MAXA_S_ENC, MAXA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MAX_D : MAX_D_ENC, MAX_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MAX_S : MAX_S_ENC, MAX_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MINA_D : MINA_D_ENC, MINA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MINA_S : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ }
def MOD : R6MMR6Rel, MOD_ENC, MOD_DESC, ISA_MIPS32R6;
def MODU : R6MMR6Rel, MODU_ENC, MODU_DESC, ISA_MIPS32R6;
-
- def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
- def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
-
def MUH : R6MMR6Rel, MUH_ENC, MUH_DESC, ISA_MIPS32R6;
def MUHU : R6MMR6Rel, MUHU_ENC, MUHU_DESC, ISA_MIPS32R6;
def MUL_R6 : R6MMR6Rel, MUL_R6_ENC, MUL_R6_DESC, ISA_MIPS32R6;
def MULU : R6MMR6Rel, MULU_ENC, MULU_DESC, ISA_MIPS32R6;
}
let AdditionalPredicates = [NotInMicroMips] in {
+ let mayRaiseFPException = 1, Uses = [FCR31] in {
+ def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+ def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+ }
+
def PREF_R6 : R6MMR6Rel, PREF_ENC, PREF_DESC, ISA_MIPS32R6;
- def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6, HARDFLOAT;
- def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT;
def SC_R6 : SC_R6_ENC, SC_R6_DESC, PTR_32, ISA_MIPS32R6;
def SDBBP_R6 : SDBBP_R6_ENC, SDBBP_R6_DESC, ISA_MIPS32R6;
def SELEQZ : R6MMR6Rel, SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32;
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index c065ba6c9632e..a9d8af1418be9 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -142,6 +142,7 @@ class CVT_PS_S_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
let isCommutable = IsComm;
}
+let mayRaiseFPException = 1, Uses = [FCR31] in
multiclass ABSS_M<string opstr, InstrItinClass Itin,
SDPatternOperator OpNode= null_frag> {
def _D32 : MMRel, ABSS_FT<opstr, AFGR64Opnd, AFGR64Opnd, Itin, OpNode>,
@@ -318,39 +319,49 @@ multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt,
C_COND_FM<fmt, 7> {
let BaseOpcode = "c.ule."#NAME;
}
- def C_SF_#NAME : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
- C_COND_FM<fmt, 8> {
- let BaseOpcode = "c.sf."#NAME;
- let isCommutable = 1;
- }
- def C_NGLE_#NAME : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
- C_COND_FM<fmt, 9> {
- let BaseOpcode = "c.ngle."#NAME;
- }
- def C_SEQ_#NAME : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
- C_COND_FM<fmt, 10> {
- let BaseOpcode = "c.seq."#NAME;
- let isCommutable = 1;
- }
- def C_NGL_#NAME : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
- C_COND_FM<fmt, 11> {
- let BaseOpcode = "c.ngl."#NAME;
- }
- def C_LT_#NAME : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
- C_COND_FM<fmt, 12> {
- let BaseOpcode = "c.lt."#NAME;
- }
- def C_NGE_#NAME : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
- C_COND_FM<fmt, 13> {
- let BaseOpcode = "c.nge."#NAME;
- }
- def C_LE_#NAME : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
- C_COND_FM<fmt, 14> {
- let BaseOpcode = "c.le."#NAME;
- }
- def C_NGT_#NAME : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
- C_COND_FM<fmt, 15> {
- let BaseOpcode = "c.ngt."#NAME;
+ let mayRaiseFPException = 1 in {
+ def C_SF_#NAME : MMRel, C_COND_FT<"sf", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 8> {
+ let BaseOpcode = "c.sf."#NAME;
+ let isCommutable = 1;
+ let mayRaiseFPException = 1;
+ }
+ def C_NGLE_#NAME : MMRel, C_COND_FT<"ngle", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 9> {
+ let BaseOpcode = "c.ngle."#NAME;
+ let mayRaiseFPException = 1;
+ }
+ def C_SEQ_#NAME : MMRel, C_COND_FT<"seq", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 10> {
+ let BaseOpcode = "c.seq."#NAME;
+ let isCommutable = 1;
+ let mayRaiseFPException = 1;
+ }
+ def C_NGL_#NAME : MMRel, C_COND_FT<"ngl", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 11> {
+ let BaseOpcode = "c.ngl."#NAME;
+ let mayRaiseFPException = 1;
+ }
+ def C_LT_#NAME : MMRel, C_COND_FT<"lt", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 12> {
+ let BaseOpcode = "c.lt."#NAME;
+ let mayRaiseFPException = 1;
+ }
+ def C_NGE_#NAME : MMRel, C_COND_FT<"nge", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 13> {
+ let BaseOpcode = "c.nge."#NAME;
+ let mayRaiseFPException = 1;
+ }
+ def C_LE_#NAME : MMRel, C_COND_FT<"le", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 14> {
+ let BaseOpcode = "c.le."#NAME;
+ let mayRaiseFPException = 1;
+ }
+ def C_NGT_#NAME : MMRel, C_COND_FT<"ngt", TypeStr, RC, itin>,
+ C_COND_FM<fmt, 15> {
+ let BaseOpcode = "c.ngt."#NAME;
+ let mayRaiseFPException = 1;
+ }
}
}
@@ -365,7 +376,7 @@ defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6,
//===----------------------------------------------------------------------===//
// Floating Point Instructions
//===----------------------------------------------------------------------===//
-let AdditionalPredicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1 in {
def ROUND_W_S : MMRel, StdMMR6Rel,
ABSS_FT<"round.w.s", FGR32Opnd, FGR32Opnd, II_ROUND>,
ABSS_FM<0xc, 16>, ISA_MIPS2;
@@ -379,16 +390,19 @@ let AdditionalPredicates = [NotInMicroMips] in {
def FLOOR_W_S : MMRel, StdMMR6Rel,
ABSS_FT<"floor.w.s", FGR32Opnd, FGR32Opnd, II_FLOOR>,
ABSS_FM<0xf, 16>, ISA_MIPS2;
- def CVT_W_S : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>,
- ABSS_FM<0x24, 16>, ISA_MIPS1;
defm TRUNC_W : ROUND_M<"trunc.w.d", II_TRUNC>, ABSS_FM<0xd, 17>, ISA_MIPS2;
defm CEIL_W : ROUND_M<"ceil.w.d", II_CEIL>, ABSS_FM<0xe, 17>, ISA_MIPS2;
defm FLOOR_W : ROUND_M<"floor.w.d", II_FLOOR>, ABSS_FM<0xf, 17>, ISA_MIPS2;
- defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>, ISA_MIPS1;
+
+ let Uses = [FCR31] in {
+ def CVT_W_S : MMRel, ABSS_FT<"cvt.w.s", FGR32Opnd, FGR32Opnd, II_CVT>, // fp
+ ABSS_FM<0x24, 16>, ISA_MIPS1;
+ defm CVT_W : ROUND_M<"cvt.w.d", II_CVT>, ABSS_FM<0x24, 17>, ISA_MIPS1;
+ }
}
-let AdditionalPredicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in {
def RECIP_S : MMRel, ABSS_FT<"recip.s", FGR32Opnd, FGR32Opnd, II_RECIP_S>,
ABSS_FM<0b010101, 0x10>, INSN_MIPS4_32R2;
def RECIP_D32 : MMRel, ABSS_FT<"recip.d", AFGR64Opnd, AFGR64Opnd, II_RECIP_D>,
@@ -410,7 +424,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
II_RSQRT_D>, ABSS_FM<0b010110, 0x11>,
INSN_MIPS4_32R2, FGR_64;
}
-let DecoderNamespace = "MipsFP64" in {
+
+let DecoderNamespace = "MipsFP64", mayRaiseFPException = 1 in {
let AdditionalPredicates = [NotInMicroMips] in {
def ROUND_L_S : ABSS_FT<"round.l.s", FGR64Opnd, FGR32Opnd, II_ROUND>,
ABSS_FM<0x8, 16>, ISA_MIPS2, FGR_64;
@@ -431,7 +446,7 @@ let DecoderNamespace = "MipsFP64" in {
}
}
-let AdditionalPredicates = [NotInMicroMips] in{
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in{
def CVT_S_W : MMRel, ABSS_FT<"cvt.s.w", FGR32Opnd, FGR32Opnd, II_CVT>,
ABSS_FM<0x20, 20>, ISA_MIPS1;
def CVT_L_S : MMRel, ABSS_FT<"cvt.l.s", FGR64Opnd, FGR32Opnd, II_CVT>,
@@ -440,7 +455,7 @@ let AdditionalPredicates = [NotInMicroMips] in{
ABSS_FM<0x25, 17>, INSN_MIPS3_32R2;
}
-let AdditionalPredicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in {
def CVT_S_D32 : MMRel, ABSS_FT<"cvt.s.d", FGR32Opnd, AFGR64Opnd, II_CVT>,
ABSS_FM<0x20, 17>, ISA_MIPS1, FGR_32;
def CVT_D32_S : MMRel, ABSS_FT<"cvt.d.s", AFGR64Opnd, FGR32Opnd, II_CVT>,
@@ -449,44 +464,43 @@ let AdditionalPredicates = [NotInMicroMips] in {
ABSS_FM<0x21, 20>, ISA_MIPS1, FGR_32;
}
-let DecoderNamespace = "MipsFP64" in {
- let AdditionalPredicates = [NotInMicroMips] in {
+let DecoderNamespace = "MipsFP64", AdditionalPredicates = [NotInMicroMips] in {
+ let mayRaiseFPException = 1, Uses = [FCR31] in {
def FADD_PS64 : ADDS_FT<"add.ps", FGR64Opnd, II_ADD_PS, 0>,
ADDS_FM<0x0, 22>,
ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
def FMUL_PS64 : ADDS_FT<"mul.ps", FGR64Opnd, II_MUL_PS, 0>,
ADDS_FM<0x2, 22>,
ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
- def PLL_PS64 : ADDS_FT<"pll.ps", FGR64Opnd, II_CVT, 0>,
- ADDS_FM<0x2C, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
- def PLU_PS64 : ADDS_FT<"plu.ps", FGR64Opnd, II_CVT, 0>,
- ADDS_FM<0x2D, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
- def PUL_PS64 : ADDS_FT<"pul.ps", FGR64Opnd, II_CVT, 0>,
- ADDS_FM<0x2E, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
- def PUU_PS64 : ADDS_FT<"puu.ps", FGR64Opnd, II_CVT, 0>,
- ADDS_FM<0x2F, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
def FSUB_PS64 : ADDS_FT<"sub.ps", FGR64Opnd, II_SUB_PS, 0>,
ADDS_FM<0x1, 22>,
ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
-
- def CVT_S_PU64 : ABSS_FT<"cvt.s.pu", FGR32Opnd, FGR64Opnd, II_CVT>,
- ABSS_FM<0x20, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
- def CVT_S_PL64 : ABSS_FT<"cvt.s.pl", FGR32Opnd, FGR64Opnd, II_CVT>,
- ABSS_FM<0x28, 22>,
- ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
-
def CVT_PS_S64 : CVT_PS_S_FT<"cvt.ps.s", FGR64Opnd, FGR32Opnd, II_CVT, 0>,
ADDS_FM<0x26, 16>,
ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
}
+
+ def PLL_PS64 : ADDS_FT<"pll.ps", FGR64Opnd, II_CVT, 0>,
+ ADDS_FM<0x2C, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
+ def PLU_PS64 : ADDS_FT<"plu.ps", FGR64Opnd, II_CVT, 0>,
+ ADDS_FM<0x2D, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
+ def PUL_PS64 : ADDS_FT<"pul.ps", FGR64Opnd, II_CVT, 0>,
+ ADDS_FM<0x2E, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
+ def PUU_PS64 : ADDS_FT<"puu.ps", FGR64Opnd, II_CVT, 0>,
+ ADDS_FM<0x2F, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
+ def CVT_S_PU64 : ABSS_FT<"cvt.s.pu", FGR32Opnd, FGR64Opnd, II_CVT>,
+ ABSS_FM<0x20, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
+ def CVT_S_PL64 : ABSS_FT<"cvt.s.pl", FGR32Opnd, FGR64Opnd, II_CVT>,
+ ABSS_FM<0x28, 22>,
+ ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
}
-let DecoderNamespace = "MipsFP64" in {
+let DecoderNamespace = "MipsFP64", mayRaiseFPException = 1, Uses = [FCR31] in {
let AdditionalPredicates = [HasMips3D] in {
def ADDR_PS64 : ADDS_FT<"addr.ps", FGR64Opnd, II_ADDR_PS, 0>,
ADDS_FM<0x18, 22>, ISA_MIPS32R2_NOT_32R6_64R6, FGR_64;
@@ -501,7 +515,7 @@ let DecoderNamespace = "MipsFP64" in {
}
}
-let DecoderNamespace = "MipsFP64" in {
+let DecoderNamespace = "MipsFP64", mayRaiseFPException = 1, Uses = [FCR31] in {
let AdditionalPredicates = [NotInMicroMips] in {
def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32Opnd, FGR64Opnd, II_CVT>,
ABSS_FM<0x20, 21>, INSN_MIPS3_32R2, FGR_64;
@@ -536,7 +550,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
defm FNEG : ABSS_M<"neg.d", II_NEG, fneg>, ABSS_FM<0x7, 17>, ISA_MIPS1;
}
-let AdditionalPredicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in {
def FSQRT_S : MMRel, StdMMR6Rel, ABSS_FT<"sqrt.s", FGR32Opnd, FGR32Opnd,
II_SQRT_S, any_fsqrt>, ABSS_FM<0x4, 16>, ISA_MIPS2;
defm FSQRT : ABSS_M<"sqrt.d", II_SQRT_D, any_fsqrt>, ABSS_FM<0x4, 17>, ISA_MIPS2;
@@ -659,7 +673,7 @@ let AdditionalPredicates = [NotInMicroMips],
}
/// Floating-point Arithmetic
-let AdditionalPredicates = [NotInMicroMips] in {
+let AdditionalPredicates = [NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in {
def FADD_S : MMRel, ADDS_FT<"add.s", FGR32Opnd, II_ADD_S, 1, any_fadd>,
ADDS_FM<0x00, 16>, ISA_MIPS1;
defm FADD : ADDS_M<"add.d", II_ADD_D, 1, any_fadd>, ADDS_FM<0x00, 17>,
@@ -678,7 +692,7 @@ let AdditionalPredicates = [NotInMicroMips] in {
ISA_MIPS1;
}
-let AdditionalPredicates = [NotInMicroMips, HasMadd4] in {
+let AdditionalPredicates = [NotInMicroMips, HasMadd4], mayRaiseFPException = 1, Uses = [FCR31] in {
def MADD_S : MMRel, MADDS_FT<"madd.s", FGR32Opnd, II_MADD_S, any_fadd>,
MADDS_FM<4, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
def MSUB_S : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S, any_fsub>,
@@ -697,7 +711,7 @@ let AdditionalPredicates = [NotInMicroMips, HasMadd4] in {
}
}
-let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in {
+let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips], mayRaiseFPException = 1, Uses = [FCR31] in {
def NMADD_S : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S, any_fadd>,
MADDS_FM<6, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6;
def NMSUB_S : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S, any_fsub>,
diff --git a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
index 6ca587b1ba4d5..948d4db8585db 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -206,6 +206,8 @@ getReservedRegs(const MachineFunction &MF) const {
}
}
}
+ // Reserve fp control and status register
+ Reserved.set(Mips::FCR31);
// Reserve hardware registers.
Reserved.set(Mips::HWR29);
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_arithmetic_operations.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_arithmetic_operations.mir
index 2654952dc28fc..77af724c76783 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_arithmetic_operations.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/float_arithmetic_operations.mir
@@ -25,18 +25,21 @@ body: |
; FP32-LABEL: name: float_add
; FP32: liveins: $f12, $f14
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP32: [[FADD_S:%[0-9]+]]:fgr32 = FADD_S [[COPY]], [[COPY1]]
- ; FP32: $f0 = COPY [[FADD_S]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP32-NEXT: [[FADD_S:%[0-9]+]]:fgr32 = nofpexcept FADD_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[FADD_S]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: float_add
; FP64: liveins: $f12, $f14
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP64: [[FADD_S:%[0-9]+]]:fgr32 = FADD_S [[COPY]], [[COPY1]]
- ; FP64: $f0 = COPY [[FADD_S]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP64-NEXT: [[FADD_S:%[0-9]+]]:fgr32 = nofpexcept FADD_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[FADD_S]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s32) = COPY $f12
%1:fprb(s32) = COPY $f14
%2:fprb(s32) = G_FADD %0, %1
@@ -56,18 +59,21 @@ body: |
; FP32-LABEL: name: float_sub
; FP32: liveins: $f12, $f14
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP32: [[FSUB_S:%[0-9]+]]:fgr32 = FSUB_S [[COPY]], [[COPY1]]
- ; FP32: $f0 = COPY [[FSUB_S]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP32-NEXT: [[FSUB_S:%[0-9]+]]:fgr32 = nofpexcept FSUB_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[FSUB_S]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: float_sub
; FP64: liveins: $f12, $f14
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP64: [[FSUB_S:%[0-9]+]]:fgr32 = FSUB_S [[COPY]], [[COPY1]]
- ; FP64: $f0 = COPY [[FSUB_S]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP64-NEXT: [[FSUB_S:%[0-9]+]]:fgr32 = nofpexcept FSUB_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[FSUB_S]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s32) = COPY $f12
%1:fprb(s32) = COPY $f14
%2:fprb(s32) = G_FSUB %0, %1
@@ -87,18 +93,21 @@ body: |
; FP32-LABEL: name: float_mul
; FP32: liveins: $f12, $f14
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP32: [[FMUL_S:%[0-9]+]]:fgr32 = FMUL_S [[COPY]], [[COPY1]]
- ; FP32: $f0 = COPY [[FMUL_S]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP32-NEXT: [[FMUL_S:%[0-9]+]]:fgr32 = nofpexcept FMUL_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[FMUL_S]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: float_mul
; FP64: liveins: $f12, $f14
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP64: [[FMUL_S:%[0-9]+]]:fgr32 = FMUL_S [[COPY]], [[COPY1]]
- ; FP64: $f0 = COPY [[FMUL_S]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP64-NEXT: [[FMUL_S:%[0-9]+]]:fgr32 = nofpexcept FMUL_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[FMUL_S]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s32) = COPY $f12
%1:fprb(s32) = COPY $f14
%2:fprb(s32) = G_FMUL %0, %1
@@ -118,18 +127,21 @@ body: |
; FP32-LABEL: name: float_div
; FP32: liveins: $f12, $f14
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP32: [[FDIV_S:%[0-9]+]]:fgr32 = FDIV_S [[COPY]], [[COPY1]]
- ; FP32: $f0 = COPY [[FDIV_S]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP32-NEXT: [[FDIV_S:%[0-9]+]]:fgr32 = nofpexcept FDIV_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[FDIV_S]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: float_div
; FP64: liveins: $f12, $f14
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
- ; FP64: [[FDIV_S:%[0-9]+]]:fgr32 = FDIV_S [[COPY]], [[COPY1]]
- ; FP64: $f0 = COPY [[FDIV_S]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr32 = COPY $f14
+ ; FP64-NEXT: [[FDIV_S:%[0-9]+]]:fgr32 = nofpexcept FDIV_S [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[FDIV_S]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s32) = COPY $f12
%1:fprb(s32) = COPY $f14
%2:fprb(s32) = G_FDIV %0, %1
@@ -149,18 +161,21 @@ body: |
; FP32-LABEL: name: double_add
; FP32: liveins: $d6, $d7
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
- ; FP32: [[FADD_D32_:%[0-9]+]]:afgr64 = FADD_D32 [[COPY]], [[COPY1]]
- ; FP32: $d0 = COPY [[FADD_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
+ ; FP32-NEXT: [[FADD_D32_:%[0-9]+]]:afgr64 = nofpexcept FADD_D32 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FADD_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: double_add
; FP64: liveins: $d6, $d7
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
- ; FP64: [[FADD_D64_:%[0-9]+]]:fgr64 = FADD_D64 [[COPY]], [[COPY1]]
- ; FP64: $d0 = COPY [[FADD_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
+ ; FP64-NEXT: [[FADD_D64_:%[0-9]+]]:fgr64 = nofpexcept FADD_D64 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FADD_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s64) = COPY $d6
%1:fprb(s64) = COPY $d7
%2:fprb(s64) = G_FADD %0, %1
@@ -180,18 +195,21 @@ body: |
; FP32-LABEL: name: double_sub
; FP32: liveins: $d6, $d7
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
- ; FP32: [[FSUB_D32_:%[0-9]+]]:afgr64 = FSUB_D32 [[COPY]], [[COPY1]]
- ; FP32: $d0 = COPY [[FSUB_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
+ ; FP32-NEXT: [[FSUB_D32_:%[0-9]+]]:afgr64 = nofpexcept FSUB_D32 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FSUB_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: double_sub
; FP64: liveins: $d6, $d7
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
- ; FP64: [[FSUB_D64_:%[0-9]+]]:fgr64 = FSUB_D64 [[COPY]], [[COPY1]]
- ; FP64: $d0 = COPY [[FSUB_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
+ ; FP64-NEXT: [[FSUB_D64_:%[0-9]+]]:fgr64 = nofpexcept FSUB_D64 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FSUB_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s64) = COPY $d6
%1:fprb(s64) = COPY $d7
%2:fprb(s64) = G_FSUB %0, %1
@@ -211,18 +229,21 @@ body: |
; FP32-LABEL: name: double_mul
; FP32: liveins: $d6, $d7
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
- ; FP32: [[FMUL_D32_:%[0-9]+]]:afgr64 = FMUL_D32 [[COPY]], [[COPY1]]
- ; FP32: $d0 = COPY [[FMUL_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
+ ; FP32-NEXT: [[FMUL_D32_:%[0-9]+]]:afgr64 = nofpexcept FMUL_D32 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FMUL_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: double_mul
; FP64: liveins: $d6, $d7
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
- ; FP64: [[FMUL_D64_:%[0-9]+]]:fgr64 = FMUL_D64 [[COPY]], [[COPY1]]
- ; FP64: $d0 = COPY [[FMUL_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
+ ; FP64-NEXT: [[FMUL_D64_:%[0-9]+]]:fgr64 = nofpexcept FMUL_D64 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FMUL_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s64) = COPY $d6
%1:fprb(s64) = COPY $d7
%2:fprb(s64) = G_FMUL %0, %1
@@ -242,18 +263,21 @@ body: |
; FP32-LABEL: name: double_div
; FP32: liveins: $d6, $d7
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
- ; FP32: [[FDIV_D32_:%[0-9]+]]:afgr64 = FDIV_D32 [[COPY]], [[COPY1]]
- ; FP32: $d0 = COPY [[FDIV_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
+ ; FP32-NEXT: [[FDIV_D32_:%[0-9]+]]:afgr64 = nofpexcept FDIV_D32 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FDIV_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: double_div
; FP64: liveins: $d6, $d7
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
- ; FP64: [[FDIV_D64_:%[0-9]+]]:fgr64 = FDIV_D64 [[COPY]], [[COPY1]]
- ; FP64: $d0 = COPY [[FDIV_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
+ ; FP64-NEXT: [[FDIV_D64_:%[0-9]+]]:fgr64 = nofpexcept FDIV_D64 [[COPY]], [[COPY1]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FDIV_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s64) = COPY $d6
%1:fprb(s64) = COPY $d7
%2:fprb(s64) = G_FDIV %0, %1
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fpext_and_fptrunc.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fpext_and_fptrunc.mir
index 053da198abe36..983362aea209a 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fpext_and_fptrunc.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fpext_and_fptrunc.mir
@@ -19,16 +19,19 @@ body: |
; FP32-LABEL: name: fpext
; FP32: liveins: $f12
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[CVT_D32_S:%[0-9]+]]:afgr64 = CVT_D32_S [[COPY]]
- ; FP32: $d0 = COPY [[CVT_D32_S]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[CVT_D32_S:%[0-9]+]]:afgr64 = nofpexcept CVT_D32_S [[COPY]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[CVT_D32_S]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: fpext
; FP64: liveins: $f12
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[CVT_D64_S:%[0-9]+]]:fgr64 = CVT_D64_S [[COPY]]
- ; FP64: $d0 = COPY [[CVT_D64_S]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[CVT_D64_S:%[0-9]+]]:fgr64 = nofpexcept CVT_D64_S [[COPY]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[CVT_D64_S]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s32) = COPY $f12
%1:fprb(s64) = G_FPEXT %0(s32)
$d0 = COPY %1(s64)
@@ -47,16 +50,19 @@ body: |
; FP32-LABEL: name: fptrunc
; FP32: liveins: $d6
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[CVT_S_D32_:%[0-9]+]]:fgr32 = CVT_S_D32 [[COPY]]
- ; FP32: $f0 = COPY [[CVT_S_D32_]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[CVT_S_D32_:%[0-9]+]]:fgr32 = nofpexcept CVT_S_D32 [[COPY]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[CVT_S_D32_]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: fptrunc
; FP64: liveins: $d6
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[CVT_S_D64_:%[0-9]+]]:fgr32 = CVT_S_D64 [[COPY]]
- ; FP64: $f0 = COPY [[CVT_S_D64_]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[CVT_S_D64_:%[0-9]+]]:fgr32 = nofpexcept CVT_S_D64 [[COPY]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[CVT_S_D64_]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s64) = COPY $d6
%1:fprb(s32) = G_FPTRUNC %0(s64)
$f0 = COPY %1(s32)
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fsqrt.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fsqrt.mir
index 0759fc1ab5c2f..b4f6f9edc054a 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fsqrt.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/fsqrt.mir
@@ -19,16 +19,19 @@ body: |
; FP32-LABEL: name: sqrt_f32
; FP32: liveins: $f12
- ; FP32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP32: [[FSQRT_S:%[0-9]+]]:fgr32 = FSQRT_S [[COPY]]
- ; FP32: $f0 = COPY [[FSQRT_S]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP32-NEXT: [[FSQRT_S:%[0-9]+]]:fgr32 = nofpexcept FSQRT_S [[COPY]], implicit $fcr31
+ ; FP32-NEXT: $f0 = COPY [[FSQRT_S]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: sqrt_f32
; FP64: liveins: $f12
- ; FP64: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
- ; FP64: [[FSQRT_S:%[0-9]+]]:fgr32 = FSQRT_S [[COPY]]
- ; FP64: $f0 = COPY [[FSQRT_S]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; FP64-NEXT: [[FSQRT_S:%[0-9]+]]:fgr32 = nofpexcept FSQRT_S [[COPY]], implicit $fcr31
+ ; FP64-NEXT: $f0 = COPY [[FSQRT_S]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:fprb(s32) = COPY $f12
%1:fprb(s32) = G_FSQRT %0
$f0 = COPY %1(s32)
@@ -47,16 +50,19 @@ body: |
; FP32-LABEL: name: sqrt_f64
; FP32: liveins: $d6
- ; FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
- ; FP32: [[FSQRT_D32_:%[0-9]+]]:afgr64 = FSQRT_D32 [[COPY]]
- ; FP32: $d0 = COPY [[FSQRT_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; FP32-NEXT: [[FSQRT_D32_:%[0-9]+]]:afgr64 = nofpexcept FSQRT_D32 [[COPY]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FSQRT_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: sqrt_f64
; FP64: liveins: $d6
- ; FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
- ; FP64: [[FSQRT_D64_:%[0-9]+]]:fgr64 = FSQRT_D64 [[COPY]]
- ; FP64: $d0 = COPY [[FSQRT_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; FP64-NEXT: [[FSQRT_D64_:%[0-9]+]]:fgr64 = nofpexcept FSQRT_D64 [[COPY]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FSQRT_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:fprb(s64) = COPY $d6
%1:fprb(s64) = G_FSQRT %0
$d0 = COPY %1(s64)
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
index 1569e00f30959..a9d4a6d93402f 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/sitofp_and_uitofp.mir
@@ -20,16 +20,19 @@ body: |
; FP32-LABEL: name: i32tof32
; FP32: liveins: $a0
- ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP32: [[PseudoCVT_S_W:%[0-9]+]]:fgr32 = PseudoCVT_S_W [[COPY]]
- ; FP32: $f0 = COPY [[PseudoCVT_S_W]]
- ; FP32: RetRA implicit $f0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP32-NEXT: [[PseudoCVT_S_W:%[0-9]+]]:fgr32 = PseudoCVT_S_W [[COPY]]
+ ; FP32-NEXT: $f0 = COPY [[PseudoCVT_S_W]]
+ ; FP32-NEXT: RetRA implicit $f0
+ ;
; FP64-LABEL: name: i32tof32
; FP64: liveins: $a0
- ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP64: [[PseudoCVT_S_W:%[0-9]+]]:fgr32 = PseudoCVT_S_W [[COPY]]
- ; FP64: $f0 = COPY [[PseudoCVT_S_W]]
- ; FP64: RetRA implicit $f0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP64-NEXT: [[PseudoCVT_S_W:%[0-9]+]]:fgr32 = PseudoCVT_S_W [[COPY]]
+ ; FP64-NEXT: $f0 = COPY [[PseudoCVT_S_W]]
+ ; FP64-NEXT: RetRA implicit $f0
%0:gprb(s32) = COPY $a0
%1:fprb(s32) = G_SITOFP %0(s32)
$f0 = COPY %1(s32)
@@ -48,16 +51,19 @@ body: |
; FP32-LABEL: name: i32tof64
; FP32: liveins: $a0
- ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP32: [[PseudoCVT_D32_W:%[0-9]+]]:afgr64 = PseudoCVT_D32_W [[COPY]]
- ; FP32: $d0 = COPY [[PseudoCVT_D32_W]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP32-NEXT: [[PseudoCVT_D32_W:%[0-9]+]]:afgr64 = PseudoCVT_D32_W [[COPY]]
+ ; FP32-NEXT: $d0 = COPY [[PseudoCVT_D32_W]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: i32tof64
; FP64: liveins: $a0
- ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP64: [[PseudoCVT_D64_W:%[0-9]+]]:fgr64 = PseudoCVT_D64_W [[COPY]]
- ; FP64: $d0 = COPY [[PseudoCVT_D64_W]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP64-NEXT: [[PseudoCVT_D64_W:%[0-9]+]]:fgr64 = PseudoCVT_D64_W [[COPY]]
+ ; FP64-NEXT: $d0 = COPY [[PseudoCVT_D64_W]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:gprb(s32) = COPY $a0
%1:fprb(s64) = G_SITOFP %0(s32)
$d0 = COPY %1(s64)
@@ -76,26 +82,29 @@ body: |
; FP32-LABEL: name: u32tof64
; FP32: liveins: $a0
- ; FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP32: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
- ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 [[COPY]], [[LUi]]
- ; FP32: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
- ; FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
- ; FP32: [[BuildPairF64_1:%[0-9]+]]:afgr64 = BuildPairF64 [[ORi]], [[LUi1]]
- ; FP32: [[FSUB_D32_:%[0-9]+]]:afgr64 = FSUB_D32 [[BuildPairF64_]], [[BuildPairF64_1]]
- ; FP32: $d0 = COPY [[FSUB_D32_]]
- ; FP32: RetRA implicit $d0
+ ; FP32-NEXT: {{ $}}
+ ; FP32-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP32-NEXT: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
+ ; FP32-NEXT: [[BuildPairF64_:%[0-9]+]]:afgr64 = BuildPairF64 [[COPY]], [[LUi]]
+ ; FP32-NEXT: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
+ ; FP32-NEXT: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
+ ; FP32-NEXT: [[BuildPairF64_1:%[0-9]+]]:afgr64 = BuildPairF64 [[ORi]], [[LUi1]]
+ ; FP32-NEXT: [[FSUB_D32_:%[0-9]+]]:afgr64 = nofpexcept FSUB_D32 [[BuildPairF64_]], [[BuildPairF64_1]], implicit $fcr31
+ ; FP32-NEXT: $d0 = COPY [[FSUB_D32_]]
+ ; FP32-NEXT: RetRA implicit $d0
+ ;
; FP64-LABEL: name: u32tof64
; FP64: liveins: $a0
- ; FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; FP64: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
- ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64 = BuildPairF64_64 [[COPY]], [[LUi]]
- ; FP64: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
- ; FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
- ; FP64: [[BuildPairF64_64_1:%[0-9]+]]:fgr64 = BuildPairF64_64 [[ORi]], [[LUi1]]
- ; FP64: [[FSUB_D64_:%[0-9]+]]:fgr64 = FSUB_D64 [[BuildPairF64_64_]], [[BuildPairF64_64_1]]
- ; FP64: $d0 = COPY [[FSUB_D64_]]
- ; FP64: RetRA implicit $d0
+ ; FP64-NEXT: {{ $}}
+ ; FP64-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; FP64-NEXT: [[LUi:%[0-9]+]]:gpr32 = LUi 17200
+ ; FP64-NEXT: [[BuildPairF64_64_:%[0-9]+]]:fgr64 = BuildPairF64_64 [[COPY]], [[LUi]]
+ ; FP64-NEXT: [[LUi1:%[0-9]+]]:gpr32 = LUi 17200
+ ; FP64-NEXT: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 0
+ ; FP64-NEXT: [[BuildPairF64_64_1:%[0-9]+]]:fgr64 = BuildPairF64_64 [[ORi]], [[LUi1]]
+ ; FP64-NEXT: [[FSUB_D64_:%[0-9]+]]:fgr64 = nofpexcept FSUB_D64 [[BuildPairF64_64_]], [[BuildPairF64_64_1]], implicit $fcr31
+ ; FP64-NEXT: $d0 = COPY [[FSUB_D64_]]
+ ; FP64-NEXT: RetRA implicit $d0
%0:gprb(s32) = COPY $a0
%2:gprb(s32) = G_CONSTANT i32 1127219200
%3:fprb(s64) = G_MERGE_VALUES %0(s32), %2(s32)
diff --git a/llvm/test/CodeGen/Mips/fp-strict-fp-ops.ll b/llvm/test/CodeGen/Mips/fp-strict-fp-ops.ll
new file mode 100644
index 0000000000000..abb3e5b06cb1b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/fp-strict-fp-ops.ll
@@ -0,0 +1,110 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=mips -mcpu=mips32r2 < %s | FileCheck %s
+
+define void @unused_div(float %x, float %y) {
+; CHECK-LABEL: unused_div:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+entry:
+ %add = fdiv float %x, %y
+ ret void
+}
+
+define void @unused_div_fpexcept_strict(float %x, float %y) #0 {
+; CHECK-LABEL: unused_div_fpexcept_strict:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: div.s $f0, $f12, $f14
+entry:
+ %add = call float @llvm.experimental.constrained.fdiv.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
+ ret void
+}
+
+define void @unused_div_round_dynamic(float %x, float %y) #0 {
+; CHECK-LABEL: unused_div_round_dynamic:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+entry:
+ %add = call float @llvm.experimental.constrained.fdiv.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+ ret void
+}
+
+define float @add_twice(float %x, float %y, i32 %n) {
+; CHECK-LABEL: add_twice:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: beqz $6, $BB3_2
+; CHECK-NEXT: add.s $f0, $f12, $f14
+; CHECK-NEXT: # %bb.1: # %if.then
+; CHECK-NEXT: mul.s $f0, $f0, $f0
+; CHECK-NEXT: $BB3_2: # %if.end
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+entry:
+ %add = fadd float %x, %y
+ %tobool.not = icmp eq i32 %n, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:
+ %add1 = fadd float %x, %y
+ %mul = fmul float %add, %add1
+ br label %if.end
+
+if.end:
+ %a.0 = phi float [ %mul, %if.then ], [ %add, %entry ]
+ ret float %a.0
+}
+
+define float @add_twice_fpexcept_strict(float %x, float %y, i32 %n) #0 {
+; CHECK-LABEL: add_twice_fpexcept_strict:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: beqz $6, $BB4_2
+; CHECK-NEXT: add.s $f0, $f12, $f14
+; CHECK-NEXT: # %bb.1: # %if.then
+; CHECK-NEXT: add.s $f1, $f12, $f14
+; CHECK-NEXT: mul.s $f0, $f0, $f1
+; CHECK-NEXT: $BB4_2: # %if.end
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+entry:
+ %add = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
+ %tobool.not = icmp eq i32 %n, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:
+ %add1 = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
+ %mul = call float @llvm.experimental.constrained.fmul.f32(float %add, float %add1, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
+ br label %if.end
+
+if.end:
+ %a.0 = phi float [ %mul, %if.then ], [ %add, %entry ]
+ ret float %a.0
+}
+
+define float @add_twice_round_dynamic(float %x, float %y, i32 %n) #0 {
+; CHECK-LABEL: add_twice_round_dynamic:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: beqz $6, $BB5_2
+; CHECK-NEXT: add.s $f0, $f12, $f14
+; CHECK-NEXT: # %bb.1: # %if.then
+; CHECK-NEXT: mul.s $f0, $f0, $f0
+; CHECK-NEXT: $BB5_2: # %if.end
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+entry:
+ %add = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+ %tobool.not = icmp eq i32 %n, 0
+ br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:
+ %add1 = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+ %mul = call float @llvm.experimental.constrained.fmul.f32(float %add, float %add1, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
+ br label %if.end
+
+if.end:
+ %a.0 = phi float [ %mul, %if.then ], [ %add, %entry ]
+ ret float %a.0
+}
+
+attributes #0 = { strictfp }
More information about the llvm-commits
mailing list