public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* non-volatile automatic variables in setjmp tests
@ 2019-04-05 10:50 Jozef Lawrynowicz
  2019-04-05 16:25 ` Michael Matz
  0 siblings, 1 reply; 7+ messages in thread
From: Jozef Lawrynowicz @ 2019-04-05 10:50 UTC (permalink / raw)
  To: gcc

Some setjmp/longjmp tests[1] depend on the value of an auto set before setjmp
to to be retained after returning from the longjmp. As I understand, this
behaviour is actually undefined, according to the gccint manual.

Section 3 "Interfacing to GCC Output" of gccint says:
  If you use longjmp, beware of automatic variables. ISO C says that automatic
  variables that are not declared volatile have undefined values after a
  longjmp. And this is all GCC promises to do, because it is very difficult to
  restore register variables correctly, and one of GCC’s features is that it
  can put variables in registers without your asking it to.
  
However, ISO C says [2]:
  ... values of objects of automatic storage duration are unspecified if they
  meet all the following conditions:
  * They are local to the function containing the corresponding setjmp()
    invocation.
  * They do not have volatile-qualified type.
  * They are changed between the setjmp() invocation and longjmp() call.

Technically this third condition is not satisfied in these tests, as the auto
variable is not modified between the setjmp and longjmp calls. But I'm assuming
the gccint manual overrides this.

gcc.dg/torture/stackalign/setjmp-1.c and
gcc.c-torture/execute/built-in-setjmp.c actually fail at execution for
msp430-elf @ -O1, because the auto being tested after the longjmp has not been
restored correctly.
These tests feature a contrived way of making the auto appear used up to the
longjmp, so I wonder if they have been written deliberately without a
volatile, or if it was just an oversight.
For msp430-elf @ -O1, this code to make the auto appear used is ineffective as
an optimization replaces the variable with a constant, which is what
triggers the test failure.

Are these tests that rely on the value of a non-volatile auto after a longjmp
invalid? I can patch them to make the auto variable a global instead.

Thanks,
Jozef

[1] The C setjmp/longjmp tests using autos:
gcc.c-torture/execute/built-in-setjmp.c
gcc.c-torture/execute/pr60003.c
gcc.dg/torture/pr66101.c
gcc.dg/torture/stackalign/setjmp-4.c
gcc.dg/torture/stackalign/setjmp-3.c
gcc.dg/torture/stackalign/setjmp-1.c
gcc.dg/torture/pr48542.c
gcc.dg/setjmp-4.c
gcc.dg/setjmp-3.c
gcc.dg/tree-prof/pr34999.c
gcc.dg/tree-ssa/pr79803.c

[2] http://pubs.opengroup.org/onlinepubs/009695399/functions/longjmp.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-05 10:50 non-volatile automatic variables in setjmp tests Jozef Lawrynowicz
@ 2019-04-05 16:25 ` Michael Matz
  2019-04-08  9:16   ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Matz @ 2019-04-05 16:25 UTC (permalink / raw)
  To: Jozef Lawrynowicz; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 3074 bytes --]

Hello,

On Fri, 5 Apr 2019, Jozef Lawrynowicz wrote:

> Some setjmp/longjmp tests[1] depend on the value of an auto set before setjmp
> to to be retained after returning from the longjmp. As I understand, this
> behaviour is actually undefined, according to the gccint manual.
> 
> Section 3 "Interfacing to GCC Output" of gccint says:
>   If you use longjmp, beware of automatic variables. ISO C says that automatic
>   variables that are not declared volatile have undefined values after a
>   longjmp. And this is all GCC promises to do, because it is very difficult to
>   restore register variables correctly, and one of GCC’s features is that it
>   can put variables in registers without your asking it to.

That is very old text, from 1997, and doesn't reflect what GCC actually 
does, which is ...

> However, ISO C says [2]:
>   ... values of objects of automatic storage duration are unspecified if they
>   meet all the following conditions:
>   * They are local to the function containing the corresponding setjmp()
>     invocation.
>   * They do not have volatile-qualified type.
>   * They are changed between the setjmp() invocation and longjmp() call.

... supporting this (and in any case if there's a direct conflict between 
the GCC docu and a relevant standard, then the former is likely the wrong 
one).  The are two modi: (a) the target has a setjmp/longjmp combination 
which restores all callee-saved registers (to the values at just before 
the setjmp call) and (b) the target doesn't save all these.

For (a) GCC treats the setjmp call as a normal function call from a 
register-clobber perspective, so any auto variable live over the 
setjmp that is stored in a callee-saved register is restored to the 
pre-setjmp value.

For (b) GCC makes sure to not allocate variables live over setjmp to 
registers.  This is the conservative assumption.

Most targets in GCC follow the (b) model, even though the specific 
setjmp/longjmp mechanism would allow for (a).

