From 58b42e19f7b39f55069798d8b4b834ba680fc22d Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Wed, 8 Dec 2004 02:15:36 +0000 Subject: [PATCH] re PR middle-end/18293 (Redundant copy operation introduced by expand) 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). From-SVN: r91851 --- gcc/ChangeLog | 8 ++++++++ gcc/expmed.c | 25 ++++++++++++++++++++----- gcc/loop.c | 4 +++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b74fcd8e516..b03f62a05b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2004-12-07 Roger Sayle + + 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 * tree-pretty-print.c (dump_array_domain): Split out from diff --git a/gcc/expmed.c b/gcc/expmed.c index c6c8058cc9e..47fc2d2bd47 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -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; - if (choose_mult_variant (mode, INTVAL (const_op1), &algorithm, &variant, + /* 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); + } + + 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) diff --git a/gcc/loop.c b/gcc/loop.c index 995df4863c2..15039e85bfc 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -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)