public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2500] [RA][PR109520]: Catch error when there are no enough registers for asm insn
@ 2023-07-13 14:48 Vladimir Makarov
  0 siblings, 0 replies; only message in thread
From: Vladimir Makarov @ 2023-07-13 14:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b175b4887f928118af997f6d4d75097a64dcec5d

commit r14-2500-gb175b4887f928118af997f6d4d75097a64dcec5d
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Thu Jul 13 10:42:17 2023 -0400

    [RA][PR109520]: Catch error when there are no enough registers for asm insn
    
    Asm insn unlike other insns can have so many operands whose
    constraints can not be satisfied.  It results in LRA cycling for such
    test case.  The following patch catches such situation and reports the
    problem.
    
            PR middle-end/109520
    
    gcc/ChangeLog:
    
            * lra-int.h (lra_insn_recog_data): Add member asm_reloads_num.
            (lra_asm_insn_error): New prototype.
            * lra.cc: Include rtl_error.h.
            (lra_set_insn_recog_data): Initialize asm_reloads_num.
            (lra_asm_insn_error): New func whose code is taken from ...
            * lra-assigns.cc (lra_split_hard_reg_for): ... here.  Use lra_asm_insn_error.
            * lra-constraints.cc (curr_insn_transform): Check reloads nummber for asm.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr109520.c: New test.

Diff:
---
 gcc/lra-assigns.cc                       | 16 ++---------
 gcc/lra-constraints.cc                   |  4 +++
 gcc/lra-int.h                            |  4 +++
 gcc/lra.cc                               | 23 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr109520.c | 48 ++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 14 deletions(-)

diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc
index 2f95121df06..3555926af66 100644
--- a/gcc/lra-assigns.cc
+++ b/gcc/lra-assigns.cc
@@ -1851,20 +1851,8 @@ lra_split_hard_reg_for (void)
       insn = lra_insn_recog_data[u]->insn;
       if (asm_noperands (PATTERN (insn)) >= 0)
 	{
-	  lra_asm_error_p = asm_p = true;
-	  error_for_asm (insn,
-			 "%<asm%> operand has impossible constraints");
-	  /* Avoid further trouble with this insn.  */
-	  if (JUMP_P (insn))
-	    {
-	      ira_nullify_asm_goto (insn);
-	      lra_update_insn_regno_info (insn);
-	    }
-	  else
-	    {
-	      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
-	      lra_set_insn_deleted (insn);
-	    }
+	  asm_p = true;
+	  lra_asm_insn_error (insn);
 	}
       else if (!asm_p)
 	{
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 9bfc88149ff..0c6912d6e7d 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -4813,6 +4813,10 @@ curr_insn_transform (bool check_only_p)
       lra_update_operator_dups (curr_id);
       /* Something changes -- process the insn.	 */
       lra_update_insn_regno_info (curr_insn);
+      if (asm_noperands (PATTERN (curr_insn)) >= 0
+	  && ++curr_id->asm_reloads_num >= FIRST_PSEUDO_REGISTER)
+	/* Most probably there are no enough registers to satisfy asm insn: */
+	lra_asm_insn_error (curr_insn);
     }
   lra_process_new_insns (curr_insn, before, after, "Inserting insn reload");
   return change_p;
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 4dbe6672f3a..a32359e5772 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -209,6 +209,9 @@ public:
      debug insn.  LRA_NON_CLOBBERED_ALT means ignoring any earlier
      clobbers for the insn.  */
   int used_insn_alternative;
+  /* Defined for asm insn and it is how many times we already generated reloads
+     for the asm insn.  */
+  int asm_reloads_num;
   /* SP offset before the insn relative to one at the func start.  */
   poly_int64 sp_offset;
   /* The insn itself.  */
@@ -307,6 +310,7 @@ extern void lra_delete_dead_insn (rtx_insn *);
 extern void lra_emit_add (rtx, rtx, rtx);
 extern void lra_emit_move (rtx, rtx);
 extern void lra_update_dups (lra_insn_recog_data_t, signed char *);
