This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 10 Aug 2010 06:35:04 -0700
- Subject: 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
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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.
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;
+}