re PR middle-end/79665 (gcc's signed (x*x)/200 is slower than clang's)
authorTamar Christina <tamar.christina@arm.com>
Thu, 27 Apr 2017 09:58:27 +0000 (09:58 +0000)
committerTamar Christina <tnfchris@gcc.gnu.org>
Thu, 27 Apr 2017 09:58:27 +0000 (09:58 +0000)
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

gcc/ChangeLog
gcc/expr.c

index f5111d1..cc20232 100644 (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
index 29ebad3..c5c50e0 100644 (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)