On Thu, Dec 10, 2020 at 12:00:17PM +0100, Jakub Jelinek wrote:
> So, would it be better to check for one of FRAME_POINTER_REGNUM,
> ARG_POINTER_REGNUM or RETURN_ADDRESS_POINTER_REGNUM if they
> are mentioned in (from part of pairs in) ELIMINABLE_REGS?

In patch form now:

2020-12-10  Jakub Jelinek  <ja...@redhat.com>

        PR target/92469
        * varasm.c (eliminable_regno_p): New function.
        (make_decl_rtl): Reject asm vars for frame and argp
        if they are different from hard frame pointer.

        * gcc.target/i386/pr92469.c: New test.
        * gcc.target/i386/pr79804.c: Adjust expected diagnostics.
        * gcc.target/i386/pr88178.c: Expect an error.

--- gcc/varasm.c.jj     2020-12-04 10:53:56.314043883 +0100
+++ gcc/varasm.c        2020-12-10 16:02:48.273074206 +0100
@@ -1370,6 +1370,23 @@ ultimate_transparent_alias_target (tree
   return target;
 }
 
+/* Return true if REGNUM is mentioned in ELIMINABLE_REGS as a from
+   register number.  */
+
+static bool
+eliminable_regno_p (int regnum)
+{
+  static const struct
+  {
+    const int from;
+    const int to;
+  } eliminables[] = ELIMINABLE_REGS;
+  for (size_t i = 0; i < ARRAY_SIZE (eliminables); i++)
+    if (regnum == eliminables[i].from)
+      return true;
+  return false;
+}
+
 /* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
    have static storage duration.  In other words, it should not be an
    automatic variable, including PARM_DECLs.
@@ -1472,6 +1489,15 @@ make_decl_rtl (tree decl)
       else if (!targetm.hard_regno_mode_ok (reg_number, mode))
        error ("register specified for %q+D isn%'t suitable for data type",
                decl);
+      else if (reg_number != HARD_FRAME_POINTER_REGNUM
+              && (reg_number == FRAME_POINTER_REGNUM
+#ifdef RETURN_ADDRESS_POINTER_REGNUM
+                  || reg_number == RETURN_ADDRESS_POINTER_REGNUM
+#endif
+                  || reg_number == ARG_POINTER_REGNUM)
+              && eliminable_regno_p (reg_number))
+       error ("register specified for %q+D is an internal GCC "
+              "implementation detail", decl);
       /* Now handle properly declared static register variables.  */
       else
        {
--- gcc/testsuite/gcc.target/i386/pr92469.c.jj  2020-12-09 13:41:50.497501433 
+0100
+++ gcc/testsuite/gcc.target/i386/pr92469.c     2020-12-09 13:41:30.416724986 
+0100
@@ -0,0 +1,24 @@
+/* PR target/92469 */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+void
+foo (void)
+{ 
+  register int x asm ("frame");        /* { dg-error "register specified for 
'x' is an internal GCC implementation detail" } */
+  int y = x;
+}
+
+void
+bar (void)
+{ 
+  register int x asm ("19");   /* { dg-error "register specified for 'x' is an 
internal GCC implementation detail" } */
+  int y = x;
+}
+
+void
+baz (void)
+{ 
+  register int x asm ("argp"); /* { dg-error "register specified for 'x' is an 
internal GCC implementation detail" } */
+  int y = x;
+}
--- gcc/testsuite/gcc.target/i386/pr79804.c.jj  2020-01-12 11:54:37.976389828 
+0100
+++ gcc/testsuite/gcc.target/i386/pr79804.c     2020-12-10 10:11:53.948939322 
+0100
@@ -4,7 +4,7 @@
 
 void foo (void)
 {
-  register int r19 asm ("19");
+  register int r19 asm ("19"); /* { dg-error "register specified for 'r19' is 
an internal GCC implementation detail" } */
 
-  asm volatile ("# %0" : "=r"(r19));  /* { dg-error "invalid use of register" 
} */
-}  /* { dg-error "cannot be used in 'asm' here" } */
+  asm volatile ("# %0" : "=r"(r19));
+}
--- gcc/testsuite/gcc.target/i386/pr88178.c.jj  2020-01-12 11:54:37.983389722 
+0100
+++ gcc/testsuite/gcc.target/i386/pr88178.c     2020-12-10 10:12:30.140535022 
+0100
@@ -4,5 +4,5 @@
 
 void foo (void)
 {
-  register int r19 asm ("19");
+  register int r19 asm ("19"); /* { dg-error "register specified for 'r19' is 
an internal GCC implementation detail" } */
 }


        Jakub

Reply via email to