From 87e47c1f3715b140c106a7d054ca8b20bda6040e Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Fri, 18 Jun 2021 20:11:42 +0800
Subject: [PATCH 1/6] mips: check MSA support for vector modes
 [PR100760,PR100761,PR100762]

Check if the vector mode is really supported by MSA in certain cases,
instead of testing ISA_HAS_MSA.  Simply testing ISA_HAS_MSA can cause
ICE when MSA is enabled besides other MIPS SIMD extensions (notably,
Loongson MMI).

gcc/

	PR target/100760
	PR target/100761
	PR target/100762
	* config/mips/mips.c (mips_const_insns): Use MSA_SUPPORTED_MODE_P
	instead of ISA_HAS_MSA.
	(mips_expand_vec_unpack): Likewise.
	(mips_expand_vector_init): Likewise.

gcc/testsuite/

	PR target/100760
	PR target/100761
	PR target/100762
	* gcc.target/mips/pr100760.c: New test.
	* gcc.target/mips/pr100761.c: New test.
	* gcc.target/mips/pr100762.c: New test.

(cherry picked from commit 82625a42e652d52fc6bbe6070f8d0589d5e0c8ad)
---
 gcc/config/mips/mips.c                   |  6 +++---
 gcc/testsuite/gcc.target/mips/pr100760.c | 10 ++++++++++
 gcc/testsuite/gcc.target/mips/pr100761.c | 17 ++++++++++++++++
 gcc/testsuite/gcc.target/mips/pr100762.c | 25 ++++++++++++++++++++++++
 4 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/pr100760.c
 create mode 100644 gcc/testsuite/gcc.target/mips/pr100761.c
 create mode 100644 gcc/testsuite/gcc.target/mips/pr100762.c

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 315545966f8..bb615d95e3b 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2878,7 +2878,7 @@ mips_const_insns (rtx x)
       return mips_build_integer (codes, INTVAL (x));
 
     case CONST_VECTOR:
-      if (ISA_HAS_MSA
+      if (MSA_SUPPORTED_MODE_P (GET_MODE (x))
 	  && mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511))
 	return 1;
       /* Fall through.  */
@@ -21731,7 +21731,7 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
   rtx (*cmpFunc) (rtx, rtx, rtx);
   rtx tmp, dest, zero;
 