> gcc.dg/torture/stackalign/setjmp-1.c and
> gcc.c-torture/execute/built-in-setjmp.c actually fail at execution for
> msp430-elf @ -O1, because the auto being tested after the longjmp has not been
> restored correctly.

So the testcases should indeed work without volatile and you need to 
investigate why the restoring doesn't happen correctly.

> These tests feature a contrived way of making the auto appear used up to the
> longjmp, so I wonder if they have been written deliberately without a
> volatile, or if it was just an oversight.
> 
> For msp430-elf @ -O1, this code to make the auto appear used is 
> ineffective as an optimization replaces the variable with a constant, 
> which is what triggers the test failure.

Well, then it should be the correct constant, and hence be unaffected by 
setjmp/longjmp, so if that still doesn't work the constant is wrong, 
right?

> Are these tests that rely on the value of a non-volatile auto after a 
> longjmp invalid? I can patch them to make the auto variable a global 
> instead.

No, they should work as is.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-05 16:25 ` Michael Matz
@ 2019-04-08  9:16   ` Richard Biener
  2019-04-08 12:31     ` Michael Matz
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2019-04-08  9:16 UTC (permalink / raw)
  To: Michael Matz; +Cc: Jozef Lawrynowicz, GCC Development

On Fri, Apr 5, 2019 at 6:25 PM Michael Matz <matz@suse.de> wrote:
>
> Hello,
>
> On Fri, 5 Apr 2019, Jozef Lawrynowicz wrote:
>
> > Some setjmp/longjmp tests[1] depend on the value of an auto set before setjmp
> > to to be retained after returning from the longjmp. As I understand, this
> > behaviour is actually undefined, according to the gccint manual.
> >
> > Section 3 "Interfacing to GCC Output" of gccint says:
> >   If you use longjmp, beware of automatic variables. ISO C says that automatic
> >   variables that are not declared volatile have undefined values after a
> >   longjmp. And this is all GCC promises to do, because it is very difficult to
> >   restore register variables correctly, and one of GCC’s features is that it
> >   can put variables in registers without your asking it to.
>
> That is very old text, from 1997, and doesn't reflect what GCC actually
> does, which is ...
>
> > However, ISO C says [2]:
> >   ... values of objects of automatic storage duration are unspecified if they
> >   meet all the following conditions:
> >   * They are local to the function containing the corresponding setjmp()
> >     invocation.
> >   * They do not have volatile-qualified type.
> >   * They are changed between the setjmp() invocation and longjmp() call.
>
> ... supporting this (and in any case if there's a direct conflict between
> the GCC docu and a relevant standard, then the former is likely the wrong
> one).  The are two modi: (a) the target has a setjmp/longjmp combination
> which restores all callee-saved registers (to the values at just before
> the setjmp call) and (b) the target doesn't save all these.
>
> For (a) GCC treats the setjmp call as a normal function call from a
> register-clobber perspective, so any auto variable live over the
> setjmp that is stored in a callee-saved register is restored to the
> pre-setjmp value.
>
> For (b) GCC makes sure to not allocate variables live over setjmp to
> registers.  This is the conservative assumption.
>
> Most targets in GCC follow the (b) model, even though the specific
> setjmp/longjmp mechanism would allow for (a).
>
> > gcc.dg/torture/stackalign/setjmp-1.c and
> > gcc.c-torture/execute/built-in-setjmp.c actually fail at execution for
> > msp430-elf @ -O1, because the auto being tested after the longjmp has not been
> > restored correctly.
>
> So the testcases should indeed work without volatile and you need to
> investigate why the restoring doesn't happen correctly.

There's one known "hole" in that the abnormal edges created to support all
of the above on GIMPLE are thrown away at RTL expansion time and
expected to be re-created "properly" but that doesn't actually happen.

The proper fix is to not throw them away but carry them over (with the
additional complication that you have to deal with that
find-many-sub-basic-block
case in some way).

Not sure if in this case we run into an RTL optimization that breaks things
(PRE / scheduling / invariant motion are candidates).

> > These tests feature a contrived way of making the auto appear used up to the
> > longjmp, so I wonder if they have been written deliberately without a
> > volatile, or if it was just an oversight.
> >
> > For msp430-elf @ -O1, this code to make the auto appear used is
> > ineffective as an optimization replaces the variable with a constant,
> > which is what triggers the test failure.
>
> Well, then it should be the correct constant, and hence be unaffected by
> setjmp/longjmp, so if that still doesn't work the constant is wrong,
> right?
>
> > Are these tests that rely on the value of a non-volatile auto after a
> > longjmp invalid? I can patch them to make the auto variable a global
> > instead.
>
> No, they should work as is.
>
>
> Ciao,
> Michael.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-08  9:16   ` Richard Biener
@ 2019-04-08 12:31     ` Michael Matz
  2019-04-08 12:45       ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Matz @ 2019-04-08 12:31 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jozef Lawrynowicz, GCC Development

Hi,

On Mon, 8 Apr 2019, Richard Biener wrote:

> Not sure if in this case we run into an RTL optimization that breaks things
> (PRE / scheduling / invariant motion are candidates).

That's true, what Josef sees might point to a genuine bug in the 
middle-end observed only on msp430; but we do want to make this situation 
work generally, as required by ISO C, not like how it's spelled in our 
manual.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-08 12:31     ` Michael Matz
@ 2019-04-08 12:45       ` Richard Biener
  2019-04-08 13:00         ` Jozef Lawrynowicz
  0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2019-04-08 12:45 UTC (permalink / raw)
  To: Michael Matz; +Cc: Jozef Lawrynowicz, GCC Development

