Jeff, this patch fixes PR51471. It prevents frame-related insns from being speculated by delayed branch scheduling, which may cause inconsistencies in cfi state.
For one of the examples from PR51471: 20040811-1.c, the scenario is as follows. Before delayed branch scheduling, 20040811-1.c.220r.vartrack: ... (jump_insn:TI 82 77 93 3 (set (pc) (if_then_else (ne (reg/v:SI 3 $3 [orig:210 nD.1374 ] [210]) (reg:SI 7 $7 [255])) (label_ref:SI 30) (pc))) 20040811-1.c:16 434 {*branch_equalitysi} (expr_list:REG_EQUAL (if_then_else (ne (reg/v:SI 3 $3 [orig:210 nD.1374 ] [210]) (const_int 1000000 [0xf4240])) (label_ref:SI 30) (pc)) (expr_list:REG_BR_PROB (const_int 9899 [0x26ab]) (nil))) -> 30) (note 93 82 133 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (note 133 93 122 4 NOTE_INSN_EPILOGUE_BEG) (insn 122 133 123 4 (clobber (mem/c:BLK (reg/f:SI 29 $sp) [4 A8])) 20040811-1.c:19 -1 (nil)) (insn/f:TI 123 122 148 4 (set (reg/f:SI 29 $sp) (reg/f:SI 30 $fp)) 20040811-1.c:19 280 {*movsi_internal} (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI 29 $sp) (const_int 32 [0x20])) (nil))) ... After delayed branch scheduling, 20040811-1.c.221r.mach: ... (insn 153 77 93 (sequence [ (jump_insn:TI 82 77 123 (set (pc) (if_then_else (ne (reg/v:SI 3 $3 [orig:210 nD.1374 ] [210]) (reg:SI 7 $7 [255])) (label_ref:SI 30) (pc))) 20040811-1.c:16 434 {*branch_equalitysi} (expr_list:REG_BR_PRED (const_int 14 [0xe]) (expr_list:REG_EQUAL (if_then_else (ne (reg/v:SI 3 $3 [orig:210 nD.1374 ] [210]) (const_int 1000000 [0xf4240])) (label_ref:SI 30) (pc)) (expr_list:REG_BR_PROB (const_int 9899 [0x26ab]) (nil)))) -> 30) (insn/f:TI 123 82 93 (set (reg/f:SI 29 $sp) (reg/f:SI 30 $fp)) 280 {*movsi_internal} (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI 29 $sp) (const_int 32 [0x20])) (nil))) ]) 20040811-1.c:16 -1 (nil)) (note 93 153 133 [bb 4] NOTE_INSN_BASIC_BLOCK) (note 133 93 122 NOTE_INSN_EPILOGUE_BEG) (insn 122 133 148 (clobber (mem/c:BLK (reg/f:SI 29 $sp) [4 A8])) 20040811-1.c:19 -1 (nil)) ... Frame-related insn 123 is moved into the delay slot of jump 82. This speculatively executes the insn 123 before the jump to code_label 30, which causes an inconsistent cfi state at code_label 30, which causes the following ICE: ... 20040811-1.c: In function 'main': 20040811-1.c:19:1: internal compiler error: in maybe_record_trace_start, at dwarf2cfi.c:2231 ... this patch prevents frame-related insns from being speculated by delayed branch scheduling, fixing this ICE. build & reg-tested on mips64el-linux-gnu. Andrew, did you get to do bootstrap/test on mips64-linux-gnu? Jeff, ok for trunk? Thanks, - Tom 2012-01-08 Tom de Vries <t...@codesourcery.com> Andrew Pinski <apin...@cavium.com> * reorg.c (fill_slots_from_thread): Don't speculate frame-related insns.
Index: gcc/reorg.c =================================================================== --- gcc/reorg.c (revision 182903) +++ gcc/reorg.c (working copy) @@ -2716,7 +2716,8 @@ fill_slots_from_thread (rtx insn, rtx co if (!must_annul && (condition == const_true_rtx || (! insn_sets_resource_p (trial, &opposite_needed, true) - && ! may_trap_or_fault_p (pat)))) + && ! may_trap_or_fault_p (pat) + && ! RTX_FRAME_RELATED_P (trial)))) { old_trial = trial; trial = try_split (pat, trial, 0);