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