diff mbox

[v2,i386] : Enable -mstackrealign and 'force_align_arg_pointer' attribute for x86_64

Message ID CAFULd4YTOVh98w_VU6+OeJoiGirqEdkoB83r1v_TkqYVHxHzdw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Oct. 5, 2015, 5:33 p.m. UTC
On Sun, Oct 4, 2015 at 5:26 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

> As shown in PR 66697 [1] and WineHQ bug [2], an application can
> misalign incoming stack to less than ABI mandated 16 bytes. While it
> is possible to use -mincoming-stack-boundary=2  (= 4 bytes) for 32 bit
> targets to emit stack realignment code, this option is artificially
> limited to 4 (= 16  bytes) for 64bit targets.

Attached v2 patch goes all the way to enable -mstackrealign and
'force_align_arg_pointer' attribute for x86_64. In addition to
-mincoming-stack-boundary changes, the patch changes
MIN_STACK_BOUNDARY definition to 8bytes on 64bit targets, as this is
really the minimum supported stack boundary.

This patch is also needed to allow stack realignment in the interrupt handler.

2015-10-05  Uros Bizjak  <ubizjak@gmail.com>

    PR target/66697
    * config/i386/i386.h (MIN_STACK_BOUNDARY): Redefine as BITS_PER_WORD.
    * config/i386/i386.c (ix86_option_override_internal): Lower minimum
    allowed incoming stack boundary to 3 for 64bit SSE targets.
    (ix86_minimum_incoming_stack_boundary): Also initialize
    incoming_stack_boundary to MIN_STACK_BOUNDARY for 64bit targets
    when -mstackrealign or force_align_arg_pointer attribute is used.
    (ix86_handle_force_align_arg_pointer_attribute): New function.
    (ix86_attribute_table): Use it for force_align_arg_pointer attribute.

testsuite/ChangeLog:

2015-10-05  Uros Bizjak  <ubizjak@gmail.com>

    PR target/66697
    * gcc.target/i386/20060512-1.c: Also run on 64bit targets.
    (PUSH, POP): New defines.
    (sse2_test): Use PUSH and POP to misalign runtime stack.
    * gcc.target/i386/20060512-2.c: Also compile on 64bit targets.

Patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32}. I plan to commit this patch to SVN tomorrow, and also to
backport the patch to gcc-5 branch, but no soon that a couple of weeks
without problems in mainline, and after receiving confirmation from
Cygwin people that the patch cures their problems.

Uros.
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 228488)
+++ config/i386/i386.c	(working copy)
@@ -5102,8 +5102,7 @@  ix86_option_override_internal (bool main_args_p,
   ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
   if (opts_set->x_ix86_incoming_stack_boundary_arg)
     {
-      int min = (TARGET_64BIT_P (opts->x_ix86_isa_flags)
-		 ? (TARGET_SSE_P (opts->x_ix86_isa_flags) ? 4 : 3) : 2);
+      int min = TARGET_64BIT_P (opts->x_ix86_isa_flags) ? 3 : 2;
 
       if (opts->x_ix86_incoming_stack_boundary_arg < min
 	  || opts->x_ix86_incoming_stack_boundary_arg > 12)
@@ -11779,6 +11778,25 @@  find_drap_reg (void)
     }
 }
 
+/* Handle a "force_align_arg_pointer" attribute.  */
+
+static tree
+ix86_handle_force_align_arg_pointer_attribute (tree *node, tree name,
+					       tree, int, bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_TYPE
+      && TREE_CODE (*node) != METHOD_TYPE
+      && TREE_CODE (*node) != FIELD_DECL
+      && TREE_CODE (*node) != TYPE_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute only applies to functions",
+	       name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Return minimum incoming stack alignment.  */
 
 static unsigned int
@@ -11789,11 +11807,10 @@  ix86_minimum_incoming_stack_boundary (bool sibcall
   /* Prefer the one specified at command line. */
   if (ix86_user_incoming_stack_boundary)
     incoming_stack_boundary = ix86_user_incoming_stack_boundary;
-  /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
+  /* Use MIN_STACK_BOUNDARY for incoming stack boundary
      if -mstackrealign is used, it isn't used for sibcall check and
      estimated stack alignment is 128bit.  */
   else if (!sibcall
-	   && !TARGET_64BIT
 	   && ix86_force_align_arg_pointer
 	   && crtl->stack_alignment_estimated == 128)
     incoming_stack_boundary = MIN_STACK_BOUNDARY;
@@ -48050,7 +48067,7 @@  static const struct attribute_spec ix86_attribute_
     true },
   /* force_align_arg_pointer says this function realigns the stack at entry.  */
   { (const char *)&ix86_force_align_arg_pointer_string, 0, 0,
-    false, true,  true, ix86_handle_cconv_attribute, false },
+    false, true,  true, ix86_handle_force_align_arg_pointer_attribute, false },
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   { "dllimport", 0, 0, false, false, false, handle_dll_attribute, false },
   { "dllexport", 0, 0, false, false, false, handle_dll_attribute, false },
Index: config/i386/i386.h
===================================================================
--- config/i386/i386.h	(revision 228488)
+++ config/i386/i386.h	(working copy)
@@ -752,7 +752,7 @@  extern const char *host_detect_local_cpu (int argc
 #define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32)
 
 /* Minimum stack boundary.  */
-#define MIN_STACK_BOUNDARY (TARGET_64BIT ? (TARGET_SSE ? 128 : 64) : 32)
+#define MIN_STACK_BOUNDARY BITS_PER_WORD
 
 /* Boundary (in *bits*) on which the stack pointer prefers to be
    aligned; the compiler cannot rely on having this alignment.  */
Index: testsuite/gcc.target/i386/20060512-1.c
===================================================================
--- testsuite/gcc.target/i386/20060512-1.c	(revision 228488)
+++ testsuite/gcc.target/i386/20060512-1.c	(working copy)
@@ -1,5 +1,4 @@ 
 /* { dg-do run } */
-/* { dg-require-effective-target ia32 } */
 /* { dg-options "-std=gnu99 -msse2 -mpreferred-stack-boundary=4" } */
 /* { dg-require-effective-target sse2 } */
 
@@ -7,6 +6,14 @@ 
 
 #include <emmintrin.h>
 
+#ifdef __x86_64__
+# define PUSH "pushq %rsi"
+# define POP "popq %rsi"
+#else
+# define PUSH "pushl %esi"
+# define POP "popl %esi"
+#endif
+
 __m128i __attribute__ ((__noinline__))
 vector_using_function ()
 {
@@ -27,9 +34,9 @@  static void
 sse2_test (void)
 {
   int result;
-  asm ("pushl %esi");		/* Disalign runtime stack.  */
+  asm (PUSH);                  /* Misalign runtime stack.  */
   result = self_aligning_function (g_1, g_2);
   if (result != 42)
     abort ();
-  asm ("popl %esi");
+  asm (POP);
 }
Index: testsuite/gcc.target/i386/20060512-2.c
===================================================================
--- testsuite/gcc.target/i386/20060512-2.c	(revision 228488)
+++ testsuite/gcc.target/i386/20060512-2.c	(working copy)
@@ -1,5 +1,4 @@ 
 /* { dg-do compile } */
-/* { dg-require-effective-target ia32 } */
 /* { dg-options "-std=gnu99 -mpreferred-stack-boundary=4" } */
 int
 outer_function (int x, int y)