mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 21:31:32 +08:00
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:
parent
b63d61f7d1
commit
f138ea5cba
@ -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
|
||||
|
102
gcc/expr.c
102
gcc/expr.c
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user