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);

Reply via email to