Message ID | orh84kt0t1.fsf@lxoliva.fsfla.org |
---|---|
State | New |
Headers | show |
Series | use call-clobbered reg to disalign the stack | expand |
On 10/7/19 8:42 PM, Alexandre Oliva wrote: > Some x86 tests of stack realignment, that disaligned the stack with > pushes and pops, failed when the compiler was configured to tune for a > target that preferred to accumulate outgoing arguments: the stack > space is reserved before the asm push, the call sequence overwrites > the saved register, and then the asm pop restores the overwritten > value. Since that's a call-preserved register in 32-bit mode, it > should be preserved unchanged, but isn't. > > Merely changing the register to a call-clobbered one would be enough, > but the tests would remain fragile and prone to failure due to other > optimizations, so I arranged for the compiler to be made aware of the > register used for the push and the pop, so it won't use it for > something else, and forced the function to use a frame pointer, so > that it won't use stack pointer offsets for local variables: the > offsets would likely be wrong between the asm push and pop. > > Tested on x86_64-linux-gnu with -m64 and -m32. Ok to install? > > > for gcc/testsuite/ChangeLog > > * gcc.target/i386/20060512-1.c (sse2_test): Use a > call-clobbered register variable for stack-disaligning push > and pop. Require a frame pointer. > * gcc.target/i386/20060512-3.c (sse2_test): Likewise. OK jeff > ---
diff --git a/gcc/testsuite/gcc.target/i386/20060512-1.c b/gcc/testsuite/gcc.target/i386/20060512-1.c index ec163a9bc51e9..fe95f6d52fa98 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-1.c +++ b/gcc/testsuite/gcc.target/i386/20060512-1.c @@ -7,11 +7,11 @@ #include <emmintrin.h> #ifdef __x86_64__ -# define PUSH "pushq %rsi" -# define POP "popq %rsi" +# define REG "rcx" +# define WIDTH "q" #else -# define PUSH "pushl %esi" -# define POP "popl %esi" +# define REG "ecx" +# define WIDTH "l" #endif __m128i __attribute__ ((__noinline__)) @@ -30,13 +30,15 @@ self_aligning_function (int x, int y) int g_1 = 20; int g_2 = 22; -static void +static void __attribute__ ((__optimize__ ("-fno-omit-frame-pointer"))) sse2_test (void) { int result; - asm (PUSH); /* Misalign runtime stack. */ + register int __attribute__ ((__mode__ (__word__))) reg asm (REG); + asm volatile ("push" WIDTH "\t%0" /* Disalign runtime stack. */ + : : "r" (reg) : "memory"); result = self_aligning_function (g_1, g_2); if (result != 42) abort (); - asm (POP); + asm volatile ("pop" WIDTH "\t%0" : "=r" (reg)); } diff --git a/gcc/testsuite/gcc.target/i386/20060512-3.c b/gcc/testsuite/gcc.target/i386/20060512-3.c index 3370b9ec25afb..0cebb47f6e9bc 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-3.c +++ b/gcc/testsuite/gcc.target/i386/20060512-3.c @@ -23,13 +23,14 @@ self_aligning_function (int x, int y) int g_1 = 20; int g_2 = 22; -static void +static void __attribute__ ((__optimize__ ("-fno-omit-frame-pointer"))) sse2_test (void) { int result; - asm ("pushl %esi"); /* Disalign runtime stack. */ + register int reg asm ("ecx"); + asm ("pushl\t%0": : "r" (reg) : "memory"); /* Disalign runtime stack. */ result = self_aligning_function (g_1, g_2); if (result != 42) abort (); - asm ("popl %esi"); + asm ("popl\t%0" : "=r" (reg)); }