Message ID | 20111018174145.4d7cf3bc@rex.config |
---|---|
State | New |
Headers | show |
Julian Brown writes: > Hi, > > This patch fixes computed gotos on m68k, and probably other targets too > (the fix is in the middle end). Several tests fail at present with "-O3 > -fomit-frame-pointer". This is the same bug as PR47918. As described in that PR trail, the bug can be triggered also on i386. Thanks for debugging this very nasty issue! > [...] /Mikael
> This has been broken because since mainline revision r160124, which > (correctly) causes 'y' to be flagged as noreturn -- y never returns via > the normal function return route. If ipa-pure-const.c is hacked to > check that a function does not perform non-local gotos before marking > it noreturn, the original (correct) offset is restored -- but that is > simply papering over the problem. Agreed. > So, on to the attached fix. As mentioned previously, GCC tracks > elimination offsets throughout each function, which can vary as e.g. > other functions are called. There is a concept of an "initial" offset: > I believe that when nonlocal gotos are executed, and hence at all the > labels a nonlocal goto may reach, the elimination offsets must have > their "initial" values. Agreed. > We can find out if a label is the target of a nonlocal goto (and hence > force the use of initial offsets) in a somewhat roundabout way, by > looking up its containing basic block, seeing if that BB is a nonlocal > goto target, then seeing if the label is the first instruction in the > block. This seems slightly clumsy, but I didn't find another way of > doing it. These labels are on the nonlocal_goto_handler_labels chain. You presumably just need to apply the same treatment to them in set_initial_label_offsets as the one applied to forced labels. > Any comments, or OK to apply? OK for the adjusted patch if it works, mainline and 4.6 branch once it reopens. Please mention PR rtl-optimization/47918 in the ChangeLog. Thanks for fixing this.
Index: gcc/reload1.c =================================================================== --- gcc/reload1.c (revision 179967) +++ gcc/reload1.c (working copy) @@ -2371,6 +2371,19 @@ set_label_offsets (rtx x, rtx insn, int if (! offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num]) { + if (x == insn) + { + basic_block bb; + + bb = BLOCK_FOR_INSN (insn); + + /* If the label is the target of a non-local GOTO, we must use + the initial elimination offsets. */ + if (bb && BB_HEAD (bb) == insn + && (bb->flags & BB_NON_LOCAL_GOTO_TARGET)) + initial_p = true; + } + for (i = 0; i < NUM_ELIMINABLE_REGS; i++) offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i] = (initial_p ? reg_eliminate[i].initial_offset