Message ID | c6964da40e39ebe7706e8e8073ab4c2cdce64aba.1484415306.git.segher@kernel.crashing.org |
---|---|
State | New |
Headers | show |
On Sat, Jan 14, 2017 at 05:55:48PM +0000, Segher Boessenkool wrote: > - && extract_asm_operands (PATTERN (last)) != NULL_RTX > + && (extract_asm_operands (last) || JUMP_LABEL (last) == before) Somehow I removed the PATTERN there; retesting with it. I'll test it on x86 as well, maybe it triggers there (it doesn't on PowerPC obviously). Segher
On Sat, Jan 14, 2017 at 01:09:14PM -0600, Segher Boessenkool wrote: > On Sat, Jan 14, 2017 at 05:55:48PM +0000, Segher Boessenkool wrote: > > - && extract_asm_operands (PATTERN (last)) != NULL_RTX > > + && (extract_asm_operands (last) || JUMP_LABEL (last) == before) > > Somehow I removed the PATTERN there; retesting with it. I'll test it > on x86 as well, maybe it triggers there (it doesn't on PowerPC obviously). Tested that on powerpc64-linux and x86_64-linux now; no failures. Segher
On 01/14/2017 10:55 AM, Segher Boessenkool wrote: > If a jump always falls through but that cannot be optimised away, like > is the case with the PowerPC bdnz insn if its jump target is the same as > the fallthrough, sched gets confused if it schedules some instructions > from before that jump instruction to behind it: it splits the > fallthrough branch, but the jump target isn't updated, and things fall > apart as in the PR. This patch fixes it. > > The second patch fragment makes -fsched-verbose=N work for N>=4; the > currently scheduled fragment can now contain a label. Everything else > seems to work fine with that. > > Tested on powerpc*-linux (with the testcase Alan checked in earlier > today); also bootstrapped on powerpc64-linux. Is this okay for trunk? > > > Segher > > > 2017-01-14 Segher Boessenkool <segher@kernel.crashing.org> > > PR target/72749 > * cfgrtl.c (rtl_split_edge): Also patch jump insns that jump to the > fallthrough. > * haifa-sched.c (dump_insn_stream): Don't crash if there is a label > in the currently scheduled RTL fragment. So presumably the semantics in this case can only mean one thing -- both the fallthru and the jump have to go to the same place after splitting. Right? ISTM that ought to be documented in rtl_split_edge somewhere. In this case is the edge a fallthru or branch edge? And, no we don't make any guarantee about degenerate jumps -- a jump with a side effect in particular can easily survive. I wouldn't be surprised if there's various bugs lurking for cases where we have a degenerate jump like that. It's just not common enough to have been heavily exercised. Patch with PATTERN fix is OK. jeff
On Sat, Jan 14, 2017 at 09:47:41PM -0700, Jeff Law wrote: > > PR target/72749 > > * cfgrtl.c (rtl_split_edge): Also patch jump insns that jump to the > > fallthrough. > > * haifa-sched.c (dump_insn_stream): Don't crash if there is a label > > in the currently scheduled RTL fragment. > So presumably the semantics in this case can only mean one thing -- both > the fallthru and the jump have to go to the same place after splitting. > Right? ISTM that ought to be documented in rtl_split_edge somewhere. We could call patch_jump_insn in *all* cases, except for simple jumps it does gcc_assert (JUMP_LABEL (insn) == old_label); which is a useful check (for the other callers), and patch_jump_insn isn't a very cheap routine to call anyway, better not do it too often. > In this case is the edge a fallthru or branch edge? Both! You get only one edge if both jump targets are the same. > And, no we don't make any guarantee about degenerate jumps -- a jump > with a side effect in particular can easily survive. I wouldn't be > surprised if there's various bugs lurking for cases where we have a > degenerate jump like that. It's just not common enough to have been > heavily exercised. > > Patch with PATTERN fix is OK. Thanks, I'll commit it tomorrow. Segher
On 01/14/2017 10:27 PM, Segher Boessenkool wrote: > On Sat, Jan 14, 2017 at 09:47:41PM -0700, Jeff Law wrote: >>> PR target/72749 >>> * cfgrtl.c (rtl_split_edge): Also patch jump insns that jump to the >>> fallthrough. >>> * haifa-sched.c (dump_insn_stream): Don't crash if there is a label >>> in the currently scheduled RTL fragment. >> So presumably the semantics in this case can only mean one thing -- both >> the fallthru and the jump have to go to the same place after splitting. >> Right? ISTM that ought to be documented in rtl_split_edge somewhere. > > We could call patch_jump_insn in *all* cases, except for simple jumps > it does > > gcc_assert (JUMP_LABEL (insn) == old_label); > > which is a useful check (for the other callers), and patch_jump_insn > isn't a very cheap routine to call anyway, better not do it too often. > >> In this case is the edge a fallthru or branch edge? > > Both! You get only one edge if both jump targets are the same. Right. To be more precise, my question was does it have EDGE_FALLTHRU set? Jeff
On Sat, Jan 14, 2017 at 10:52:04PM -0700, Jeff Law wrote: > >>In this case is the edge a fallthru or branch edge? > > > >Both! You get only one edge if both jump targets are the same. > Right. To be more precise, my question was does it have EDGE_FALLTHRU > set? Yes: succ: 6 [92.5%] (FALLTHRU,DFS_BACK,CAN_FALLTHRU) Just after doloop created it it was two edges. After fwprop it is just one. outof_cfglayout makes it two again (to different targets). bbro makes it one yet again. Segher
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 7604346..dbbba59 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1931,7 +1931,7 @@ rtl_split_edge (edge edge_in) if (last && JUMP_P (last) && edge_in->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) - && extract_asm_operands (PATTERN (last)) != NULL_RTX + && (extract_asm_operands (last) || JUMP_LABEL (last) == before) && patch_jump_insn (last, before, bb)) df_set_bb_dirty (edge_in->src); } diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 1b13e32..07de1bb 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -6495,7 +6495,7 @@ dump_insn_stream (rtx_insn *head, rtx_insn *tail) if (sched_verbose >= 4) { - if (NOTE_P (insn) || recog_memoized (insn) < 0) + if (NOTE_P (insn) || LABEL_P (insn) || recog_memoized (insn) < 0) fprintf (sched_dump, "nothing"); else print_reservation (sched_dump, insn);