This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR51471. Don't speculate frame-related insns during delayed branch scheduling.
- From: Tom de Vries <Tom_deVries at mentor dot com>
- To: Andrew Pinski <pinskia at gmail dot com>, Jeff Law <law at redhat dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Richard Henderson <rth at redhat dot com>
- Date: Sun, 8 Jan 2012 14:51:58 +0100
- Subject: [PATCH] PR51471. Don't speculate frame-related insns during delayed branch scheduling.
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 <tom@codesourcery.com>
Andrew Pinski <apinski@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);