On Fri, 2019-01-18 at 12:32 -0500, David Malcolm wrote: [CCing Abel]
> PR rtl-optimization/88423 reports an ICE within sched-ebb.c's > begin_move_insn, failing the assertion at line 175, where there's > no fall-through edge: > > 171 rtx_insn *x = NEXT_INSN (insn); > 172 if (e) > 173 gcc_checking_assert (NOTE_P (x) || LABEL_P (x)); > 174 else > 175 gcc_checking_assert (BARRIER_P (x)); > > "insn" is a jump_insn for a table jump, and its NEXT_INSN is the > placeholder code_label, followed by the jump_table_data. > > It's not clear to me if such a jump_insn can be repositioned within > the insn stream, or if the scheduler is able to do so. I believe a > tablejump is always at the end of such a head/tail insn sub-stream. > Is it a requirement that the placeholder code_label for the jump_insn > is always its NEXT_INSN? > > The loop at the start of schedule_ebb adjusts the head and tail > of the insns to be scheduled so that it skips leading and trailing > notes > and debug insns. > > This patch adjusts that loop to also skip trailing jump_insn > instances > that are table jumps, so that we don't attempt to move such table > jumps. > > This fixes the ICE, but I'm not very familiar with this part of the > compiler - so I have two questions: > > (1) What does GCC mean by "ebb" in this context? > > My understanding is that the normal definition of an "extended basic > block" (e.g. Muchnick's book pp175-177) is that it's a maximal > grouping > of basic blocks where only one BB in each group has multiple in-edges > and all other BBs in the group have a single in-edge (and thus e.g. > there's a tree-like structure of BBs within each EBB). > > From what I can tell, schedule_ebbs is iterating over BBs, looking > for > runs of BBs joined by next_bb that are connected by fallthrough edges > and don't have labels (and aren't flagged with BB_DISABLE_SCHEDULE). > It uses this run of BBs to generate a run of instructions within the > NEXT_INSN/PREV_INSN doubly-linked list, which it passes as "head" > and "tail" to schedule_ebb. > > This sounds like it will be a group of basic blocks with single in- > edges > internally, but it isn't a *maximal* group of such BBs - but perhaps > it's "maximal" in the sense of what the NEXT_INSN/PREV_INSN > representation can cope with? > > There (presumably) can't be a fallthrough edge after a table jump, so > a table jump could only ever be at the end of such a chain, never in > the > middle. > > (2) Is it OK to omit "tail" from consideration here, from a dataflow > and insn-dependency point-of-view? Presumably the scheduler is > written > to ensure that data used by subsequent basic blocks will still be > available > after the insns within an "EBB" are reordered, so presumably any data > uses *within* the jump_insn are still going to be available - but, as > I > said, I'm not very familiar with this part of the code. (I think I'm > also > assuming that the jump_insn can't clobber data, just the PC) > > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. > > OK for trunk? > > gcc/ChangeLog: > PR rtl-optimization/88423 > * sched-ebb.c (schedule_ebb): Don't move the jump_insn for a > table > jump. > > gcc/testsuite/ChangeLog: > PR rtl-optimization/88423 > * gcc.c-torture/compile/pr88423.c: New test. > --- > gcc/sched-ebb.c | 4 ++++ > gcc/testsuite/gcc.c-torture/compile/pr88423.c | 5 +++++ > 2 files changed, 9 insertions(+) > create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr88423.c > > diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c > index d459e09..1fe0b76 100644 > --- a/gcc/sched-ebb.c > +++ b/gcc/sched-ebb.c > @@ -485,6 +485,10 @@ schedule_ebb (rtx_insn *head, rtx_insn *tail, > bool modulo_scheduling) > tail = PREV_INSN (tail); > else if (LABEL_P (head)) > head = NEXT_INSN (head); > + else if (tablejump_p (tail, NULL, NULL)) > + /* Don't move a jump_insn for a tablejump, to avoid having > + to move the placeholder code_label and jump_table_data. > */ > + tail = PREV_INSN (tail); > else > break; > } > diff --git a/gcc/testsuite/gcc.c-torture/compile/pr88423.c > b/gcc/testsuite/gcc.c-torture/compile/pr88423.c > new file mode 100644 > index 0000000..4948817 > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/compile/pr88423.c > @@ -0,0 +1,5 @@ > +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ > +/* { dg-options "-march=skylake -fPIC -fsched2-use-superblocks -fno- > if-conversion" } */ > +/* { dg-require-effective-target fpic } */ > + > +#include "../../gcc.dg/20030309-1.c"