This simple code: typedef void (*TestFunction)(int *); void Add(int *testCase); void test(void); int* TestNew( TestFunction function); static void foo(int* tc){ test(); } int* GetProfileSuite(){ Add(TestNew(foo)); return 0; } ...triggers internal assert on my port of 4.3.2 when compiled with -O2 -g. It will pass with -O2 only or with -O2 -fno-var-tracking -g. The assert triggered is this one: ... static void check_cfg (rtx head, rtx tail) { ... if (control_flow_insn_p (head)) { gcc_assert (BB_END (bb) == head); <<<<<< This one if (any_uncondjump_p (head)) gcc_assert (EDGE_COUNT (bb->succs) == 1 && BARRIER_P (NEXT_INSN (head))); It looks like free_cfg pass removes something it should not after NOTE_INSN_VAR_LOCATION was inserted by variable_tracking pass.
>It looks like free_cfg pass removes something it should not after > NOTE_INSN_VAR_LOCATION was inserted by variable_tracking pass. Are you running the scheduler manually in your machine dependent reorg? If so you need to call compute_bb_for_insn before calling schedule_insns.
Thank you for the suggestion, but... I use schedule_ebbs in machine dependent reorg, and I do call compute_bb_for_insn before it. CFG is messed up before I get there...
Look at the ia64 port (and a few others too, e.g. blackfin), they call compute_bb_for_insn first thing in machine reorg and that works. It is obviously not ideal, but the only pass between free_cfg and machine_reorg that can destroy the CFG is dbr_sched (delay branch scheduling). Anyway, out-of-tree port => INVALID. Feel free to re-open this bug report if you can reproduce it with an in-tree port, of course.