+extern void lra_asm_insn_error (rtx_insn *insn);
 
 extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
 				   const char *);
diff --git a/gcc/lra.cc b/gcc/lra.cc
index c8b3f139acd..563aff10b96 100644
--- a/gcc/lra.cc
+++ b/gcc/lra.cc
@@ -106,6 +106,7 @@ along with GCC; see the file COPYING3.	If not see
 #include "backend.h"
 #include "target.h"
 #include "rtl.h"
+#include "rtl-error.h"
 #include "tree.h"
 #include "predict.h"
 #include "df.h"
@@ -536,6 +537,27 @@ lra_update_dups (lra_insn_recog_data_t id, signed char *nops)
 	*id->dup_loc[i] = *id->operand_loc[nop];
 }
 
+/* Report asm insn error and modify the asm insn.  */
+void
+lra_asm_insn_error (rtx_insn *insn)
+{
+  lra_asm_error_p = true;
+  error_for_asm (insn,
+		 "%<asm%> operand has impossible constraints"
+		 " or there are not enough registers");
+  /* Avoid further trouble with this insn.  */
+  if (JUMP_P (insn))
+    {
+      ira_nullify_asm_goto (insn);
+      lra_update_insn_regno_info (insn);
+    }
+  else
+    {
+      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
+      lra_set_insn_deleted (insn);
+    }
+}
+
 \f
 
 /* This page contains code dealing with info about registers in the
@@ -973,6 +995,7 @@ lra_set_insn_recog_data (rtx_insn *insn)
   lra_insn_recog_data[uid] = data;
   data->insn = insn;
   data->used_insn_alternative = LRA_UNKNOWN_ALT;
+  data->asm_reloads_num = 0;
   data->icode = icode;
   data->regs = NULL;
   if (DEBUG_INSN_P (insn))
diff --git a/gcc/testsuite/gcc.target/i386/pr109520.c b/gcc/testsuite/gcc.target/i386/pr109520.c
new file mode 100644
index 00000000000..d81b2555202
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr109520.c
@@ -0,0 +1,48 @@
+/* { dg-do compile  { target { ! ia32 } } } */
+/* { dg-options "-O0" } */
+
+int
+foo (int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
+     int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16)
+{
+  register int v0 asm ("rax") = a3;
+  register int v1 asm ("rbx") = a4;
+  register int v2 asm ("rcx") = a5;
+  register int v3 asm ("rdx") = a6;
+  register int v4 asm ("rsi") = a7;
+  register int v5 asm ("rdi") = a8;
+  register int v6 asm ("r8") = a9;
+  register int v7 asm ("r9") = a10;
+  register int v8 asm ("r10") = a11;
+  register int v9 asm ("r11") = a12;
+  register int v10 asm ("r12") = a13;
+  register int v11 asm ("r13") = a14;
+  register int v12 asm ("r14") = a15;
+  register int v13 asm ("r15") = a16;
+  int x;
+  
+  v0 += a0;
+  v1 += a1;
+  v2 += a2;
+  v0 |= a0;
+  v1 |= a1;
+  v2 |= a2;
+  v0 ^= a0;
+  v1 ^= a1;
+  v2 ^= a2;
+  v0 &= a0;
+  v1 &= a1;
+  v2 &= a2;
+  asm goto ("": "=r" (x) : : : lab); /* { dg-error "operand has impossible constraints" } */
+  a1 ^= a0;
+  a2 = a1;
+  a0 |= a2;
+  a0 |= x;
+ lab:
+  v0 += x + a0 + a1 + a2;
+  v1 -= a0 - a1 - a2;
+  v2 |= a0 | a1 | a2;
+  v3 |= a0 & a1 & a2;
+  v4 ^= a0 ^ a1 ^ a2;
+  return  v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + v13 + a0 + a1 + a2;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-13 14:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-13 14:48 [gcc r14-2500] [RA][PR109520]: Catch error when there are no enough registers for asm insn Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).