Hi, On Thu, 12 Jun 2014 12:49:13, Richard Biener wrote: > > On Thu, Jun 12, 2014 at 10:36 AM, Eric Botcazou <ebotca...@adacore.com> wrote: >>> Btw, I wonder if we can simply mark the MEMs generated from spill code >>> with MEM_NOTRAP_P so we can remove the special casing of >>> frame-pointer-based addresses from add while properly initializing >>> MEM_NOTRAP_p from rtx_addr_can_trap_p? >> >> Spill code generated by the compiler itself? That's quite restrictive. >> >>> I suppose it was added exactly to cover spill code? >> >> Nope, it was added for jump tables: >> >> 2003-04-22 Richard Henderson <r...@redhat.com> >> >> PR 8866 >> * rtl.h (MEM_NOTRAP_P): New. >> (MEM_COPY_ATTRIBUTES): Copy it. >> * rtlanal.c (may_trap_p): Check it. >> * expr.c (do_tablejump): Set it. >> * doc/rtl.texi (Flags): Document it. >> >> * cfgrtl.c (try_redirect_by_replacing_jump): Revert last three changes. >> >> that is to say, for memory accesses that can nominally trap but for which we >> know that they actually don't. > > I was asking for the special-casing of frame-pointer-based accesses in > rtx_addr_can_trap_p, not MEM_NOTRAP_P. (MEM_NOTRAP_P > of course has the issue that it may not be trusted when you try to > move the MEM ...)
that was recently introduced by Eric's patch: Author: ebotcazou Date: Wed Mar 26 07:38:30 2014 New Revision: 208837 URL: http://gcc.gnu.org/viewcvs?rev=208837&root=gcc&view=rev Log: PR rtl-optimization/60452 * rtlanal.c (rtx_addr_can_trap_p_1): Fix head comment. <case REG>: Return 1 for invalid offsets from the frame pointer. Added: trunk/gcc/testsuite/gcc.c-torture/execute/20140326-1.c Modified: trunk/gcc/ChangeLog trunk/gcc/rtlanal.c trunk/gcc/testsuite/ChangeLog which fixes this example: cat 20140326-1.c int a; int main (void) { char e[2] = { 0, 0 }, f = 0; if (a == 131072) f = e[a]; return f; } gcc -O1 -fdump-rtl-all-slim 20140326-1.c hits the frame_pointer_rtx check twice, before reload. *** frame can trap: offset=131056, size=1, low_bound=-16, high_bound=0, reload_in_progress=0, reload_completed=0 *** frame can trap: offset=131056, size=1, low_bound=-16, high_bound=0, reload_in_progress=0, reload_completed=0 grep '\(frame\|sp\):DI+' 20140326-1.c.* 20140326-1.c.172r.vregs: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.173r.into_cfglayout: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.174r.jump: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.174r.jump: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.175r.subreg1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.176r.dfinit: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.177r.cse1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.177r.cse1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.178r.fwprop1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.185r.ce1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.185r.ce1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.185r.ce1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.186r.reginfo: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.187r.loop2: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.188r.loop2_init: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.188r.loop2_init: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.189r.loop2_invariant: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.192r.loop2_done: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.192r.loop2_done: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.196r.dse1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.197r.fwprop2: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.199r.init-regs: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.201r.combine: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.202r.ce2: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.204r.outof_cfglayout: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.205r.split1: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.206r.subreg2: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.208r.mode_sw: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.209r.asmcons: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.213r.ira: 10: r83:QI=[frame:DI+0x1fff0] 20140326-1.c.214r.reload: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.215r.postreload: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.217r.split2: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.221r.pro_and_epilogue: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.222r.dse2: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.223r.csa: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.224r.jump2: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.226r.ce3: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.228r.cprop_hardreg: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.229r.rtl_dce: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.235r.split3: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.236r.stack: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.237r.alignments: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.239r.mach: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.240r.barriers: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.244r.shorten: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.245r.nothrow: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.246r.dwarf2: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.247r.final: 10: ax:QI=[sp:DI+0x1ffe8] 20140326-1.c.248r.dfinish: 10: ax:QI=[sp:DI+0x1ffe8] shows the [frame:DI+0x1fff0] is introduced in 172r.vreg and changed to [sp:DI+0x1ffe8] in 214r.reload. the other sample, cat 20140611-1.c int a, c, d; short b; int main () { int e[1]; for (; b < 2; b++) { a = 0; if (b == 28378) a = e[b]; if (!(d || b)) for (; c;) ; } return 0; } gcc -O1 -fdump-rtl-all-slim 20140611-1.c *** sp can trap: offset=113488, size=4, low_bound=-144, high_bound=24, reload_in_progress=0, reload_completed=1 grep '\(frame\|sp\):DI+' 20140611-1.c.* 20140611-1.c.172r.vregs: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.173r.into_cfglayout: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.174r.jump: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.174r.jump: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.175r.subreg1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.176r.dfinit: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.177r.cse1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.177r.cse1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.178r.fwprop1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.185r.ce1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.185r.ce1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.186r.reginfo: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.187r.loop2: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.188r.loop2_init: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.188r.loop2_init: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.189r.loop2_invariant: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.192r.loop2_done: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.192r.loop2_done: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.196r.dse1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.197r.fwprop2: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.199r.init-regs: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.201r.combine: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.202r.ce2: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.204r.outof_cfglayout: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.205r.split1: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.206r.subreg2: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.208r.mode_sw: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.209r.asmcons: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.213r.ira: 28: r90:SI=[frame:DI+0x1bb58] 20140611-1.c.214r.reload: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.215r.postreload: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.217r.split2: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.221r.pro_and_epilogue: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.222r.dse2: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.223r.csa: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.224r.jump2: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.226r.ce3: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.228r.cprop_hardreg: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.229r.rtl_dce: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.235r.split3: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.236r.stack: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.237r.alignments: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.239r.mach: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.240r.barriers: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.244r.shorten: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.245r.nothrow: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.246r.dwarf2: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.247r.final: 28: cx:SI=[sp:DI+0x1bb50] 20140611-1.c.248r.dfinish: 28: cx:SI=[sp:DI+0x1bb50] looks very similar in my eyes, only that rtx_addr_can_trap_p_1 is called after reload, and now, because it is not frame pointer relative any more, this silly function lies to us: "Dont worry, this [sp:DI+0x1bb50] thing can't possibly trap." Which is nonsense, as everybody knows. Bernd. > > Richard. > >> -- >> Eric Botcazou