------- Comment #4 from wilson at gcc dot gnu dot org  2005-12-02 02:24 -------
The spurious warning is a problem because binutils is compiled by -Werror by
default now, when compiled by gcc.  This spurious warning thus causes a build
failure for binutils.  This build failure does not show up in a native
ia64-linux build fortunately, it only shows up for cross builds, or if
--enable-targets=all is used.  Still, this means it is a problem for people
trying to do binutils development on an ia64-linux host.  This may also cause
problems with other programs as use of -Werror spreads.

Also, the spurious warning is a problem because the warning is inherently
unportable.  Different targets and/or different optimization options can result
in different sets of warnings.  So what happens is that one person compiles the
code and gets no warning.  Another compiles the code for a different target,
gets a warning, and submits a patch.  Then the first person points out that the
code isn't broken, that the patch shouldn't necessary, and recommends that the
compiler should be fixed.  Hence this PR.

The failure happens for ia64 because of the lack of reg+offset addressing
modes.  We have a parameter info, copied into pseudo-reg 345, that is
dereferenced twice, once for the fprintf_func field and once for the stream
field.  These fields are at offset 0 and 4.  Normally, we would get two mems
one with address (reg 345) and one with address (plus (reg 345) (const_int 4)).
 But IA-64 does not have reg+offset, so we end up with a post-increment of reg
345.  This means reg 345 is now set twice.  Once before the setjmp, and once
afterwards.  This triggers the code in regno_clobbered_at_setjmp which has a
test "REG_N_SETS (regno) > 1" which is now true for IA-64, but not for most
other targets.

The best fix I see is to improve the CFG to include info about which block
after setjmp is the fallthrough and which is the return from longjmp path. 
Once we have the improved CFG, then we can implement a more accurate test, such
as the one tft mentioned in comment #3.  It may be easier and/or more
appropriate to do this work in the tree-ssa part of the compiler.  This is
likely more work than I can do at the moment for this PR.

A more limited solution may be possible by adjusting the setjmp warning code to
take these post-inc sets into account.  We could keep track of sets created by
auto-inc optimizations, and then subtract them in the setjmp warning code. 
This would ensure the same results for all targets, regardless of addressing
modes.  The flaw here is that if auto-inc opts do modify a register, then we
really do have a problem, and really should have emitted a warning.  So this
doesn't seem worth pursuing.

Alternatively, we could disable auto-inc optimization for pseudo regs that live
across setjmp.  Such pseudo regs won't be allocated to hard regs, so use of
auto-inc addressing modes isn't profitable here anyways.  I think this is a
much better idea.  Unfortunately, it can't be easily implemented, as we can
perform auto-inc optimizations before regs_live_at_setjmp is set.  We would
need another  update_life_info call to do this.  Not clear if this is
worthwhile.  I think it is worth investigating though.

Another alternative is to just remove the warning code.  Most warnings emitted
by this code are probably spurious.  This may not be a viable solution though,
since the warnings are actually useful on some occasions, and the lack of
warnings for problematic code could be considered a regression.  This is
probably not feasible.


-- 

wilson at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |wilson at gcc dot gnu dot
                   |                            |org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21059

Reply via email to