simplify-rtx.c (simplify_binary_operation_1): Try to simplify away NEG as operand of a MULT by merging it with the other operand.
* simplify-rtx.c (simplify_binary_operation_1): Try to simplify away NEG as operand of a MULT by merging it with the other operand. * combine.c (make_compound_operation): Use trunc_int_for_mode when generating a MULT with constant. Canonicalize PLUS and MINUS involving MULT. * config/arm/constraints.md (M): Examine only 32 bits of a HOST_WIDE_INT. * config/arm/predicates.md (power_of_two_operand): Likewise. From-SVN: r162849
This commit is contained in:
parent
15b71db372
commit
29b40d79bb
5 changed files with 96 additions and 5 deletions
|
@ -1,3 +1,14 @@
|
|||
2010-08-03 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* simplify-rtx.c (simplify_binary_operation_1): Try to simplify away
|
||||
NEG as operand of a MULT by merging it with the other operand.
|
||||
* combine.c (make_compound_operation): Use trunc_int_for_mode when
|
||||
generating a MULT with constant. Canonicalize PLUS and MINUS involving
|
||||
MULT.
|
||||
* config/arm/constraints.md (M): Examine only 32 bits of a
|
||||
HOST_WIDE_INT.
|
||||
* config/arm/predicates.md (power_of_two_operand): Likewise.
|
||||
|
||||
2010-08-03 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
|
||||
|
||||
* config/spu/spu.c (spu_emit_branch_hint): Do not access NOTE_KIND of
|
||||
|
|
|
@ -7110,13 +7110,79 @@ make_compound_operation (rtx x, enum rtx_code in_code)
|
|||
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
|
||||
&& INTVAL (XEXP (x, 1)) >= 0)
|
||||
{
|
||||
HOST_WIDE_INT count = INTVAL (XEXP (x, 1));
|
||||
HOST_WIDE_INT multval = (HOST_WIDE_INT) 1 << count;
|
||||
|
||||
new_rtx = make_compound_operation (XEXP (x, 0), next_code);
|
||||
new_rtx = gen_rtx_MULT (mode, new_rtx,
|
||||
GEN_INT ((HOST_WIDE_INT) 1
|
||||
<< INTVAL (XEXP (x, 1))));
|
||||
if (GET_CODE (new_rtx) == NEG)
|
||||
{
|
||||
new_rtx = XEXP (new_rtx, 0);
|
||||
multval = -multval;
|
||||
}
|
||||
multval = trunc_int_for_mode (multval, mode);
|
||||
new_rtx = gen_rtx_MULT (mode, new_rtx, GEN_INT (multval));
|
||||
}
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
lhs = XEXP (x, 0);
|
||||
rhs = XEXP (x, 1);
|
||||
lhs = make_compound_operation (lhs, MEM);
|
||||
rhs = make_compound_operation (rhs, MEM);
|
||||
if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG
|
||||
&& SCALAR_INT_MODE_P (mode))
|
||||
{
|
||||
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);
|
||||
goto maybe_swap;
|
||||
}
|
||||
x = gen_lowpart (mode, new_rtx);
|
||||
goto maybe_swap;
|
||||
|
||||
case MINUS:
|
||||
lhs = XEXP (x, 0);
|
||||
rhs = XEXP (x, 1);
|
||||
lhs = make_compound_operation (lhs, MEM);
|
||||
rhs = make_compound_operation (rhs, MEM);
|
||||
if (GET_CODE (rhs) == MULT && GET_CODE (XEXP (rhs, 0)) == NEG
|
||||
&& SCALAR_INT_MODE_P (mode))
|
||||
{
|
||||
tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (rhs, 0), 0),
|
||||
XEXP (rhs, 1));
|
||||
new_rtx = 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));
|
||||
new_rtx = simplify_gen_binary (PLUS, mode, tem, lhs);
|
||||
}
|
||||
else
|
||||
{
|
||||
SUBST (XEXP (x, 0), lhs);
|
||||
SUBST (XEXP (x, 1), rhs);
|
||||
return x;
|
||||
}
|
||||
return gen_lowpart (mode, new_rtx);
|
||||
|
||||
case AND:
|
||||
/* If the second operand is not a constant, we can't do anything
|
||||
with it. */
|
||||
|
@ -7345,6 +7411,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
|
|||
SUBST (XVECEXP (x, i, j), new_rtx);
|
||||
}
|
||||
|
||||
maybe_swap:
|
||||
/* If this is a commutative operation, the changes to the operands
|
||||
may have made it noncanonical. */
|
||||
if (COMMUTATIVE_ARITH_P (x)
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
"In Thumb-1 state a constant that is a multiple of 4 in the range 0-1020."
|
||||
(and (match_code "const_int")
|
||||
(match_test "TARGET_32BIT ? ((ival >= 0 && ival <= 32)
|
||||
|| ((ival & (ival - 1)) == 0))
|
||||
|| (((ival & (ival - 1)) & 0xFFFFFFFF) == 0))
|
||||
: ival >= 0 && ival <= 1020 && (ival & 3) == 0")))
|
||||
|
||||
(define_constraint "N"
|
||||
|
|
|
@ -289,7 +289,7 @@
|
|||
(define_predicate "power_of_two_operand"
|
||||
(match_code "const_int")
|
||||
{
|
||||
HOST_WIDE_INT value = INTVAL (op);
|
||||
unsigned HOST_WIDE_INT value = INTVAL (op) & 0xffffffff;
|
||||
|
||||
return value != 0 && (value & (value - 1)) == 0;
|
||||
})
|
||||
|
|
|
@ -2109,6 +2109,19 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
|
|||
if (trueop1 == constm1_rtx)
|
||||
return simplify_gen_unary (NEG, mode, op0, mode);
|
||||
|
||||
if (GET_CODE (op0) == NEG)
|
||||
{
|
||||
rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
|
||||
if (temp)
|
||||
return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
|
||||
}
|
||||
if (GET_CODE (op1) == NEG)
|
||||
{
|
||||
rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
|
||||
if (temp)
|
||||
return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
|
||||
}
|
||||
|
||||
/* Maybe simplify x * 0 to 0. The reduction is not valid if
|
||||
x is NaN, since x * 0 is then also NaN. Nor is it valid
|
||||
when the mode has signed zeros, since multiplying a negative
|
||||
|
|
Loading…
Add table
Reference in a new issue