re PR middle-end/79665 (gcc's signed (x*x)/200 is slower than clang's)

2017-04-26  Tamar Christina  <tamar.christina@arm.com>

	PR middle-end/79665
	* expr.c (expand_expr_real_2): Move TRUNC_MOD_EXPR, FLOOR_MOD_EXPR,
	CEIL_MOD_EXPR, ROUND_MOD_EXPR cases.

From-SVN: r247307
This commit is contained in:
Tamar Christina 2017-04-27 09:58:27 +00:00 committed by Tamar Christina
parent b63d61f7d1
commit f138ea5cba
2 changed files with 56 additions and 52 deletions

View File

@ -1,3 +1,9 @@
2017-04-27 Tamar Christina <tamar.christina@arm.com>
PR middle-end/79665
* expr.c (expand_expr_real_2): Move TRUNC_MOD_EXPR, FLOOR_MOD_EXPR,
CEIL_MOD_EXPR, ROUND_MOD_EXPR cases.
2017-04-27 Jakub Jelinek <jakub@redhat.com>
PR target/77728

View File

@ -8792,54 +8792,62 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
case CEIL_MOD_EXPR:
case ROUND_MOD_EXPR:
case TRUNC_DIV_EXPR:
case FLOOR_DIV_EXPR:
case CEIL_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
/* If this is a fixed-point operation, then we cannot use the code
below because "expand_divmod" doesn't support sat/no-sat fixed-point
divisions. */
if (ALL_FIXED_POINT_MODE_P (mode))
goto binop;
if (modifier == EXPAND_STACK_PARM)
target = 0;
/* Possible optimization: compute the dividend with EXPAND_SUM
then if the divisor is constant can optimize the case
where some terms of the dividend have coeffs divisible by it. */
expand_operands (treeop0, treeop1,
subtarget, &op0, &op1, EXPAND_NORMAL);
if (SCALAR_INT_MODE_P (mode)
&& optimize >= 2
&& get_range_pos_neg (treeop0) == 1
&& get_range_pos_neg (treeop1) == 1)
{
/* If both arguments are known to be positive when interpreted
as signed, we can expand it as both signed and unsigned
division or modulo. Choose the cheaper sequence in that case. */
bool speed_p = optimize_insn_for_speed_p ();
do_pending_stack_adjust ();
start_sequence ();
rtx uns_ret = expand_divmod (0, code, mode, op0, op1, target, 1);
rtx_insn *uns_insns = get_insns ();
end_sequence ();
start_sequence ();
rtx sgn_ret = expand_divmod (0, code, mode, op0, op1, target, 0);
rtx_insn *sgn_insns = get_insns ();
end_sequence ();
unsigned uns_cost = seq_cost (uns_insns, speed_p);
unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
{
emit_insn (uns_insns);
return uns_ret;
}
emit_insn (sgn_insns);
return sgn_ret;
}
return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
{
/* If this is a fixed-point operation, then we cannot use the code
below because "expand_divmod" doesn't support sat/no-sat fixed-point
divisions. */
if (ALL_FIXED_POINT_MODE_P (mode))
goto binop;
if (modifier == EXPAND_STACK_PARM)
target = 0;
/* Possible optimization: compute the dividend with EXPAND_SUM
then if the divisor is constant can optimize the case
where some terms of the dividend have coeffs divisible by it. */
expand_operands (treeop0, treeop1,
subtarget, &op0, &op1, EXPAND_NORMAL);
bool mod_p = code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
|| code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR;
if (SCALAR_INT_MODE_P (mode)
&& optimize >= 2
&& get_range_pos_neg (treeop0) == 1
&& get_range_pos_neg (treeop1) == 1)
{
/* If both arguments are known to be positive when interpreted
as signed, we can expand it as both signed and unsigned
division or modulo. Choose the cheaper sequence in that case. */
bool speed_p = optimize_insn_for_speed_p ();
do_pending_stack_adjust ();
start_sequence ();
rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
rtx_insn *uns_insns = get_insns ();
end_sequence ();
start_sequence ();
rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
rtx_insn *sgn_insns = get_insns ();
end_sequence ();
unsigned uns_cost = seq_cost (uns_insns, speed_p);
unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
{
emit_insn (uns_insns);
return uns_ret;
}
emit_insn (sgn_insns);
return sgn_ret;
}
return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
}
case RDIV_EXPR:
goto binop;
@ -8849,16 +8857,6 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
gcc_assert (temp);
return temp;
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
case CEIL_MOD_EXPR:
case ROUND_MOD_EXPR:
if (modifier == EXPAND_STACK_PARM)
target = 0;
expand_operands (treeop0, treeop1,
subtarget, &op0, &op1, EXPAND_NORMAL);
return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
case FIXED_CONVERT_EXPR:
op0 = expand_normal (treeop0);
if (target == 0 || modifier == EXPAND_STACK_PARM)