Created attachment 30575 [details] preprocessed test case nprl/tst-cleanup2 fails when compiled with -O2 -mcpu=power6 due to sched1 moving an assignment to a REG over code that traps. The relevant test case source: if (setjmp (jmpbuf)) { puts ("Exiting main..."); return 0; } sprintf (p, "This should segv\n"); return 1; } The sprintf is optimised to three loads and stores. The problem occurs due to the assignment of 1 to the REG holding the function return value being scheduled before the sprintf expansion.
Confirmed.
if (_setjmp (jmpbuf)) I wonder if this is due to _setjmp not being marked as return twice.
> I wonder if this is due to _setjmp not being marked as return twice. Is that a missing decoration in the GLIBC declaration?
(In reply to Andrew Pinski from comment #2) > if (_setjmp (jmpbuf)) > > I wonder if this is due to _setjmp not being marked as return twice. Looking at special_function_p, it should return ECF_RETURNS_TWICE for that decl if I read the code correctly as it disregards the _ and then matches setjmp.
This somewhat reduced testcase fails with mainline. #include <setjmp.h> #include <signal.h> static sigjmp_buf jmpbuf; static void sig_handler (int signo) { siglongjmp (jmpbuf, 1); } int main (void) { char *p = 0; struct sigaction sa; sa.sa_handler = sig_handler; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction (SIGSEGV, &sa, 0)) return 1; if (setjmp (jmpbuf)) return 0; __builtin_memcpy (p, "abc", 4); return 1; }
On Wed, 31 Jul 2013, amodra at gmail dot com wrote: > The relevant test case source: > > if (setjmp (jmpbuf)) > { > puts ("Exiting main..."); > return 0; > } > > sprintf (p, "This should segv\n"); > > return 1; > } > > The sprintf is optimised to three loads and stores. The problem occurs due to > the assignment of 1 to the REG holding the function return value being > scheduled before the sprintf expansion. Well, in valid code this sprintf can't trap (sprintf using glibc extensions to register format extensions might). Optimizing to three loads and stores, and then scheduling them, seems a valid optimization to me. Does -fnon-call-exceptions help? (Though I'd prefer -fno-builtin-sprintf as a fix for the glibc test.)
I agree this looks like a glibc test issue rather than gcc bug.