Patchwork PATCH: PR middle-end/45234: [4.4/4.5/4.6 Regression] ICE in expand_call, at calls.c:2845 when passing aligned function argument from unaligned stack after alloca

login
register
mail settings
Submitter H.J. Lu
Date Aug. 10, 2010, 1:35 p.m.
Message ID <20100810133503.GA26174@intel.com>
Download mbox | patch
Permalink /patch/61379/
State New
Headers show

Comments

H.J. Lu - Aug. 10, 2010, 1:35 p.m.
Hi,

All variable sized adjustments must be multiple of preferred stack
boundary.  Stack alignment may change preferred stack boundary after
variable sized adjustments have been made.  We need to compensate it.
OK if it passes regresion test on Linux/ia32 and Linux/x86-64?

Thanks.


H.J.
---
gcc/

2010-08-10  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/45234
	* calls.c (expand_call): Make sure that all variable sized
	adjustments are multiple of preferred stack boundary after
	stack alignment.

gcc/testsuite/

2010-08-10  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/45234
	* gcc.dg/torture/stackalign/alloca-5.c: New.
H.J. Lu - Aug. 16, 2010, 4:09 p.m.
On Tue, Aug 10, 2010 at 6:35 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> Hi,
>
> All variable sized adjustments must be multiple of preferred stack
> boundary.  Stack alignment may change preferred stack boundary after
> variable sized adjustments have been made.  We need to compensate it.
> OK if it passes regresion test on Linux/ia32 and Linux/x86-64?
>
> Thanks.
>
>
> H.J.
> ---
> gcc/
>
> 2010-08-10  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR middle-end/45234
>        * calls.c (expand_call): Make sure that all variable sized
>        adjustments are multiple of preferred stack boundary after
>        stack alignment.
>
> gcc/testsuite/
>
> 2010-08-10  H.J. Lu  <hongjiu.lu@intel.com>
>
>        PR middle-end/45234
>        * gcc.dg/torture/stackalign/alloca-5.c: New.
>

It has no regressions on Linux/ia32 and Linux/x86-64? OK for
trunk?

Patch

diff --git a/gcc/calls.c b/gcc/calls.c
index cd0d9c5..83fa046 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2377,6 +2377,18 @@  expand_call (tree exp, rtx target, int ignore)
 
   preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
 
+  if (SUPPORTS_STACK_ALIGNMENT)
+    {
+      /* All variable sized adjustments must be multiple of preferred
+	 stack boundary.  Stack alignment may change preferred stack
+	 boundary after variable sized adjustments have been made.  We
+	 need to compensate it here.  */
+      unsigned HOST_WIDE_INT delta
+	= (stack_pointer_delta % preferred_unit_stack_boundary);
+      if (delta)
+	anti_adjust_stack (GEN_INT (preferred_unit_stack_boundary - delta));
+    }
+
   /* We want to make two insn chains; one for a sibling call, the other
      for a normal call.  We will select one of the two chains after
      initial RTL generation is complete.  */
--- /dev/null	2010-07-23 13:04:30.193381062 -0700
+++ gcc/gcc/testsuite/gcc.dg/torture/stackalign/alloca-5.c	2010-08-10 06:29:57.308629935 -0700
@@ -0,0 +1,32 @@ 
+/* PR middle-end/45234 */
+/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-m32 -mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */
+
+#include "check.h"
+
+void
+__attribute__ ((noinline))
+bar (__float128 f)
+{
+  check (&f, __alignof__(f));
+}
+
+int
+main (void)
+{
+  char *p = __builtin_alloca (6);
+
+  bar (0);
+
+  __builtin_strncpy (p, "good", 5);
+  if (__builtin_strncmp (p, "good", 5) != 0)
+    {
+#ifdef DEBUG
+      p[size] = '\0';
+      printf ("Failed: %s != good\n", p);
+#endif
+     abort ();
+    }
+
+  return 0;
+}