Commit c877353c by Roger Sayle Committed by Roger Sayle

re PR rtl-optimization/12260 (ICE in output_operand: invalid expression as operand)


	PR optimization/12260
	* simplify-rtx.c (simplify_unary_operation): Simplify all unary
	operations through CONST nodes.  Optimize (neg (plus X C)) as
	(minus -C X) for constant values C.
	(simplify_binary_operation): Optimize (minus (neg X) C) as
	(minus -C X) for constant values C.
	(simplify_plus_minus): Avoid creating (neg (const (plus X C)),
	instead create (minus -C X).

	* gcc.c-torture/compile/20031011-2.c: New test case.

From-SVN: r72379
parent e3be1116
2003-10-11 Roger Sayle <roger@eyesopen.com> 2003-10-11 Roger Sayle <roger@eyesopen.com>
PR optimization/12260
* simplify-rtx.c (simplify_unary_operation): Simplify all unary
operations through CONST nodes. Optimize (neg (plus X C)) as
(minus -C X) for constant values C.
(simplify_binary_operation): Optimize (minus (neg X) C) as
(minus -C X) for constant values C.
(simplify_plus_minus): Avoid creating (neg (const (plus X C)),
instead create (minus -C X).
2003-10-11 Roger Sayle <roger@eyesopen.com>
* expr.c (expand_expr <PLUS_EXPR>): Let expand_operands call * expr.c (expand_expr <PLUS_EXPR>): Let expand_operands call
safe_from_p for us, once it chooses an evaluation order. safe_from_p for us, once it chooses an evaluation order.
(expand_expr <MULT_EXPR>): Likewise. (expand_expr <MULT_EXPR>): Likewise.
......
...@@ -407,6 +407,8 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -407,6 +407,8 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
return gen_rtx_CONST_VECTOR (mode, v); return gen_rtx_CONST_VECTOR (mode, v);
} }
} }
else if (GET_CODE (op) == CONST)
return simplify_unary_operation (code, mode, XEXP (op, 0), op_mode);
if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR) if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR)
{ {
...@@ -971,11 +973,22 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -971,11 +973,22 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
return simplify_gen_binary (MINUS, mode, XEXP (op, 1), return simplify_gen_binary (MINUS, mode, XEXP (op, 1),
XEXP (op, 0)); XEXP (op, 0));
/* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
if (GET_CODE (op) == PLUS if (GET_CODE (op) == PLUS
&& !HONOR_SIGNED_ZEROS (mode) && !HONOR_SIGNED_ZEROS (mode)
&& !HONOR_SIGN_DEPENDENT_ROUNDING (mode)) && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
{ {
/* (neg (plus A C)) is simplified to (minus -C A). */
if (GET_CODE (XEXP (op, 1)) == CONST_INT
|| GET_CODE (XEXP (op, 1)) == CONST_DOUBLE)
{
temp = simplify_unary_operation (NEG, mode, XEXP (op, 1),
mode);
if (temp)
return simplify_gen_binary (MINUS, mode, temp,
XEXP (op, 0));
}
/* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode); temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1)); return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
} }
...@@ -1572,6 +1585,16 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -1572,6 +1585,16 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
if (GET_CODE (op1) == NEG) if (GET_CODE (op1) == NEG)
return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0)); return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
/* (-x - c) may be simplified as (-c - x). */
if (GET_CODE (op0) == NEG
&& (GET_CODE (op1) == CONST_INT
|| GET_CODE (op1) == CONST_DOUBLE))
{
tem = simplify_unary_operation (NEG, mode, op1, mode);
if (tem)
return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
}
/* If one of the operands is a PLUS or a MINUS, see if we can /* If one of the operands is a PLUS or a MINUS, see if we can
simplify this by the associative law. simplify this by the associative law.
Don't use the associative law for floating point. Don't use the associative law for floating point.
...@@ -2375,6 +2398,13 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0, ...@@ -2375,6 +2398,13 @@ simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
/* Sort the operations based on swap_commutative_operands_p. */ /* Sort the operations based on swap_commutative_operands_p. */
qsort (ops, n_ops, sizeof (*ops), simplify_plus_minus_op_data_cmp); qsort (ops, n_ops, sizeof (*ops), simplify_plus_minus_op_data_cmp);
/* Create (minus -C X) instead of (neg (const (plus X C))). */
if (n_ops == 2
&& GET_CODE (ops[1].op) == CONST_INT
&& CONSTANT_P (ops[0].op)
&& ops[0].neg)
return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
/* We suppressed creation of trivial CONST expressions in the /* We suppressed creation of trivial CONST expressions in the
combination loop to avoid recursion. Create one manually now. combination loop to avoid recursion. Create one manually now.
The combination loop should have ensured that there is exactly The combination loop should have ensured that there is exactly
......
2003-10-11 Roger Sayle <roger@eyesopen.com> 2003-10-11 Roger Sayle <roger@eyesopen.com>
PR optimization/12260
* gcc.c-torture/compile/20031011-2.c: New test case.
2003-10-11 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/20031011-1.c: New testcase. * gcc.c-torture/execute/20031011-1.c: New testcase.
2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr> 2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
......
/* PR optimization/12260. */
extern int f(void);
extern int g(int);
static char buf[512];
void h(int l) {
while (l) {
char *op = buf;
if (f() == 0)
break;
if (g(op - buf + 1))
break;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment