[Bug target/83368] alloca after setjmp breaks PIC base reg

2019-02-04 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #20 from Eric Botcazou  ---
> Thanks for the fix; is this a candidate for backporting to the gcc-7 branch?
> If not we can just carry it in Debian, but it would be nicer to have it
> upstream.

Sorry, it looks like I missed this message too...  In any case, the change was
not really appropriate for a backport.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2018-01-24 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #19 from James Clarke  ---
Thanks for the fix; is this a candidate for backporting to the gcc-7 branch? If
not we can just carry it in Debian, but it would be nicer to have it upstream.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2018-01-12 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED
   Target Milestone|--- |8.0

--- Comment #18 from Eric Botcazou  ---
Fixed on the mainline.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2018-01-12 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #17 from Eric Botcazou  ---
Author: ebotcazou
Date: Fri Jan 12 11:29:30 2018
New Revision: 256575

URL: https://gcc.gnu.org/viewcvs?rev=256575=gcc=rev
Log:
PR target/83368
* config/sparc/sparc.h (PIC_OFFSET_TABLE_REGNUM): Set to INVALID_REGNUM
in PIC mode except for TARGET_VXWORKS_RTP.
* config/sparc/sparc.c: Include cfgrtl.h.
(TARGET_INIT_PIC_REG): Define.
(TARGET_USE_PSEUDO_PIC_REG): Likewise.
(sparc_pic_register_p): New predicate.
(sparc_legitimate_address_p): Use it.
(sparc_legitimize_pic_address): Likewise.
(sparc_delegitimize_address): Likewise.
(sparc_mode_dependent_address_p): Likewise.
(gen_load_pcrel_sym): Remove 4th parameter.
(load_got_register): Adjust call to above.  Remove obsolete stuff.
(sparc_expand_prologue): Do not call load_got_register here.
(sparc_flat_expand_prologue): Likewise.
(sparc_output_mi_thunk): Set the pic_offset_table_rtx object.
(sparc_use_pseudo_pic_reg): New function.
(sparc_init_pic_reg): Likewise.
* config/sparc/sparc.md (vxworks_load_got): Set the GOT register.
(builtin_setjmp_receiver): Enable only for TARGET_VXWORKS_RTP.

Added:
trunk/gcc/testsuite/gcc.target/sparc/setjmp-1.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/config/sparc/sparc.c
trunk/gcc/config/sparc/sparc.h
trunk/gcc/config/sparc/sparc.md

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |ebotcazou at gcc dot 
gnu.org

--- Comment #16 from Eric Botcazou  ---
Investigating.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|RESOLVED|NEW
 Resolution|WONTFIX |---

--- Comment #15 from Eric Botcazou  ---
> It's true that, as far as I'm aware, no other architecture has this issue,
> as either the PIC register is caller-saved, or it gets saved by setjmp.

OK, that was my understanding too.

> However the original SPARC library authors clearly thought of this and
> decided it was the responsibility of the compiler to not rely on input or
> local registers being preserved given their explicit note in SCD, so whether
> or not you believe that this was a good idea, that's what they chose and
> what we currently have, and GCC is not adhering to that. Sure, it would be
> nice if the registers were saved by setjmp, but it's documented behaviour
> and thus not a bug as such in glibc nor Solaris's libc.