-  if (ISA_HAS_MSA)
+  if (MSA_SUPPORTED_MODE_P (imode))
     {
       switch (imode)
 	{
@@ -21993,7 +21993,7 @@ mips_expand_vector_init (rtx target, rtx vals)
 	all_same = false;
     }
 
-  if (ISA_HAS_MSA)
+  if (MSA_SUPPORTED_MODE_P (vmode))
     {
       if (all_same)
 	{
diff --git a/gcc/testsuite/gcc.target/mips/pr100760.c b/gcc/testsuite/gcc.target/mips/pr100760.c
new file mode 100644
index 00000000000..d715b85e790
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100760.c
@@ -0,0 +1,10 @@
+/* PR target/100760
+   This was triggering an ICE with "maximum number of generated reload
+   insns per insn achieved (90)" when compiled with -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef int32_t a __attribute__((__vector_size__(8)));
+void b() { a x = (a){1, 1}; }
diff --git a/gcc/testsuite/gcc.target/mips/pr100761.c b/gcc/testsuite/gcc.target/mips/pr100761.c
new file mode 100644
index 00000000000..cc2598ee023
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100761.c
@@ -0,0 +1,17 @@
+/* PR target/100761
+   This was triggering an ICE in mips_expand_vec_unpack when compiled with
+   -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef int8_t i8x8 __attribute__((__vector_size__(8)));
+typedef int16_t i16x8 __attribute__((__vector_size__(16)));
+
+i8x8 a;
+
+void f() {
+  i16x8 b = __builtin_convertvector (a, i16x8);
+}
diff --git a/gcc/testsuite/gcc.target/mips/pr100762.c b/gcc/testsuite/gcc.target/mips/pr100762.c
new file mode 100644
index 00000000000..89c1185317c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr100762.c
@@ -0,0 +1,25 @@
+/* PR target/100762
+   This was triggering an ICE in mips_expand_vector_init when compiled with
+   -mmsa -mloongson-mmi. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa -mloongson-mmi" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef int32_t i32x2 __attribute__((__vector_size__(8)));
+
+i32x2 cmp(i32x2 a, i32x2 b) {
+  return a >= b;
+}
+
+i32x2 shift(i32x2 a, i32x2 b) {
+  return a >> b;
+}
+
+i32x2 mul(i32x2 a, i32x2 b) {
+  return a * b;
+}
+
+i32x2 div(i32x2 a, i32x2 b) {
+  return a / b;
+}
-- 
2.32.0

From 59c78844147056683508a831d7443d8702f861d3 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Fri, 23 Jul 2021 13:55:56 +0800
Subject: [PATCH 2/6] testsuite: mips: pass -finline/-fnoinline through

gcc/testsuite/

	* gcc.target/mips/mips.exp (mips_option_groups): add
	  -finline and -fno-inline.

(cherry picked from commit 19e05058799ffd611f4946d1871e747bae7a0046)
---
 gcc/testsuite/gcc.target/mips/mips.exp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 01292316944..580e7c0c8f9 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -325,6 +325,7 @@ foreach option {
     finite-math-only
     fixed-hi
     fixed-lo
+    inline
     lax-vector-conversions
     omit-frame-pointer
     optimize-sibling-calls
-- 
2.32.0

From 9fefd18a0ed52c158a74e8df407112dbb56acfa4 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Sun, 20 Jun 2021 15:21:39 +0800
Subject: [PATCH 3/6] mips: add MSA vec_cmp and vec_cmpu expand pattern
 [PR101132]

Middle-end started to emit vec_cmp and vec_cmpu since GCC 11, causing
ICE on MIPS with MSA enabled.  Add the pattern to prevent it.

gcc/

	PR target/101132
	* config/mips/mips-protos.h (mips_expand_vec_cmp_expr): Declare.
	* config/mips/mips.c (mips_expand_vec_cmp_expr): New function.
	* config/mips/mips-msa.md (vec_cmp<MSA:mode><mode_i>): New
	  expander.
	  (vec_cmpu<IMSA:mode><mode_i>): New expander.

gcc/testsuite/

	PR target/101132
	* gcc.target/mips/pr101132.c: New test.

(cherry picked from commit 45cb789e6adf5d571c574a94b77413c845fed106)
---
 gcc/config/mips/mips-msa.md              | 22 ++++++++++++++++++++++
 gcc/config/mips/mips-protos.h            |  1 +
 gcc/config/mips/mips.c                   | 11 +++++++++++
 gcc/testsuite/gcc.target/mips/pr101132.c | 14 ++++++++++++++
 4 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/mips/pr101132.c

diff --git a/gcc/config/mips/mips-msa.md b/gcc/config/mips/mips-msa.md
index 3ecf2bde19f..3a67f25be56 100644
--- a/gcc/config/mips/mips-msa.md
+++ b/gcc/config/mips/mips-msa.md
@@ -435,6 +435,28 @@ (define_expand "vcond<MSA:mode><MSA_2:mode>"
   DONE;
 })
 
+(define_expand "vec_cmp<MSA:mode><mode_i>"
+  [(match_operand:<VIMODE> 0 "register_operand")
+   (match_operator 1 ""
+     [(match_operand:MSA 2 "register_operand")
+      (match_operand:MSA 3 "register_operand")])]
+  "ISA_HAS_MSA"
+{
+  mips_expand_vec_cmp_expr (operands);
+  DONE;
+})
+
+(define_expand "vec_cmpu<IMSA:mode><mode_i>"
+  [(match_operand:<VIMODE> 0 "register_operand")
+   (match_operator 1 ""
+     [(match_operand:IMSA 2 "register_operand")
+      (match_operand:IMSA 3 "register_operand")])]
+  "ISA_HAS_MSA"
+{
+  mips_expand_vec_cmp_expr (operands);
+  DONE;
+})
+
 (define_insn "msa_insert_<msafmt_f>"
   [(set (match_operand:MSA 0 "register_operand" "=f,f")
 	(vec_merge:MSA
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 2cf4ed50292..a685f7f7dd5 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -385,6 +385,7 @@ extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code);
 
 extern void mips_register_frame_header_opt (void);
 extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
+extern void mips_expand_vec_cmp_expr (rtx *);
 
 /* Routines implemented in mips-d.c  */
 extern void mips_d_target_versions (void);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index bb615d95e3b..e0ca9a11ff8 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -22320,6 +22320,17 @@ mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1)
     }
 }
 
+void
+mips_expand_vec_cmp_expr (rtx *operands)
+{
+  rtx cond = operands[1];
+  rtx op0 = operands[2];
+  rtx op1 = operands[3];
+  rtx res = operands[0];
+
+  mips_expand_msa_cmp (res, GET_CODE (cond), op0, op1);
+}
+
 /* Expand VEC_COND_EXPR, where:
    MODE is mode of the result
    VIMODE equivalent integer mode
diff --git a/gcc/testsuite/gcc.target/mips/pr101132.c b/gcc/testsuite/gcc.target/mips/pr101132.c
new file mode 100644
index 00000000000..d490b5d3a82
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr101132.c
@@ -0,0 +1,14 @@
+/* PR target/101132
+   This was triggering an ICE in do_store_flag when compiled with -mmsa -O3. */
+
+/* { dg-do compile } */
+/* { dg-options "-mmsa" } */
+
+int r_0, q_0;
+void bar() {
+  int i;
+  for (i = 0; i < 96; i++) {
+    r_0 = i << i ? 2 + i : -i;
+    q_0 = r_0 > 2 ?: i;
+  }
+}
-- 
2.32.0

From 7fa8802a1c9627dd64c66ad0855ea782e1323dda Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Fri, 30 Jul 2021 23:44:14 +0800
Subject: [PATCH 4/6] mips: Fix up mips_atomic_assign_expand_fenv [PR94780]

