aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-05-10 16:41:35 +0200
committerYvan Roux <yvan.roux@linaro.org>2017-05-10 16:41:35 +0200
commitffc354ab2f2465daf14068b1ad2c7afec87a1c9e (patch)
tree796416f445ac663ebbc70a9e681c282e589105bb /gcc/expr.c
parent96120a0d3aa66005f59526908acca0ab23e06492 (diff)
Merge branches/gcc-7-branch rev 247824.
Change-Id: I68bb3c61e4d42b50a91c29bb86cb2c2c41741d63
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c104
1 files changed, 51 insertions, 53 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 29ebad3a061..c5c50e015ad 100644
--- a/gcc/expr.c
+++ b/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)