Hello, This patch is a followup of http://gcc.gnu.org/ml/gcc-patches/2014-02/msg01042.html
If fixes a bunch of ICEs for the testsuite ran with --target_board=arm-sim/\{-mapcs-frame\}, noticed on a reference branch for testing the former patch. One of the strange issue I had to deal with, for instance with ./gcc.c-torture/compile/991202-1.c, is that the epilogue emitted the CFA notes in the following order: (set/f (reg:SI 12 ip) (plus:SI (reg:SI 12 ip) (const_int 16 [0x10]))) (set/f (reg:DF 32 s16) (mem/c:DF (reg:SI 12 ip) [3 S8 A64])) (set/f (reg:DF 34 s18) (mem/c:DF (plus:SI (reg:SI 12 ip) (const_int 8 [0x8])) [3 S8 A64])) ]) /home/bruelc/tmp/991202-1.c:18 347 {*vfp_pop_multiple_with_writeback} (expr_list:REG_UNUSED (reg:SI 12 ip) (expr_list:REG_CFA_ADJUST_CFA (set (reg:SI 12 ip) (plus:SI (reg:SI 12 ip) (const_int 16 [0x10]))) (expr_list:REG_CFA_DEF_CFA (reg/f:SI 11 fp) (expr_list:REG_CFA_RESTORE (reg:DF 34 s18) (expr_list:REG_CFA_RESTORE (reg:DF 32 s16) (nil))))))) but shrink-wrapping duplicates it as (insn/f:TI 140 137 171 (parallel [ (set/f (reg:SI 12 ip) (plus:SI (reg:SI 12 ip) (const_int 16 [0x10]))) (set/f (reg:DF 32 s16) (mem/c:DF (reg:SI 12 ip) [3 S8 A64])) (set/f (reg:DF 34 s18) (mem/c:DF (plus:SI (reg:SI 12 ip) (const_int 8 [0x8])) [3 S8 A64])) ]) /home/bruelc/tmp/991202-1.c:18 347 {*vfp_pop_multiple_with_writeback} (expr_list:REG_UNUSED (reg:SI 12 ip) (expr_list:REG_CFA_RESTORE (reg:DF 32 s16) (expr_list:REG_CFA_RESTORE (reg:DF 34 s18) (expr_list:REG_CFA_DEF_CFA (reg/f:SI 11 fp) (expr_list:REG_CFA_ADJUST_CFA (set (reg:SI 12 ip) (plus:SI (reg:SI 12 ip) (const_int 16 [0x10]))) (nil))))))) Since the CFA_RESTORE order is inverted with CFA_DEF_CFA, cur_cfa->reg was set with IP instead of FP I fixed this by not emitting the CFA_ADJUST_CFA in this case, since it's not needed anyway as we have: fldmfdd ip!, {d8-d9} @ 140 *vfp_pop_multiple_with_writeback sub sp, fp, #12 @ 142 ldmfd sp, {fp, sp, pc} @ 143 so after @140 cur_cfa can't be IP. Regression tested for for armv7-a --target_board=arm-sim/\{,-mapcs-frame\}. Fixes a large number of tests OK for trunk ? Many thanks
--- config/arm/arm.c 2014-02-19 15:28:34.000000000 +0100 +++ /work1/bruel/superh_elf/gnu_trunk.devs/gcc/gcc/config/arm/arm.c 2014-02-19 14:30:44.000000000 +0100 @@ -19911,10 +19911,14 @@ /* Make sure cfa doesn't leave with IP_REGNUM. */ if (TARGET_VFP && REGNO (base_reg) == IP_REGNUM) - add_reg_note (par, REG_CFA_DEF_CFA, hard_frame_pointer_rtx); + { + RTX_FRAME_RELATED_P (par) = 1; + add_reg_note (par, REG_CFA_DEF_CFA, hard_frame_pointer_rtx); + } + else + arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, + base_reg, base_reg); - arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, - base_reg, base_reg); } @@ -27109,8 +27113,8 @@ if (saved_size > 0) { rtx insn; - floats_from_frame += saved_size; - insn = emit_insn (gen_addsi3 (gen_rtx_REG (SImode, IP_REGNUM), + floats_from_frame += saved_size; + insn = emit_insn (gen_addsi3 (gen_rtx_REG (SImode, IP_REGNUM), hard_frame_pointer_rtx, GEN_INT (-floats_from_frame))); RTX_FRAME_RELATED_P (insn) = 1; @@ -27192,7 +27196,9 @@ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, hard_frame_pointer_rtx, GEN_INT (- 4 * num_regs))); - RTX_FRAME_RELATED_P (insn) = 1; + + arm_add_cfa_adjust_cfa_note (insn, - 4 * num_regs, + stack_pointer_rtx, hard_frame_pointer_rtx); } arm_emit_multi_reg_pop (saved_regs_mask);