On Mon, Apr 8, 2019 at 2:31 PM Michael Matz <matz@suse.de> wrote:
>
> Hi,
>
> On Mon, 8 Apr 2019, Richard Biener wrote:
>
> > Not sure if in this case we run into an RTL optimization that breaks things
> > (PRE / scheduling / invariant motion are candidates).
>
> That's true, what Josef sees might point to a genuine bug in the
> middle-end observed only on msp430; but we do want to make this situation
> work generally, as required by ISO C, not like how it's spelled in our
> manual.

Yes, and there's at least one existing bug, PR57067 for which it was
observed the scheduler genrates wrong-code.

Richard.

>
> Ciao,
> Michael.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-08 12:45       ` Richard Biener
@ 2019-04-08 13:00         ` Jozef Lawrynowicz
  2019-04-09 21:04           ` Jozef Lawrynowicz
  0 siblings, 1 reply; 7+ messages in thread
From: Jozef Lawrynowicz @ 2019-04-08 13:00 UTC (permalink / raw)
  To: Richard Biener; +Cc: Michael Matz, GCC Development

On Mon, 8 Apr 2019 14:45:17 +0200
Richard Biener <richard.guenther@gmail.com> wrote:

> On Mon, Apr 8, 2019 at 2:31 PM Michael Matz <matz@suse.de> wrote:
> >
> > Hi,
> >
> > On Mon, 8 Apr 2019, Richard Biener wrote:
> >  
> > > Not sure if in this case we run into an RTL optimization that breaks things
> > > (PRE / scheduling / invariant motion are candidates).  
> >
> > That's true, what Josef sees might point to a genuine bug in the
> > middle-end observed only on msp430; but we do want to make this situation
> > work generally, as required by ISO C, not like how it's spelled in our
> > manual.  
> 
> Yes, and there's at least one existing bug, PR57067 for which it was
> observed the scheduler genrates wrong-code.
> 
> Richard.
> 
> >
> > Ciao,
> > Michael.  

Thank you both for the information.

I'm still digging to find the cause of the failure, but I think it's a bug in
reload rather than an earlier pass having issues with setjmp/longjmp. The RTL
up to reload looks good to me. Also when I managed to coerce a build of GCC to
complete with LRA enabled for msp430, the test passed.

It was r255136 that exposed the failure by replacing usage of a variable with
a constant. Taking that optimization into account I'm now trying to find
which earlier commit exposed/caused the failure, as the test works with
r247017 when GCC8 development started on trunk. But that might just be because
the RTL when we get to reload is different, and doesn't expose the bug.

I'll file a bugzilla once I have more concrete details.

Jozef

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: non-volatile automatic variables in setjmp tests
  2019-04-08 13:00         ` Jozef Lawrynowicz
@ 2019-04-09 21:04           ` Jozef Lawrynowicz
  0 siblings, 0 replies; 7+ messages in thread
From: Jozef Lawrynowicz @ 2019-04-09 21:04 UTC (permalink / raw)
  To: Richard Biener; +Cc: Michael Matz, GCC Development

On Mon, 8 Apr 2019 14:00:39 +0100
Jozef Lawrynowicz <jozefl.gcc@gmail.com> wrote:

> I'll file a bugzilla once I have more concrete details.
> 
> Jozef

I filed BZ90032 for what I believe to be a bug during the reload pass.

Jozef

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-04-09 21:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-05 10:50 non-volatile automatic variables in setjmp tests Jozef Lawrynowicz
2019-04-05 16:25 ` Michael Matz
2019-04-08  9:16   ` Richard Biener
2019-04-08 12:31     ` Michael Matz
2019-04-08 12:45       ` Richard Biener
2019-04-08 13:00         ` Jozef Lawrynowicz
2019-04-09 21:04           ` Jozef Lawrynowicz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).