From 4e78c6883f97bf45eeb1ad3041dcf2e2de01912c Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 9 Oct 2019 01:14:02 +0000 Subject: [PATCH] use call-clobbered reg to disalign the stack 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. 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. From-SVN: r276751 --- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.target/i386/20060512-1.c | 16 +++++++++------- gcc/testsuite/gcc.target/i386/20060512-3.c | 7 ++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f189e3..a1f3966 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-10-08 Alexandre Oliva + + * 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. + 2019-10-08 Martin Sebor PR c++/92001 diff --git a/gcc/testsuite/gcc.target/i386/20060512-1.c b/gcc/testsuite/gcc.target/i386/20060512-1.c index ec163a9..fe95f6d 100644 --- a/gcc/testsuite/gcc.target/i386/20060512-1.c +++ b/gcc/testsuite/gcc.target/i386/20060512-1.c @@ -7,11 +7,11 @@ #include #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 3370b9e..0cebb47 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)); } -- 2.7.4