aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-03-17 12:53:53 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-03-17 12:53:53 +0100
commit9bc057c8da4c460ffd067e5202d399fce6c8cbee (patch)
treeaa8a16afdb4d9862a59c6cb53f3fe9990ab1bf61 /gcc
parentea913779b0921886a8d8503263f27e3ddfc1831b (diff)
downloadgcc-9bc057c8da4c460ffd067e5202d399fce6c8cbee.zip
gcc-9bc057c8da4c460ffd067e5202d399fce6c8cbee.tar.gz
gcc-9bc057c8da4c460ffd067e5202d399fce6c8cbee.tar.bz2
re PR middle-end/70245 (Miscompilation of ICU on i386 with atom tuning starting with r227382)
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. From-SVN: r234285
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/rtlanal.c26
4 files changed, 31 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 78f4697..3edfba0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2016-03-17 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <enkovich.gnu@gmail.com>
* 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 554e623..eed43b1 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 c91d60d..7f0bfa4 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 bacc5f2..b4dff86 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;