Commit message shamelessly copied from 1777beb6b129 by jakub:

This function, because it is sometimes called even outside of function
bodies, uses create_tmp_var_raw rather than create_tmp_var.  But in order
for that to work, when first referenced, the VAR_DECLs need to appear in a
TARGET_EXPR so that during gimplification the var gets the right
DECL_CONTEXT and is added to local decls.

gcc/

	PR target/94780
	* config/mips/mips.c (mips_atomic_assign_expand_fenv): Use
	  TARGET_EXPR instead of MODIFY_EXPR.

(cherry picked from commit 2065654435e3d97676366f82b939bc9273382dbe)
---
 gcc/config/mips/mips.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e0ca9a11ff8..caa074056c4 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -22438,12 +22438,12 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   tree get_fcsr = mips_builtin_decls[MIPS_GET_FCSR];
   tree set_fcsr = mips_builtin_decls[MIPS_SET_FCSR];
   tree get_fcsr_hold_call = build_call_expr (get_fcsr, 0);
-  tree hold_assign_orig = build2 (MODIFY_EXPR, MIPS_ATYPE_USI,
-				  fcsr_orig_var, get_fcsr_hold_call);
+  tree hold_assign_orig = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
+				  fcsr_orig_var, get_fcsr_hold_call, NULL, NULL);
   tree hold_mod_val = build2 (BIT_AND_EXPR, MIPS_ATYPE_USI, fcsr_orig_var,
 			      build_int_cst (MIPS_ATYPE_USI, 0xfffff003));
-  tree hold_assign_mod = build2 (MODIFY_EXPR, MIPS_ATYPE_USI,
-				 fcsr_mod_var, hold_mod_val);
+  tree hold_assign_mod = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
+				 fcsr_mod_var, hold_mod_val, NULL, NULL);
   tree set_fcsr_hold_call = build_call_expr (set_fcsr, 1, fcsr_mod_var);
   tree hold_all = build2 (COMPOUND_EXPR, MIPS_ATYPE_USI,
 			  hold_assign_orig, hold_assign_mod);
@@ -22453,8 +22453,8 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   *clear = build_call_expr (set_fcsr, 1, fcsr_mod_var);
 
   tree get_fcsr_update_call = build_call_expr (get_fcsr, 0);
-  *update = build2 (MODIFY_EXPR, MIPS_ATYPE_USI,
-		    exceptions_var, get_fcsr_update_call);
+  *update = build4 (TARGET_EXPR, MIPS_ATYPE_USI,
+		    exceptions_var, get_fcsr_update_call, NULL, NULL);
   tree set_fcsr_update_call = build_call_expr (set_fcsr, 1, fcsr_orig_var);
   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
 		    set_fcsr_update_call);
-- 
2.32.0

From 8db45a1c26a4480b2ed99d8f71d83919ef5f3706 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan@123.wang>
Date: Wed, 23 Jun 2021 14:45:06 -0400
Subject: [PATCH 5/6] testsuite: add -fwrapv for 950704-1.c

gcc/testsuite
	* gcc.c-torture/execute/950704-1.c: Add -fwrapv to avoid
	undefined behavior.

(cherry picked from commit d48320083c9a2bdf0ddac693f9d523755b8b29ec)
---
 gcc/testsuite/gcc.c-torture/execute/950704-1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.c-torture/execute/950704-1.c b/gcc/testsuite/gcc.c-torture/execute/950704-1.c
index f11aff8cabc..67fe0885e5a 100644
--- a/gcc/testsuite/gcc.c-torture/execute/950704-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/950704-1.c
@@ -1,3 +1,4 @@
+/* { dg-additional-options "-fwrapv" } */
 int errflag;
 
 long long
-- 
2.32.0

From 6dcdf62c62f765d73d5d55a7848f633cfd56021f Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@mengyan1223.wang>
Date: Tue, 22 Jun 2021 14:57:47 +0800
Subject: [PATCH 6/6] testsuite: avoid no-stack-protector-attr-3 fail on
 mips*-*-*

On MIPS a call to __stack_chk_fail needs an additional .reloc pseudo-op,
so "stack_chk_fail" will appear two times.

gcc/testsuite/

	* g++.dg/no-stack-protector-attr-3.C (dg-final): Adjust for MIPS.

(cherry picked from commit 607c558804f70af2b8f0c39d4d349b349d56cc84)
---
 gcc/testsuite/g++.dg/no-stack-protector-attr-3.C | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C
index 56a4e74da50..76a5ec08681 100644
--- a/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C
+++ b/gcc/testsuite/g++.dg/no-stack-protector-attr-3.C
@@ -20,4 +20,5 @@ int __attribute__((stack_protect)) bar()
   return 0;
 }
 
-/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */
+/* { dg-final { scan-assembler-times "stack_chk_fail" 1 { target { ! mips*-*-* } } } }*/
+/* { dg-final { scan-assembler-times "stack_chk_fail" 2 { target { mips*-*-* } } } }*/
-- 
2.32.0

