gcc/gcc10-pr97032.patch

90 lines
3.4 KiB
Diff

2020-09-14 H.J. Lu <hjl.tools@gmail.com>
PR target/97032
* cfgexpand.c (asm_clobber_reg_kind): Set sp_is_clobbered_by_asm
to true if the stack pointer is clobbered by asm statement.
* emit-rtl.h (rtl_data): Add sp_is_clobbered_by_asm.
* config/i386/i386.c (ix86_get_drap_rtx): Set need_drap to true
if the stack pointer is clobbered by asm statement.
* gcc.target/i386/pr97032.c: New test.
--- gcc/cfgexpand.c
+++ gcc/cfgexpand.c
@@ -2879,11 +2879,15 @@ 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))
+ {
+ crtl->sp_is_clobbered_by_asm = true;
+ if (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");
+ }
return is_valid;
}
--- gcc/config/i386/i386.c
+++ gcc/config/i386/i386.c
@@ -12283,10 +12283,12 @@ ix86_update_stack_boundary (void)
static rtx
ix86_get_drap_rtx (void)
{
- /* We must use DRAP if there are outgoing arguments on stack and
+ /* We must use DRAP if there are outgoing arguments on stack or
+ the stack pointer register is clobbered by asm statment and
ACCUMULATE_OUTGOING_ARGS is false. */
if (ix86_force_drap
- || (cfun->machine->outgoing_args_on_stack
+ || ((cfun->machine->outgoing_args_on_stack
+ || crtl->sp_is_clobbered_by_asm)
&& !ACCUMULATE_OUTGOING_ARGS))
crtl->need_drap = true;
--- gcc/emit-rtl.h
+++ gcc/emit-rtl.h
@@ -266,6 +266,9 @@ struct GTY(()) rtl_data {
pass_stack_ptr_mod has run. */
bool sp_is_unchanging;
+ /* True if the stack pointer is clobbered by asm statement. */
+ bool sp_is_clobbered_by_asm;
+
/* Nonzero if function being compiled doesn't contain any calls
(ignoring the prologue and epilogue). This is set prior to
register allocation in IRA and is valid for the remaining
--- gcc/testsuite/gcc.target/i386/pr97032.c
+++ 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" } } */