On Thu, 2022-03-10 at 21:41 +0800, Xi Ruoyao wrote:
> Changes from v1:
> 
>  * Added all zeroed registers into the return value of
>    TARGET_ZERO_CALL_USED_REGS.  **The question: is this allowed?**
>  * Define mips_zero_fcc insn only for ISA_HAS_8CC and mips_isa >
>    MIPS_ISA_MIPS4, because MIPS I-IV and MIPSr6 don't support
>    "ISA_HAS_8CC && mips_isa > MIPS_ISA_MIPS4".
>  * Change mips_zero_fcc to explicit clear all eight registers.
>  * Report an error for MIPS I-IV.

My mail client somehow mangled the patch.  Resending...

-- >8 --

This fixes the ICEs using -fzero-call-used-regs=all for MIPS target.

OpenSSH-8.9p1 has started to enable this by default, giving us a reason
to fix -fzero-call-used-regs for more targets.

gcc/

        PR target/xxxxxx (WIP)
        PR target/xxxxxx (Don't push)
        * config/mips/mips.cc (mips_zero_call_used_regs): New function.
          (TARGET_ZERO_CALL_USED_REGS): Define.
        * config/mips/mips.md (FCC{0..9}_REGNUM): New constants.
        (mips_zero_fcc): New insn.

gcc/testsuite

        * c-c++-common/zero-scratch-regs-8.c: Enable for MIPS.
        * c-c++-common/zero-scratch-regs-9.c: Likewise.
        * c-c++-common/zero-scratch-regs-10.c: Likewise.
        * c-c++-common/zero-scratch-regs-11.c: Likewise.
---
 gcc/config/mips/mips.cc                       | 55 +++++++++++++++++++
 gcc/config/mips/mips.md                       | 20 +++++++
 .../c-c++-common/zero-scratch-regs-10.c       |  2 +-
 .../c-c++-common/zero-scratch-regs-11.c       |  2 +-
 .../c-c++-common/zero-scratch-regs-8.c        |  2 +-
 .../c-c++-common/zero-scratch-regs-9.c        |  2 +-
 6 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 4f9683e8bf4..59eef515826 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -22611,6 +22611,59 @@ mips_asm_file_end (void)
   if (NEED_INDICATE_EXEC_STACK)
     file_end_indicate_exec_stack ();
 }
+
+static HARD_REG_SET
+mips_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
+{
+  HARD_REG_SET zeroed_hardregs;
+  CLEAR_HARD_REG_SET (zeroed_hardregs);
+
+  if (TEST_HARD_REG_BIT (need_zeroed_hardregs, HI_REGNUM))
+    {
+      /* Clear HI and LO altogether.  MIPS target treats HILO as a
+        double-word register.  */
+      machine_mode dword_mode = TARGET_64BIT ? TImode : DImode;
+      rtx hilo = gen_rtx_REG (dword_mode, MD_REG_FIRST);
+      rtx zero = CONST0_RTX (dword_mode);
+      emit_move_insn (hilo, zero);
+
+      SET_HARD_REG_BIT (zeroed_hardregs, HI_REGNUM);
+      SET_HARD_REG_BIT (zeroed_hardregs, LO_REGNUM);
+    }
+
+  /* MIPS does not have a simple way to clear one bit in FCC.  We just
+     clear FCC with ctc1 and clobber all FCC bits.  */
+  HARD_REG_SET fcc = reg_class_contents[ST_REGS] & accessible_reg_set;
+  if (hard_reg_set_intersect_p (need_zeroed_hardregs, fcc))
+    {
+      static bool issued_error = false;
+      if (mips_isa <= MIPS_ISA_MIPS4)
+       {
+         /* We don't have an easy way to clear FCC on MIPS I, II, III,
+            and IV.  */
+         if (!issued_error)
+           sorry ("%qs not supported on this target",
+                  "-fzero-call-used-regs");
+         issued_error = true;
+
+         /* Prevent an ICE.  */
+         need_zeroed_hardregs &= ~fcc;
+       }
+      else
+       {
+         /* If the target is MIPSr6, we should not reach here.  All other
+            MIPS targets are ISA_HAS_8CC.  */
+         gcc_assert (ISA_HAS_8CC);
+         emit_insn (gen_mips_zero_fcc ());
+         zeroed_hardregs |= fcc;
+       }
+    }
+
+  need_zeroed_hardregs &= ~zeroed_hardregs;
+  return (zeroed_hardregs |
+         default_zero_call_used_regs (need_zeroed_hardregs));
+}
+
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
@@ -22919,6 +22972,8 @@ mips_asm_file_end (void)
 #undef TARGET_ASM_FILE_END
 #define TARGET_ASM_FILE_END mips_asm_file_end
 
