From patchwork Wed Jan 4 14:07:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Add missed adjustment to label_nuses in reload. Date: Wed, 04 Jan 2012 04:07:52 -0000 From: Marcus Shawcroft X-Patchwork-Id: 134254 Message-Id: <4F045D38.7060204@arm.com> To: gcc-patches@gcc.gnu.org Reload (find_reloads) has code that can replace a register with a label_ref when presented with RTL of the form: (set (reg) (reg) (notes (rtx_equal (label_ref))) Label references are initially counted in jump.c:mark_all_labels() and friends. This code traverses the RTL and counts each observed label_ref. The code inserts REG_LABEL_OPERAND or REG_LABEL_TARGET as appropriate. Notes are not traversed therefore the (rtx_equal (label_ref)) shown above is not treated as a reference. Instruction deletion, in cfgrtl.c:delete_insn() does not re-traverse the RTL, The code traverses only the notes looking for REG_LABEL_OPERAND and REG_TARGET_OPERAND notes in order to count down the label_nuses field. The code in reload.c:find_reloads() converts a register to a label_ref and inserts the associated REG_LABEL_OPERAND but does not adjust label_nuses, this may result in the inappropriate deletion of a live label. This issue was discovered during the development of the ARM aarch64 gcc backend and results in an ICE due to deletion of a live jump table. The issue has not been re-created on another target. The proposed patch has been regressed on x86 (and aarch64). Proposed ChangeLog entry below, patch attached: 2012-01-04 Marcus Shawcroft * reload.c (find_reloads): Adjust LABEL_NUSES on REG_LABEL_OPERAND insertion. /Marcus diff --git a/gcc/reload.c b/gcc/reload.c index 53dcd2d..206fb36 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -4212,7 +4212,12 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, && (!JUMP_P (insn) || !label_is_jump_target_p (XEXP (substitution, 0), insn))) - add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0)); + { + add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0)); + if (LABEL_P (XEXP (substitution, 0))) + ++ LABEL_NUSES(XEXP (substitution, 0)); + } + } else retval |= (substed_operand[i] != *recog_data.operand_loc[i]);