Fair enough, let's bow to SCD's wisdom then. ;-)

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #14 from James Clarke  ---
(In reply to Eric Botcazou from comment #12)
> > Can't be done without an ABI break. But it is just the PIC register, and I'm
> > still of the view this is a GCC bug. You seem to not be listening to my
> > arguments and just reciting that "setjmp must save call-saved registers",
> > which would be nice if it were true, but that's not what actually happens,
> > and GCC already tries to handle this; it just misses a case on SPARC.
> 
> OK, let's see it the other way around: how does it work on other
> architectures?  Does GCC save and restore the PIC register or it is
> preserved through the call to setjmp?

It's true that, as far as I'm aware, no other architecture has this issue, as
either the PIC register is caller-saved, or it gets saved by setjmp. However
the original SPARC library authors clearly thought of this and decided it was
the responsibility of the compiler to not rely on input or local registers
being preserved given their explicit note in SCD, so whether or not you believe
that this was a good idea, that's what they chose and what we currently have,
and GCC is not adhering to that. Sure, it would be nice if the registers were
saved by setjmp, but it's documented behaviour and thus not a bug as such in
glibc nor Solaris's libc.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #13 from James Clarke  ---
(In reply to Eric Botcazou from comment #11)
> > > Again you're wrong, the call-saved registers are properly preserved if you
> > > don't clobber the stack pointer, just write a small test or simply tweak
> > > yours.
> > 
> > Yes, I know that.
> 
> OK, at least something we agree on. :-)
> 
> > But GCC doesn't rely on that for *any other use* of the input and local 
> > registers; they are spilled to the stack and reloaded after the setjmp when
> > needed.
> 
> No, that's also wrong, try:
> 
> int main(void)
> {
>   register int i asm ("l0") = 1;
>   setjmp(jb);
>   printf("%d\n", i);
> 
>   if (c < 10)
> bar();
> 
>   return 0;
> }
> 
> main:
> save%sp, -176, %sp
> mov 1, %l0
> sethi   %hi(jb), %g1
> or  %g1, %lo(jb), %o0
> call_setjmp, 0
>  nop
> mov %l0, %g1
> sra %g1, 0, %g1
> mov %g1, %o1
> sethi   %hi(.LC0), %g1
> or  %g1, %lo(.LC0), %o0
> callprintf, 0
>  nop
> 
> GCC really expects all call-saved registers to be preserved.

That's a bad example; if you change "l0" to "o5", GCC will still let you do it,
and doesn't spill the value anywhere either. GCC assumes if you give a
register, you know that the register really won't be clobbered by any function
calls in between. Yes you might not be aware of the issue with setjmp in this
instance, but that's your problem if you write this code.

> > Also the fact that alloca clobbers the stack pointer
> > is an implementation detail; for example, LLVM allocates all the space up
> > front in the function prologue in this case, which means it would not run
> > into this issue (and in fact it also spills its PIC base register).
> 
> This should also work with libc's alloca and it clobbers the stack pointer.

Ok, true.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #12 from Eric Botcazou  ---
> Can't be done without an ABI break. But it is just the PIC register, and I'm
> still of the view this is a GCC bug. You seem to not be listening to my
> arguments and just reciting that "setjmp must save call-saved registers",
> which would be nice if it were true, but that's not what actually happens,
> and GCC already tries to handle this; it just misses a case on SPARC.

OK, let's see it the other way around: how does it work on other architectures?
 Does GCC save and restore the PIC register or it is preserved through the call
to setjmp?

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #11 from Eric Botcazou  ---
> > Again you're wrong, the call-saved registers are properly preserved if you
> > don't clobber the stack pointer, just write a small test or simply tweak
> > yours.
> 
> Yes, I know that.

OK, at least something we agree on. :-)

> But GCC doesn't rely on that for *any other use* of the input and local 
> registers; they are spilled to the stack and reloaded after the setjmp when
> needed.

No, that's also wrong, try:

int main(void)
{
  register int i asm ("l0") = 1;
  setjmp(jb);
  printf("%d\n", i);

  if (c < 10)
bar();

  return 0;
}

main:
save%sp, -176, %sp
mov 1, %l0
sethi   %hi(jb), %g1
or  %g1, %lo(jb), %o0
call_setjmp, 0
 nop
mov %l0, %g1
sra %g1, 0, %g1
mov %g1, %o1
sethi   %hi(.LC0), %g1
or  %g1, %lo(.LC0), %o0
callprintf, 0
 nop

GCC really expects all call-saved registers to be preserved.

> Also the fact that alloca clobbers the stack pointer
> is an implementation detail; for example, LLVM allocates all the space up
> front in the function prologue in this case, which means it would not run
> into this issue (and in fact it also spills its PIC base register).

