https://gcc.gnu.org/g:a68a67d9ba10a3867b619cc4d52d7e23a5d6976c

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

    rtlanal: Tweak operator precedence for comparisons
    
    One quirk of the commutative operand precedence rules is that:
    
    - PLUS and MINUS have precedence 4
    - other binary arithmetic operators have precedence 2
    - NOT and NEG have precedence 1
    - (binary) comparison operators have precedence 0
    
    This means that the arithmetic inverse operator (NEG) has a lower
    precedence than the binary arithmetic operators, but the logical
    inverse operator (NOT) has a higher precedence than binary comparisons
    that produce a logical result.  In other words, we have:
    
      some binary > some unary > some other binary
    
    This patch shuffles the precedence values so that all binary operators
    have precedence over all unary operators.  It means that existing
    aarch64.md patterns such as:
    
      (define_insn "*add<mode>3_carryinC_zero"
        [(set (reg:CC_ADC CC_REGNUM)
              (compare:CC_ADC
                (plus:<DWI>
                  (match_operand:<DWI> 2 "aarch64_carry_operation" "")
                  (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" 
"r")))
                (match_operand 4 "const_scalar_int_operand" "")))
         (set (match_operand:GPI 0 "register_operand" "=r")
              (plus:GPI (match_operand:GPI 3 "aarch64_carry_operation" "")
                        (match_dup 1)))]
    
    are now canonical.
    
    gcc/
            * rtlanal.cc (commutative_operand_precedence): Bump the precedence
            of non-commutative binary arithmetic to 3.  Give comparisons a
            precedence of 2.

Diff:
---
 gcc/rtlanal.cc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index 88561a54e5a0..5274a5c59cf1 100644
--- a/gcc/rtlanal.cc
+++ b/gcc/rtlanal.cc
@@ -3829,6 +3829,13 @@ commutative_operand_precedence (rtx op)
       /* If only one operand is a binary expression, it will be the first
          operand.  In particular,  (plus (minus (reg) (reg)) (neg (reg)))
          is canonical, although it will usually be further simplified.  */
+      return 3;
+
+    case RTX_COMM_COMPARE:
+    case RTX_COMPARE:
+      /* Give comparisons a cost between the unary expressions below
+        and the other binary expressions above, so that we don't have
+        a situation where the canonical order is binary, unary, binary.  */
       return 2;
 
     case RTX_UNARY:

Reply via email to