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.
/* 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: