------- 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