aboutsummaryrefslogtreecommitdiff
path: root/gcc/compare-elim.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/compare-elim.c')
-rw-r--r--gcc/compare-elim.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
index 50bbaa8..8afbe76 100644
--- a/gcc/compare-elim.c
+++ b/gcc/compare-elim.c
@@ -734,7 +734,7 @@ try_merge_compare (struct comparison *cmp)
static bool
try_eliminate_compare (struct comparison *cmp)
{
- rtx flags, in_a, in_b, cmp_src;
+ rtx flags, in_a, in_b, cmp_a, cmp_b;
if (try_merge_compare (cmp))
return true;
@@ -786,7 +786,7 @@ try_eliminate_compare (struct comparison *cmp)
rtx x = XVECEXP (PATTERN (insn), 0, 0);
if (rtx_equal_p (SET_DEST (x), in_a))
- cmp_src = SET_SRC (x);
+ cmp_a = SET_SRC (x);
/* Also check operations with implicit extensions, e.g.:
[(set (reg:DI)
@@ -800,7 +800,7 @@ try_eliminate_compare (struct comparison *cmp)
&& (GET_CODE (SET_SRC (x)) == ZERO_EXTEND
|| GET_CODE (SET_SRC (x)) == SIGN_EXTEND)
&& GET_MODE (XEXP (SET_SRC (x), 0)) == GET_MODE (in_a))
- cmp_src = XEXP (SET_SRC (x), 0);
+ cmp_a = XEXP (SET_SRC (x), 0);
/* Also check fully redundant comparisons, e.g.:
[(set (reg:SI)
@@ -811,7 +811,7 @@ try_eliminate_compare (struct comparison *cmp)
&& GET_CODE (SET_SRC (x)) == MINUS
&& rtx_equal_p (XEXP (SET_SRC (x), 0), in_a)
&& rtx_equal_p (XEXP (SET_SRC (x), 1), in_b))
- cmp_src = in_a;
+ cmp_a = in_a;
else
return false;
@@ -819,17 +819,26 @@ try_eliminate_compare (struct comparison *cmp)
/* If the source uses addressing modes with side effects, we can't
do the merge because we'd end up with a PARALLEL that has two
instances of that side effect in it. */
- if (side_effects_p (cmp_src))
+ if (side_effects_p (cmp_a))
+ return false;
+
+ if (in_a == in_b)
+ cmp_b = cmp_a;
+ else if (rtx_equal_p (SET_DEST (x), in_b))
+ cmp_b = SET_SRC (x);
+ else
+ cmp_b = in_b;
+ if (side_effects_p (cmp_b))
return false;
/* Determine if we ought to use a different CC_MODE here. */
- flags = maybe_select_cc_mode (cmp, cmp_src, in_b);
+ flags = maybe_select_cc_mode (cmp, cmp_a, cmp_b);
if (flags == NULL)
flags = gen_rtx_REG (cmp->orig_mode, targetm.flags_regnum);
/* Generate a new comparison for installation in the setter. */
- rtx y = copy_rtx (cmp_src);
- y = gen_rtx_COMPARE (GET_MODE (flags), y, in_b);
+ rtx y = copy_rtx (cmp_a);
+ y = gen_rtx_COMPARE (GET_MODE (flags), y, copy_rtx (cmp_b));
y = gen_rtx_SET (flags, y);
/* Canonicalize instruction to: