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:
