Fix PR48542: reload register contents reuse crossing setjmp

Jeff Law
Thu Jun 16 22:57:00 GMT 2011

Hash: SHA1

On 06/15/11 21:46, Hans-Peter Nilsson wrote:
> A generic bug found in one of the less common targets.  The MMIX
> port usually saves the return-address from the special-register rJ to
> a general call-saved register (helped by get_hard_reg_initial_val),
> restored to rJ immediately on return from the call.  I know, the
> "restore immediately on return" is odd and I don't remember exactly
> why I did it that way and not in the "return" insn; I might change that,
> but that's only incidental.  IRA dutifully refuses to allocate a
> register for the return-address seeing that it's live across the setjmp,
> but reload comes to the "rescue" and when fixing up the accesses to the
> resulting stack-slot, reuses the reload register across the setjmp, so
> the generated code looks just like an ordinary register allocation,
> save for the sometimes-unused stack-slot (in sjtest, completely
> unused; in sjtest3 just not used across the setjmp).  The test-case is
> slightly changed from the submitted original to avoid the
> miscompilation causing an endless loop and a test-timeout.
> There are two fixes, because when register contents is invalidated for
> the main path (the patch to reload1.c), there's fallback code (patch
> to reload.c) that also iterates over code, and which also lacks proper
> handling of setjmp-type calls.
> You will see this bug on other targets if you're unlucky enough to get
> a reuse of a register that held something live at the time of the
> setjmp but which died and the register reused for something else some
> time after the setjmp call but before the longjmp call, and the
> original value is live again after the second setjmp return.  This
> just naturally happens more often for MMIX (read: always when there's
> a temporary held in a register like the loop counter in the
> test-case), given that (set rJ (mem stack-slot)) is emitted after every
> call and always needs a reload through a general register, and is always
> reloaded from the same stack-slot.  A trivial attempt failed to come
> up with a test-case that fails for x86_64.
> When working on the test-case, I noticed IPA discovering the
> noreturn-ness of (calls to) functions calling longjmp but which were
> declared noinline; naturally I didn't want gcc to look at the called
> function or assume anything of its contents.  Adding attribute weak
> helped, but that's a kludge that LTO will (at some time) see through.
> So, isn't there now a need for a "noipa" attribute?  (Better call it
> "extern" or "foreign" or some other color to avoid leaking internal
> terms.)  The attribute would create the effect of a function that gcc
> doesn't inspect (or really, ignores knowledge at calls), so we can
> keep having self-contained tests in a single-file now and for future
> IPA-like improvements.
> Regtested mmix all open branches and native x86_64-linux trunk.
> Ok?
> For all open branches (after native regtesting)?
> gcc/testsuite:
> 	PR rtl-optimization/48542
> 	* gcc.dg/torture/pr48542.c: New test.
> gcc:
> 	PR rtl-optimization/48542
> 	* reload.c (find_equiv_reg): Stop looking when finding a
> 	setjmp-type call.
> 	* reload1.c (reload_as_needed): Invalidate all reload
> 	registers when crossing a setjmp-type call.
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora -


More information about the Gcc-patches mailing list