diff mbox

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

Message ID 20100810133503.GA26174@intel.com
State New
Headers show

Commit Message

H.J. Lu Aug. 10, 2010, 1:35 p.m. UTC
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.

Comments

H.J. Lu Aug. 16, 2010, 4:09 p.m. UTC | #1
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?
diff mbox

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;
+}