Bug 58034 - [4.8/4.9 Regression] glibc nptl/tst-cleanup2 fail due to scheduling
Summary: [4.8/4.9 Regression] glibc nptl/tst-cleanup2 fail due to scheduling
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-31 00:21 UTC by Alan Modra
Modified: 2013-08-19 09:53 UTC (History)
4 users (show)

See Also:
Host:
Target: powerpc64-linux
Build:
Known to work: 4.7.2
Known to fail: 4.8.1, 4.8.2, 4.9.0
Last reconfirmed: 2013-07-31 00:00:00


Attachments
preprocessed test case (28.85 KB, text/plain)
2013-07-31 00:21 UTC, Alan Modra
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alan Modra 2013-07-31 00:21:33 UTC
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.
Comment 1 David Edelsohn 2013-07-31 13:59:17 UTC
Confirmed.
Comment 2 Andrew Pinski 2013-07-31 15:31:11 UTC
  if (_setjmp (jmpbuf))

I wonder if this is due to _setjmp not being marked as return twice.
Comment 3 David Edelsohn 2013-07-31 15:46:12 UTC
> I wonder if this is due to _setjmp not being marked as return twice.

Is that a missing decoration in the GLIBC declaration?
Comment 4 Andrew Pinski 2013-07-31 15:52:14 UTC
(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.
Comment 5 Alan Modra 2013-08-01 01:08:47 UTC
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;
}
Comment 6 jsm-csl@polyomino.org.uk 2013-08-06 23:00:47 UTC
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.)
Comment 7 Jakub Jelinek 2013-08-19 09:53:07 UTC
I agree this looks like a glibc test issue rather than gcc bug.