use call-clobbered reg to disalign the stack
authorAlexandre Oliva <oliva@adacore.com>
Wed, 9 Oct 2019 01:14:02 +0000 (01:14 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Wed, 9 Oct 2019 01:14:02 +0000 (01:14 +0000)
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
gcc/testsuite/gcc.target/i386/20060512-1.c
gcc/testsuite/gcc.target/i386/20060512-3.c

index 3f189e31719e6da7f2cab7b573e57cfb19c6ad58..a1f3966f79196995ee089d099805dd4e00b96c64 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-08  Alexandre Oliva <oliva@adacore.com>
+
+       * 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  <msebor@redhat.com>
 
        PR c++/92001
index ec163a9bc51e9ffd51a9052dc7856d891eb367bf..fe95f6d52fa9881ccedb3795e0dbed33c4056904 100644 (file)
@@ -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));
 }
index 3370b9ec25afb2aa727c8f8f4f14e351816644b8..0cebb47f6e9bc9ed3602139ccdd5251e395598a6 100644 (file)
@@ -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));
 }