diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-03-31 15:00:52 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-03-31 15:00:52 +0200 |
commit | 97eb24c42a5d82617e576165867dd6678b6b1262 (patch) | |
tree | 636c21bb81e44f2fcc4017f5e4228179bea95408 /gcc/ira.c | |
parent | d4aff57bc079dc04d7d3ab9f71b2e923d9087e31 (diff) | |
download | gcc-97eb24c42a5d82617e576165867dd6678b6b1262.zip gcc-97eb24c42a5d82617e576165867dd6678b6b1262.tar.gz gcc-97eb24c42a5d82617e576165867dd6678b6b1262.tar.bz2 |
re PR rtl-optimization/70460 (Miscompilation of glibc on i686-linux starting with r234101)
PR rtl-optimization/70460
* ira.c (indirect_jump_optimize): Don't substitute LABEL_REF
with operand from REG_LABEL_OPERAND, instead substitute
SET_SRC or REG_EQUAL note content if it is a LABEL_REF.
Don't do anything for REG_NON_LOCAL_GOTO jumps.
* gcc.c-torture/execute/pr70460.c: New test.
From-SVN: r234614
Diffstat (limited to 'gcc/ira.c')
-rw-r--r-- | gcc/ira.c | 24 |
1 files changed, 12 insertions, 12 deletions
@@ -3870,7 +3870,8 @@ indirect_jump_optimize (void) FOR_EACH_BB_REVERSE_FN (bb, cfun) { rtx_insn *insn = BB_END (bb); - if (!JUMP_P (insn)) + if (!JUMP_P (insn) + || find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) continue; rtx x = pc_set (insn); @@ -3884,19 +3885,18 @@ indirect_jump_optimize (void) if (!DF_REF_IS_ARTIFICIAL (def)) { rtx_insn *def_insn = DF_REF_INSN (def); - rtx note = find_reg_note (def_insn, REG_LABEL_OPERAND, NULL_RTX); - - if (note) + rtx lab = NULL_RTX; + rtx set = single_set (def_insn); + if (set && GET_CODE (SET_SRC (set)) == LABEL_REF) + lab = SET_SRC (set); + else { - /* Substitute a LABEL_REF to the label given by the - note rather than using SET_SRC of DEF_INSN. - DEF_INSN might be loading the label constant from - a constant pool, which isn't what we want in a - direct branch. */ - rtx lab = gen_rtx_LABEL_REF (Pmode, XEXP (note, 0)); - if (validate_replace_rtx (SET_SRC (x), lab, insn)) - rebuild_p = true; + rtx eqnote = find_reg_note (def_insn, REG_EQUAL, NULL_RTX); + if (eqnote && GET_CODE (XEXP (eqnote, 0)) == LABEL_REF) + lab = XEXP (eqnote, 0); } + if (lab && validate_replace_rtx (SET_SRC (x), lab, insn)) + rebuild_p = true; } } } |