This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[i386] Enable -mstackrealign with SSE on 32-bit Windows


Hi,

even the latest versions of Windows still guarantee only a 4-byte alignment of 
the stack in 32-bit mode, which doesn't play nice with some SSE instructions.
That's why some projects enable -mstackrealign by default on 32-bit Windows:
  https://bugzilla.mozilla.org/show_bug.cgi?id=631252
This eliminates an entire class of bugs which are sometimes hard to reproduce.

The attached patch automatically enables it when SSE instructions are used.
That's a good compromise IMO because the default configuration of the compiler 
on this platform doesn't enable SSE so should presumably not be modified.

Tested on i686-pc-mingw32, OK for the mainline?


2015-12-15  Eric Botcazou  <ebotcazou@adacore.com>

	* config/i386/cygming.h (STACK_REALIGN_DEFAULT): Define.


2015-12-15  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.target/i386/stack-realign-win.c: New test.


-- 
Eric Botcazou
Index: config/i386/cygming.h
===================================================================
--- config/i386/cygming.h	(revision 231605)
+++ config/i386/cygming.h	(working copy)
@@ -39,6 +39,11 @@ along with GCC; see the file COPYING3.
 #undef MAX_STACK_ALIGNMENT
 #define MAX_STACK_ALIGNMENT  (TARGET_SEH ? 128 : MAX_OFILE_ALIGNMENT)
 
+/* 32-bit Windows aligns the stack on a 4-byte boundary but SSE instructions
+   may require 16-byte alignment.  */
+#undef STACK_REALIGN_DEFAULT
+#define STACK_REALIGN_DEFAULT TARGET_SSE
+
 /* Support hooks for SEH.  */
 #undef  TARGET_ASM_UNWIND_EMIT
 #define TARGET_ASM_UNWIND_EMIT  i386_pe_seh_unwind_emit
/* { dg-do compile { target *-*-mingw* *-*-cygwin* } } */
/* { dg-require-effective-target ia32 } */
/* { dg-options "-msse -O" } */

extern void abort (void);

typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));

static __m128
load_m128 (float *e)
{
  return * (__m128 *) e;
}

typedef union
{
  __m128  x;
  float a[4];
} union128;

void test (void)
{
  union128 u;
  float e[4] __attribute__ ((aligned (16)))
    = {2134.3343, 1234.635654, 1.2234, 876.8976};
  int i;

  u.x = load_m128 (e);

  for (i = 0; i < 4; i++)
    if (u.a[i] != e[i])
      abort ();
}

/* { dg-final { scan-assembler "andl\\t\\$-16, %esp" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]