From: jakub Date: Thu, 17 Mar 2016 11:53:53 +0000 (+0000) Subject: PR target/70245 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=21e8541cdd0220e448955f3c7dd02fad3421cc4c;p=thirdparty%2Fgcc.git PR target/70245 * rtl.h (replace_rtx): Add ALL_REGS argument. * rtlanal.c (replace_rtx): Likewise. If true, use REGNO equality and assert mode is the same, instead of just rtx pointer equality. * config/i386/i386.md (mov + arithmetics with load peephole): Pass true as ALL_REGS argument to replace_rtx. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234285 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78f4697b1336..3edfba0b110d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-03-17 Jakub Jelinek + + PR target/70245 + * rtl.h (replace_rtx): Add ALL_REGS argument. + * rtlanal.c (replace_rtx): Likewise. If true, use REGNO + equality and assert mode is the same, instead of just rtx pointer + equality. + * config/i386/i386.md (mov + arithmetics with load peephole): Pass + true as ALL_REGS argument to replace_rtx. + 2016-03-17 Ilya Enkovich * match.pd (A + (B vcmp C ? 1 : 0) -> A - (B vcmp C)): Apply diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 554e6239fda4..eed43b1273a3 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17885,7 +17885,7 @@ (parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 1)])) (clobber (reg:CC FLAGS_REG))])] - "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);") + "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);") (define_peephole2 [(set (match_operand 0 "register_operand") diff --git a/gcc/rtl.h b/gcc/rtl.h index c91d60d3c908..7f0bfa443a02 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3011,7 +3011,7 @@ extern bool can_nonlocal_goto (const rtx_insn *); extern void copy_reg_eh_region_note_forward (rtx, rtx_insn *, rtx); extern void copy_reg_eh_region_note_backward (rtx, rtx_insn *, rtx); extern int inequality_comparisons_p (const_rtx); -extern rtx replace_rtx (rtx, rtx, rtx); +extern rtx replace_rtx (rtx, rtx, rtx, bool = false); extern void replace_label (rtx *, rtx, rtx, bool); extern void replace_label_in_insn (rtx_insn *, rtx, rtx, bool); extern bool rtx_referenced_p (const_rtx, const_rtx); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index bacc5f25f4af..b4dff86c0e9a 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2946,10 +2946,13 @@ inequality_comparisons_p (const_rtx x) not enter into CONST_DOUBLE for the replace. Note that copying is not done so X must not be shared unless all copies - are to be modified. */ + are to be modified. + + ALL_REGS is true if we want to replace all REGs equal to FROM, not just + those pointer-equal ones. */ rtx -replace_rtx (rtx x, rtx from, rtx to) +replace_rtx (rtx x, rtx from, rtx to, bool all_regs) { int i, j; const char *fmt; @@ -2961,9 +2964,17 @@ replace_rtx (rtx x, rtx from, rtx to) if (x == 0) return 0; - if (GET_CODE (x) == SUBREG) + if (all_regs + && REG_P (x) + && REG_P (from) + && REGNO (x) == REGNO (from)) + { + gcc_assert (GET_MODE (x) == GET_MODE (from)); + return to; + } + else if (GET_CODE (x) == SUBREG) { - rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to); + rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to, all_regs); if (CONST_INT_P (new_rtx)) { @@ -2979,7 +2990,7 @@ replace_rtx (rtx x, rtx from, rtx to) } else if (GET_CODE (x) == ZERO_EXTEND) { - rtx new_rtx = replace_rtx (XEXP (x, 0), from, to); + rtx new_rtx = replace_rtx (XEXP (x, 0), from, to, all_regs); if (CONST_INT_P (new_rtx)) { @@ -2997,10 +3008,11 @@ replace_rtx (rtx x, rtx from, rtx to) for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) { if (fmt[i] == 'e') - XEXP (x, i) = replace_rtx (XEXP (x, i), from, to); + XEXP (x, i) = replace_rtx (XEXP (x, i), from, to, all_regs); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) - XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to); + XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), + from, to, all_regs); } return x;