https://gcc.gnu.org/g:439f966973a77f97f6c015cde6a9507e3be9f620

commit r17-389-g439f966973a77f97f6c015cde6a9507e3be9f620
Author: Richard Sandiford <[email protected]>
Date:   Thu May 7 21:18:03 2026 +0100

    combine: Tweak make_compound_operation PLUS/MINUS cases
    
    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.
    
    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.

Diff:
---
 gcc/combine.cc | 57 +++++----------------------------------------------------
 1 file changed, 5 insertions(+), 52 deletions(-)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index e0dab3d88280..d401ca10083b 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

Reply via email to