diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-08 02:15:36 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-08 02:15:36 +0000 |
commit | 7a9e3364f6d46f2e5d57455cdd2aed10df3bf5f7 (patch) | |
tree | 7d6bf1e1b40a2f41f7cb8871232be4ed7ebe2012 /gcc/expmed.c | |
parent | 9b1a61809f88c04374f27ddb7b611eb68d661538 (diff) | |
download | gcc-7a9e3364f6d46f2e5d57455cdd2aed10df3bf5f7.tar.gz |
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).
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91851 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 25 |
1 files changed, 20 insertions, 5 deletions
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; + + /* 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) |