Commit 4fe73cc1 by Richard Kenner

(rtx_renumbered_equal_p): Fix bug in comparing SUBREGs and REGs.

Two commutative operations are equal if the operands are in the opposite order.

From-SVN: r6633
parent 63770d6a
...@@ -3733,7 +3733,9 @@ delete_labelref_insn (insn, label, delete_this) ...@@ -3733,7 +3733,9 @@ delete_labelref_insn (insn, label, delete_this)
} }
/* Like rtx_equal_p except that it considers two REGs as equal /* Like rtx_equal_p except that it considers two REGs as equal
if they renumber to the same value. */ if they renumber to the same value and considers two commutative
operations to be the same if the order of the operands has been
reversed. */
int int
rtx_renumbered_equal_p (x, y) rtx_renumbered_equal_p (x, y)
...@@ -3745,11 +3747,13 @@ rtx_renumbered_equal_p (x, y) ...@@ -3745,11 +3747,13 @@ rtx_renumbered_equal_p (x, y)
if (x == y) if (x == y)
return 1; return 1;
if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)) if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
&& (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
&& GET_CODE (SUBREG_REG (y)) == REG))) && GET_CODE (SUBREG_REG (y)) == REG)))
{ {
register int j; int reg_x = -1, reg_y = -1;
int word_x = 0, word_y = 0;
if (GET_MODE (x) != GET_MODE (y)) if (GET_MODE (x) != GET_MODE (y))
return 0; return 0;
...@@ -3761,36 +3765,50 @@ rtx_renumbered_equal_p (x, y) ...@@ -3761,36 +3765,50 @@ rtx_renumbered_equal_p (x, y)
if (code == SUBREG) if (code == SUBREG)
{ {
i = REGNO (SUBREG_REG (x)); reg_x = REGNO (SUBREG_REG (x));
if (reg_renumber[i] >= 0) word_x = SUBREG_WORD (x);
i = reg_renumber[i];
i += SUBREG_WORD (x); if (reg_renumber[reg_x] >= 0)
{
reg_x = reg_renumber[reg_x] + word_x;
word_x = 0;
}
} }
else else
{ {
i = REGNO (x); reg_x = REGNO (x);
if (reg_renumber[i] >= 0) if (reg_renumber[reg_x] >= 0)
i = reg_renumber[i]; reg_x = reg_renumber[reg_x];
} }
if (GET_CODE (y) == SUBREG) if (GET_CODE (y) == SUBREG)
{ {
j = REGNO (SUBREG_REG (y)); reg_y = REGNO (SUBREG_REG (y));
if (reg_renumber[j] >= 0) word_y = SUBREG_WORD (y);
j = reg_renumber[j];
j += SUBREG_WORD (y); if (reg_renumber[reg_y] >= 0)
{
reg_y = reg_renumber[reg_y];
word_y = 0;
}
} }
else else
{ {
j = REGNO (y); reg_y = REGNO (y);
if (reg_renumber[j] >= 0) if (reg_renumber[reg_y] >= 0)
j = reg_renumber[j]; reg_y = reg_renumber[reg_y];
} }
return i == j;
return reg_x >= 0 && reg_x == reg_y && word_x == word_y;
} }
/* Now we have disposed of all the cases /* Now we have disposed of all the cases
in which different rtx codes can match. */ in which different rtx codes can match. */
if (code != GET_CODE (y)) if (code != GET_CODE (y))
return 0; return 0;
switch (code) switch (code)
{ {
case PC: case PC:
...@@ -3806,6 +3824,7 @@ rtx_renumbered_equal_p (x, y) ...@@ -3806,6 +3824,7 @@ rtx_renumbered_equal_p (x, y)
/* We can't assume nonlocal labels have their following insns yet. */ /* We can't assume nonlocal labels have their following insns yet. */
if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y)) if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
return XEXP (x, 0) == XEXP (y, 0); return XEXP (x, 0) == XEXP (y, 0);
/* Two label-refs are equivalent if they point at labels /* Two label-refs are equivalent if they point at labels
in the same position in the instruction stream. */ in the same position in the instruction stream. */
return (next_real_insn (XEXP (x, 0)) return (next_real_insn (XEXP (x, 0))
...@@ -3820,6 +3839,19 @@ rtx_renumbered_equal_p (x, y) ...@@ -3820,6 +3839,19 @@ rtx_renumbered_equal_p (x, y)
if (GET_MODE (x) != GET_MODE (y)) if (GET_MODE (x) != GET_MODE (y))
return 0; return 0;
/* For commutative operations, the RTX match if the operand match in any
order. Also handle the simple binary and unary cases without a loop. */
if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
&& rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
|| (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
&& rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
&& rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
else if (GET_RTX_CLASS (code) == '1')
return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
/* Compare the elements. If any pair of corresponding elements /* Compare the elements. If any pair of corresponding elements
fail to match, return 0 for the whole things. */ fail to match, return 0 for the whole things. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment