This patch tackles two problems with the make_compound_operation(_int)
handling of PLUS:

(a) The PLUS case had some simplifications related to multiplications
    of negative numbers.  Those simplifications assigned the simplified
    form to the variable "new_rtx", but the rest of the case ignored
    new_rtx and returned the original expression "x".  This had the
    effect of discarding both the simplification result and the
    recursive make_compound_operation results.

(b) The PLUS case applied maybe_swap_commutative_operands after
    substituting the recursive make_compound_operation results.
    That's good enough for unchained PLUSes.  However, if the
    expression is a nest of PLUSes, we might need to redistribute
    operands in the entire nest.

    For example, expand_compound_operation converts sign and zero
    extensions to shifts.  The extensions have commutative operand
    priority 0, whereas the shifts have priority 2.  This means that:

      (plus (plus (not X) (zero_extend Y)) (zero_extend Z))

    is correctly ordered, since PLUS has priority 4, NOT has priority 1,
    and ZERO_EXTEND has priority 0.  But when expand_compound_operation
    converts the extends to shifts, the NOT becomes the lowest priority
    operand, giving:

      (plus (plus (lshiftrt ...) (lshiftrt ...)) (not X))

    Currently, make_compound_operation would convert that back to:

      (plus (plus (zero_extend Y) (zero_extend Z)) (not X))

    since, considered in isolation, neither PLUS needs a swap.
    This result is not canonical, since the NOT should be first.

Both problems can be dealt with by using simplify_gen_binary instead.
That already has the simplifications for (a) and knows how to
redistribute operands in nested operations.

Although the MINUS case seemed to be ok, the simplifications there
also duplicate what simplify_gen_binary would do.

This is likely to be needed for Muhammad's uaddc/usubc patches.

Tested on aarch64-linux-gnu, powerpc64le-linux-gnu & x86_64-linux-gnu.
OK to install?

Richard


gcc/
        * combine.cc (make_compound_operation_int): Remove PLUS and MINUS
        simplifications and PLUS operand order swapping.  Delegate those
        tasks to simplify_gen_binary instead.
---
 gcc/combine.cc | 57 +++++---------------------------------------------
 1 file changed, 5 insertions(+), 52 deletions(-)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index e0dab3d8828..d401ca10083 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -8118,59 +8118,12 @@ make_compound_operation_int (scalar_int_mode mode, rtx 
*x_ptr,
       break;
 
     case PLUS:
-      lhs = XEXP (x, 0);
-      rhs = XEXP (x, 1);
-      lhs = make_compound_operation (lhs, next_code);
-      rhs = make_compound_operation (rhs, next_code);
-      if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG)
-       {
-         tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (lhs, 0), 0),
-                                    XEXP (lhs, 1));
-         new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
-       }
-      else if (GET_CODE (lhs) == MULT
-              && (CONST_INT_P (XEXP (lhs, 1)) && INTVAL (XEXP (lhs, 1)) < 0))
-       {
-         tem = simplify_gen_binary (MULT, mode, XEXP (lhs, 0),
-                                    simplify_gen_unary (NEG, mode,
-                                                        XEXP (lhs, 1),
-                                                        mode));
-         new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
-       }
-      else
-       {
-         SUBST (XEXP (x, 0), lhs);
-         SUBST (XEXP (x, 1), rhs);
-       }
-      maybe_swap_commutative_operands (x);
-      return x;
-
     case MINUS:
-      lhs = XEXP (x, 0);
-      rhs = XEXP (x, 1);
-      lhs = make_compound_operation (lhs, next_code);
-      rhs = make_compound_operation (rhs, next_code);
-      if (GET_CODE (rhs) == MULT && GET_CODE (XEXP (rhs, 0)) == NEG)
-       {
-         tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (rhs, 0), 0),
-                                    XEXP (rhs, 1));
-         return simplify_gen_binary (PLUS, mode, tem, lhs);
-       }
-      else if (GET_CODE (rhs) == MULT
-              && (CONST_INT_P (XEXP (rhs, 1)) && INTVAL (XEXP (rhs, 1)) < 0))
-       {
-         tem = simplify_gen_binary (MULT, mode, XEXP (rhs, 0),
-                                    simplify_gen_unary (NEG, mode,
-                                                        XEXP (rhs, 1),
-                                                        mode));
-         return simplify_gen_binary (PLUS, mode, tem, lhs);
-       }
-      else
-       {
-         SUBST (XEXP (x, 0), lhs);
-         SUBST (XEXP (x, 1), rhs);
-         return x;
-       }
+      lhs = make_compound_operation (XEXP (x, 0), next_code);
+      rhs = make_compound_operation (XEXP (x, 1), next_code);
+      if (lhs != XEXP (x, 0) || rhs != XEXP (x, 1))
+       return simplify_gen_binary (code, mode, lhs, rhs);
+      return x;
 
     case AND:
       /* If the second operand is not a constant, we can't do anything
-- 
2.54.0

Reply via email to