PR middle-end/18293
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2004 02:15:36 +0000 (02:15 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2004 02:15:36 +0000 (02:15 +0000)
* expmed.c (EXACT_POWER_OF_2_OR_ZERO_P): Move definition earlier.
(expand_mult): Special case powers of two to avoid synth_mult.
* loop.c (product_cheap_p): Handle case where expand_mult does
require/generate any instructions (i.e. multiplication by zero).

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91851 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expmed.c
gcc/loop.c

index b74fcd8..b03f62a 100644 (file)
@@ -1,3 +1,11 @@
+2004-12-07  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/18293
+       * expmed.c (EXACT_POWER_OF_2_OR_ZERO_P): Move definition earlier.
+       (expand_mult): Special case powers of two to avoid synth_mult.
+       * loop.c (product_cheap_p): Handle case where expand_mult does
+       require/generate any instructions (i.e. multiplication by zero).
+
 2004-12-07  Richard Henderson  <rth@redhat.com>
 
        * tree-pretty-print.c (dump_array_domain): Split out from
index c6c8058..47fc2d2 100644 (file)
@@ -54,6 +54,9 @@ static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx);
 static rtx expand_smod_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
 static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
 
+/* Test whether a value is zero of a power of two.  */
+#define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
+
 /* Nonzero means divides or modulus operations are relatively cheap for
    powers of two, so don't use branches; emit the operation instead.
    Usually, this will mean that the MD file will emit non-branch
@@ -3024,11 +3027,25 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
   if (const_op1 && GET_CODE (const_op1) == CONST_INT
       && (unsignedp || !flag_trapv))
     {
-      int mult_cost = rtx_cost (gen_rtx_MULT (mode, op0, op1), SET);
+      HOST_WIDE_INT coeff = INTVAL (const_op1);
+      int mult_cost;
+
+      /* Special case powers of two.  */
+      if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
+       {
+         if (coeff == 0)
+           return const0_rtx;
+         if (coeff == 1)
+           return op0;
+         return expand_shift (LSHIFT_EXPR, mode, op0,
+                              build_int_cst (NULL_TREE, floor_log2 (coeff)),
+                              target, unsignedp);
+       }
 
-      if (choose_mult_variant (mode, INTVAL (const_op1), &algorithm, &variant,
+      mult_cost = rtx_cost (gen_rtx_MULT (mode, op0, op1), SET);
+      if (choose_mult_variant (mode, coeff, &algorithm, &variant,
                               mult_cost))
-       return expand_mult_const (mode, op0, INTVAL (const_op1), target,
+       return expand_mult_const (mode, op0, coeff, target,
                                  &algorithm, variant);
     }
 
@@ -3627,8 +3644,6 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
    (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28
    */
 
-#define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
-
 rtx
 expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
               rtx op0, rtx op1, rtx target, int unsignedp)
index 995df48..15039e8 100644 (file)
@@ -9202,7 +9202,9 @@ product_cheap_p (rtx a, rtx b)
   end_sequence ();
 
   win = 1;
-  if (INSN_P (tmp))
+  if (tmp == NULL_RTX)
+    ;
+  else if (INSN_P (tmp))
     {
       n_insns = 0;
       while (tmp != NULL_RTX)