This should also work with libc's alloca and it clobbers the stack pointer.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #10 from James Clarke  ---
(In reply to James Clarke from comment #9)
> (In reply to Eric Botcazou from comment #7)
> > > And for what it's worth, 32-bit Solaris/SPARC's setjmp isn't saving any of
> > > the caller's input or local registers either, so it's not glibc-specific.
> > 
> > Again you're wrong, the call-saved registers are properly preserved if you
> > don't clobber the stack pointer, just write a small test or simply tweak
> > yours.
> 
> Yes, I know that. But GCC doesn't rely on that for *any other use* of the
> input and local registers; they are spilled to the stack and reloaded after
> the setjmp when needed. Also the fact that alloca clobbers the stack pointer
> is an implementation detail; for example, LLVM allocates all the space up
> front in the function prologue in this case, which means it would not run
> into this issue (and in fact it also spills its PIC base register).

(In reply to Eric Botcazou from comment #8)
> > You already have code in sched-deps.c to deal with setjmp potentially not
> > saving registers it should across all architectures:
> > 
> >   if (find_reg_note (insn, REG_SETJMP, NULL))
> > {
> >   /* This is setjmp.  Assume that all registers, not just
> >  hard registers, may be clobbered by this call.  */
> >   reg_pending_barrier = MOVE_BARRIER;
> > }
> 
> GCC expects all call-saved registers to be preserved by setjmp/longjmp
> though and I think that's what is implemented in glibc for other
> architectures.

No, it doesn't. Try it yourself. Make a local variable live across a setjmp
call, and even under -O3 you will see it spilled to the stack and reloaded
after setjmp returns.

> > Why is it so hard to fix this bug? It's a very simple problem that only
> > affects %l7; all it needs is for it to be spilled and reloaded.
> 
> Because it's a call-saved register.

Not for setjmp, but this is where we disagree.

> > This is breaking real-world code that works on every other architecture I 
> > have
> > tried it on, and telling people to use non-portable built-in functions 
> > isn't 
> > going to necessarily be well-received.
> 
> Then you need to convince someone to fix glibc and make setjmp/longjmp
> preserve call-saved registers even if the stack pointer is subsequently
> clobbered.  Or maybe just the PIC register, but I think it's only the tip of
> the iceberg.

Can't be done without an ABI break. But it is just the PIC register, and I'm
still of the view this is a GCC bug. You seem to not be listening to my
arguments and just reciting that "setjmp must save call-saved registers", which
would be nice if it were true, but that's not what actually happens, and GCC
already tries to handle this; it just misses a case on SPARC.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #9 from James Clarke  ---
(In reply to Eric Botcazou from comment #7)
> > And for what it's worth, 32-bit Solaris/SPARC's setjmp isn't saving any of
> > the caller's input or local registers either, so it's not glibc-specific.
> 
> Again you're wrong, the call-saved registers are properly preserved if you
> don't clobber the stack pointer, just write a small test or simply tweak
> yours.

Yes, I know that. But GCC doesn't rely on that for *any other use* of the input
and local registers; they are spilled to the stack and reloaded after the
setjmp when needed. Also the fact that alloca clobbers the stack pointer is an
implementation detail; for example, LLVM allocates all the space up front in
the function prologue in this case, which means it would not run into this
issue (and in fact it also spills its PIC base register).

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #8 from Eric Botcazou  ---
> You already have code in sched-deps.c to deal with setjmp potentially not
> saving registers it should across all architectures:
> 
>   if (find_reg_note (insn, REG_SETJMP, NULL))
> {
>   /* This is setjmp.  Assume that all registers, not just
>  hard registers, may be clobbered by this call.  */
>   reg_pending_barrier = MOVE_BARRIER;
> }

GCC expects all call-saved registers to be preserved by setjmp/longjmp though
and I think that's what is implemented in glibc for other architectures.

> Why is it so hard to fix this bug? It's a very simple problem that only
> affects %l7; all it needs is for it to be spilled and reloaded.

Because it's a call-saved register.

> This is breaking real-world code that works on every other architecture I have
> tried it on, and telling people to use non-portable built-in functions isn't 
> going to necessarily be well-received.

Then you need to convince someone to fix glibc and make setjmp/longjmp preserve
call-saved registers even if the stack pointer is subsequently clobbered.  Or
maybe just the PIC register, but I think it's only the tip of the iceberg.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|REOPENED|RESOLVED
 Resolution|--- |WONTFIX

--- Comment #7 from Eric Botcazou  ---
> And for what it's worth, 32-bit Solaris/SPARC's setjmp isn't saving any of
> the caller's input or local registers either, so it's not glibc-specific.

Again you're wrong, the call-saved registers are properly preserved if you
don't clobber the stack pointer, just write a small test or simply tweak yours.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

--- Comment #6 from James Clarke  ---
And for what it's worth, 32-bit Solaris/SPARC's setjmp isn't saving any of the
caller's input or local registers either, so it's not glibc-specific.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

James Clarke  changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|WONTFIX |---

--- Comment #5 from James Clarke  ---
(In reply to Eric Botcazou from comment #4)
> > Therefore, I am of the view that this should be reopened as a bug in GCC.
> > GCC already spills local variables live across a setjmp to the stack (as it
> > can't use input or local registers due to the above note); it should be
> > doing the same for %l7.
> 
> No, setjmp/longjmp must preserve the call-saved registers and it does in
> almost all cases, both on Linux and Solaris.

You already have code in sched-deps.c to deal with setjmp potentially not
saving registers it should across all architectures:

  if (find_reg_note (insn, REG_SETJMP, NULL))
{
  /* This is setjmp.  Assume that all registers, not just
 hard registers, may be clobbered by this call.  */
  reg_pending_barrier = MOVE_BARRIER;
}

Why is it so hard to fix this bug? It's a very simple problem that only affects
%l7; all it needs is for it to be spilled and reloaded. This is breaking
real-world code that works on every other architecture I have tried it on, and
telling people to use non-portable built-in functions isn't going to
necessarily be well-received.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|REOPENED|RESOLVED
 Resolution|--- |WONTFIX

--- Comment #4 from Eric Botcazou  ---
> Therefore, I am of the view that this should be reopened as a bug in GCC.
> GCC already spills local variables live across a setjmp to the stack (as it
> can't use input or local registers due to the above note); it should be
> doing the same for %l7.

No, setjmp/longjmp must preserve the call-saved registers and it does in almost
all cases, both on Linux and Solaris.  But you're clobbering the stack pointer
after calling setjmp and this cannot reasonably work on SPARC because of the
way setjmp/longjmp is implemented for this architecture.

Let's declare this as WONTFIX; you can use __builtin_setjmp/longjmp instead.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-18 Thread jrtc27 at jrtc27 dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

James Clarke  changed:

   What|Removed |Added

 Status|RESOLVED|REOPENED
 Resolution|INVALID |---

--- Comment #3 from James Clarke  ---
(In reply to Eric Botcazou from comment #2)
> It's a glibc bug, setjmp doesn't preserve %l7.

I filed [1], but having gone away and thought about this, I don't think it is.
SPARC Compliance Definition 2.4.1 specifically calls this out (page 47 or 3P-11
in my PDF), with:

"There are some routines, like setjmp(), sigsetjmp(), and vfork(), that require
the caller assume the registers %l0 through %l7, and %i0 through %i5 are
volatile across the call."

Therefore, I am of the view that this should be reopened as a bug in GCC. GCC
already spills local variables live across a setjmp to the stack (as it can't
use input or local registers due to the above note); it should be doing the
same for %l7.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=22604

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-12 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--- Comment #2 from Eric Botcazou  ---
It's a glibc bug, setjmp doesn't preserve %l7.

[Bug target/83368] alloca after setjmp breaks PIC base reg

2017-12-12 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83368

Eric Botcazou  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-12-12
 CC||ebotcazou at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #1 from Eric Botcazou  ---
builtin_setjmp_receiver has simply nothing to do with setjmp/longjmp.