https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64242
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I wonder about following, on i686-linux it FAILs with older trunk and succeeds with current trunk. Without the (useless) stack realignment the right value of stack pointer happened to be in exactly that slot from which it read memory. While still not fully portable, I think if the two alloca (0) are more than 1024 bytes appart, something is wrong with the target or at least alloca is helplessly expensive there. --- gcc/testsuite/gcc.c-torture/execute/pr64242.c 2018-12-01 00:25:08.082009500 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr64242.c 2018-12-03 16:43:33.343875994 +0100 @@ -11,20 +11,40 @@ broken_longjmp(void *p) __builtin_longjmp (buf, 1); } +__attribute ((noipa)) __UINTPTR_TYPE__ +foo(void *p) +{ + return (__UINTPTR_TYPE__) p; +} + +__attribute ((noipa)) void +bar(void *p) +{ + asm volatile ("" : : "r" (p)); +} + volatile int x = 0; -volatile void *p; +void *volatile p; +void *volatile q; int main (void) { void *buf[5]; + struct __attribute__((aligned (32))) S { int a[4]; } s; + bar (&s); p = __builtin_alloca (x); - if (!__builtin_setjmp (buf)) broken_longjmp (buf); /* Fails if stack pointer corrupted. */ - if (p != __builtin_alloca (x)) - abort(); + q = __builtin_alloca (x); + if (foo (p) < foo (q)) + { + if (foo (q) - foo (p) >= 1024) + abort (); + } + else if (foo (p) - foo (q) >= 1024) + abort (); return 0; }