This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][GCC][mid-end] Align cost calculations of mod with div. (PR middle-end/79665)


Hi all,

r245676 (PR/79665) introduced a change to calculate the costs of signed
and unsigned div operations independently and when both are possible to
allow you to specify a preference via cost mode.

>From the cover letter https://gcc.gnu.org/ml/gcc-patches/2017-02/msg01408.html
this was also supposed to apply to modulo but it only changed division.
This adds the changes to modulo as well.

I believe this to be a regression from GCC7 since now modulo generates worse code
and blocks CSE when e.g. div and mod are used together.

Bootstrapped on aarch64-none-linux-gnu and x86_64-linux
and reg-tested on aarch64-none-linux-gnu with no regressions.

OK for trunk and back-port to GCC7?

Thanks,
Tamar


gcc/
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.
diff --git a/gcc/expr.c b/gcc/expr.c
index 91d7ea217229fac62380b5d4b646961bf7c836c1..00f08aad55c90a0563bf93cf578107fe0b871231 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8791,54 +8791,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;
 
@@ -8848,16 +8856,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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]