+#undef TARGET_ZERO_CALL_USED_REGS
+#define TARGET_ZERO_CALL_USED_REGS mips_zero_call_used_regs
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index e0f0a582732..36d6a43d67f 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -167,6 +167,14 @@ (define_constants
    (SET_FCSR_REGNUM            4)
    (PIC_FUNCTION_ADDR_REGNUM   25)
    (RETURN_ADDR_REGNUM         31)
+   (FCC0_REGNUM                        67)
+   (FCC1_REGNUM                        68)
+   (FCC2_REGNUM                        69)
+   (FCC3_REGNUM                        70)
+   (FCC4_REGNUM                        71)
+   (FCC5_REGNUM                        72)
+   (FCC6_REGNUM                        73)
+   (FCC7_REGNUM                        74)
    (CPRESTORE_SLOT_REGNUM      76)
    (GOT_VERSION_REGNUM         79)
 
@@ -7670,6 +7678,18 @@ (define_insn "*mips_set_fcsr"
   "TARGET_HARD_FLOAT"
   "ctc1\t%0,$31")
 
+(define_insn "mips_zero_fcc"
+  [(set (reg:CC FCC0_REGNUM) (const_int 0))
+   (set (reg:CC FCC1_REGNUM) (const_int 0))
+   (set (reg:CC FCC2_REGNUM) (const_int 0))
+   (set (reg:CC FCC3_REGNUM) (const_int 0))
+   (set (reg:CC FCC4_REGNUM) (const_int 0))
+   (set (reg:CC FCC5_REGNUM) (const_int 0))
+   (set (reg:CC FCC6_REGNUM) (const_int 0))
+   (set (reg:CC FCC7_REGNUM) (const_int 0))]
+  "TARGET_HARD_FLOAT && ISA_HAS_8CC && mips_isa > MIPS_ISA_MIPS4"
+  "ctc1\t$0,$25")
+
 ;; See tls_get_tp_mips16_<mode> for why this form is used.
 (define_insn "mips_set_fcsr_mips16_<mode>"
   [(unspec_volatile:SI [(match_operand:P 0 "call_insn_operand" "dS")
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
index 96e0b79b328..c23b2ceb391 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-10.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* nvptx*-*-* s390*-*-* mips*-*-* } } } */
 /* { dg-options "-O2" } */
 
 #include <assert.h>
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
index 0714f95a04f..f51f5a2161c 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-11.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* mips*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-10.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
index aceda7e5cb8..3e5e59b3c79 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-8.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* mips*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all-arg" } */
 
 #include "zero-scratch-regs-1.c"
diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c 
b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
index f3152a7a732..d88d61accb2 100644
--- a/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
+++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-9.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* } } } */
+/* { dg-skip-if "not implemented" { ! { i?86*-*-* x86_64*-*-* sparc*-*-* 
aarch64*-*-* arm*-*-* nvptx*-*-* s390*-*-* mips*-*-* } } } */
 /* { dg-options "-O2 -fzero-call-used-regs=all" } */
 
 #include "zero-scratch-regs-1.c"
-- 
2.35.1

Reply via email to