rtl_data: Add sp_is_clobbered_by_asm
Add sp_is_clobbered_by_asm to rtl_data to inform backends that the stack pointer is clobbered by asm statement. gcc/ 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/testsuite/ PR target/97032 * gcc.target/i386/pr97032.c: New test.
This commit is contained in:
parent
f419a01589
commit
453a20c657
@ -2868,11 +2868,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;
|
||||
}
|
||||
|
@ -6968,10 +6968,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;
|
||||
|
||||
|
@ -281,6 +281,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
|
||||
|
23
gcc/testsuite/gcc.target/i386/pr97032.c
Normal file
23
gcc/testsuite/gcc.target/i386/pr97032.c
Normal file
@ -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" } } */
|
Loading…
Reference in New Issue
Block a user