public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Ignore the clobbered stack pointer in asm statment
@ 2020-09-12 17:11 H.J. Lu
  2020-09-12 17:37 ` Florian Weimer
  2020-09-14 14:35 ` Jakub Jelinek
  0 siblings, 2 replies; 14+ messages in thread
From: H.J. Lu @ 2020-09-12 17:11 UTC (permalink / raw)
  To: gcc-patches

Clobbering the stack pointer in asm statment has been deprecated.  Adding
the stack pointer register to the clobber list has traditionally had some
undocumented and somewhat obscure side-effects, including ICE.  Issue
a warning and ignore the clobbered stack pointer in asm statment.

gcc/

	PR target/97032
	* cfgexpand.c (asm_clobber_reg_kind): New enum.
	(asm_clobber_reg_is_valid): Renamed to ...
	(get_asm_clobber_reg_kind): This.  Ignore the stack pointer.
	(expand_asm_stmt): Replace asm_clobber_reg_is_valid with
	get_asm_clobber_reg_kind.  Skip ignored clobbered register.

gcc/testsuite/

	PR target/97032
	* gcc.target/i386/pr97032.c: New test.
---
 gcc/cfgexpand.c                         | 45 ++++++++++++++++++-------
 gcc/testsuite/gcc.target/i386/pr97032.c | 23 +++++++++++++
 2 files changed, 55 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr97032.c

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b334ea03c25..433e7889138 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2832,14 +2832,21 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
   return false;
 }
 
+enum asm_clobber_reg_kind
+{
+  asm_clobber_reg_valid,
+  asm_clobber_reg_invalid,
+  asm_clobber_reg_ignored
+};
+
 /* Check that the given REGNO spanning NREGS is a valid
    asm clobber operand.  Some HW registers cannot be
    saved/restored, hence they should not be clobbered by
    asm statements.  */
-static bool
-asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
+static asm_clobber_reg_kind
+get_asm_clobber_reg_kind (int regno, int nregs, const char *regname)
 {
-  bool is_valid = true;
+  asm_clobber_reg_kind kind = asm_clobber_reg_valid;
   HARD_REG_SET regset;
 
   CLEAR_HARD_REG_SET (regset);
@@ -2852,7 +2859,7 @@ asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
     {
       /* ??? Diagnose during gimplification?  */
       error ("PIC register clobbered by %qs in %<asm%>", regname);
-      is_valid = false;
+      kind = asm_clobber_reg_invalid;
     }
   else if (!in_hard_reg_set_p
 	   (accessible_reg_set, reg_raw_mode[regno], regno))
@@ -2860,7 +2867,7 @@ asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
       /* ??? Diagnose during gimplification?  */
       error ("the register %qs cannot be clobbered in %<asm%>"
 	     " for the current target", regname);
-      is_valid = false;
+      kind = asm_clobber_reg_invalid;
     }
 
   /* Clobbering the stack pointer register is deprecated.  GCC expects
@@ -2868,13 +2875,18 @@ asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
      as it was before, so no asm can validly clobber the stack pointer in
      the usual sense.  Adding the stack pointer to the clobber list has
      traditionally had some undocumented and somewhat obscure side-effects.  */
-  if (overlaps_hard_reg_set_p (regset, Pmode, STACK_POINTER_REGNUM)
-      && warning (OPT_Wdeprecated, "listing the stack pointer register"
-		  " %qs in a clobber list is deprecated", regname))
-    inform (input_location, "the value of the stack pointer after an %<asm%>"
-	    " statement must be the same as it was before the statement");
+  if (overlaps_hard_reg_set_p (regset, Pmode, STACK_POINTER_REGNUM))
+      {
+	kind = asm_clobber_reg_ignored;
+	if (warning (OPT_Wdeprecated, "listing the stack pointer register"
+		     " %qs in a clobber list is deprecated and ignored",
+		     regname))
+	  inform (input_location, "the value of the stack pointer after"
+		  " an %<asm%> statement must be the same as it was"
+		  " before the statement");
+      }
 
-  return is_valid;
+  return kind;
 }
 
 /* Generate RTL for an asm statement with arguments.
@@ -3009,8 +3021,15 @@ expand_asm_stmt (gasm *stmt)
 	  else
 	    for (int reg = j; reg < j + nregs; reg++)
 	      {
-		if (!asm_clobber_reg_is_valid (reg, nregs, regname))
-		  return;
+		switch (get_asm_clobber_reg_kind (reg, nregs, regname))
+		  {
+		  case asm_clobber_reg_valid:
+		    break;
+		  case asm_clobber_reg_invalid:
+		    return;
+		  case asm_clobber_reg_ignored:
+		    continue;
+		  }
 
 	        SET_HARD_REG_BIT (clobbered_regs, reg);
 	        rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);
diff --git a/gcc/testsuite/gcc.target/i386/pr97032.c b/gcc/testsuite/gcc.target/i386/pr97032.c
new file mode 100644
index 00000000000..7cbbe9bc22a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr97032.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { ia32 && fstack_protector } } } */
+/* { dg-options "-O2 -mincoming-stack-boundary=2 -fstack-protector-all" } */
+
+#include <stdarg.h>
+
+extern int *__errno_location (void);
+
+long
+sys_socketcall (int op, ...)
+{
+  long int res;
+  va_list ap;
+  va_start (ap, op);
+  asm volatile ("push %%ebx; movl %2, %%ebx; int $0x80; pop %%ebx"
+  /* { dg-warning "listing the stack pointer register" "" { target *-*-* } .-1 } */
+		: "=a" (res) : "0" (102), "ri" (16), "c" (ap) : "memory", "esp");
+  if (__builtin_expect (res > 4294963200UL, 0))
+    *__errno_location () = -res;
+  va_end (ap);
+  return res;
+}
+
+/* { dg-final { scan-assembler "call\[ \t\]*_?__errno_location" } } */
-- 
2.26.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-09-24 17:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-12 17:11 [PATCH] Ignore the clobbered stack pointer in asm statment H.J. Lu
2020-09-12 17:37 ` Florian Weimer
2020-09-12 17:47   ` H.J. Lu
2020-09-12 17:52   ` Jakub Jelinek
2020-09-12 17:57     ` Florian Weimer
2020-09-14 14:35 ` Jakub Jelinek
2020-09-14 15:12   ` H.J. Lu
2020-09-14 15:57     ` H.J. Lu
2020-09-14 17:04       ` Jakub Jelinek
2020-09-14 20:31         ` H.J. Lu
2020-09-16 11:34         ` Richard Sandiford
2020-09-16 11:47           ` Jakub Jelinek
2020-09-24 16:48             ` [GCC 8] " H.J. Lu
2020-09-24 17:39               ` H.J. Lu

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).