On Mon, Aug 9, 2021 at 10:13 AM Roger Sayle <ro...@nextmovesoftware.com> wrote:
>
>
> This patch allows GCC to constant fold (i | (i<<16)) | ((i<<24) | (i<<8)),
> where i is an unsigned char, or the equivalent (i*65537) | (i*16777472), to
> i*16843009.  The trick is to teach tree_nonzero_bits which bits may be
> set in the result of a multiplication by a constant given which bits are
> potentially set in the operands.  This allows the optimizations recently
> added to match.pd to catch more cases.
>
> The required mask/value pair from a multiplication may be calculated using
> a classical shift-and-add algorithm, given we already have implementations
> for both addition and shift by constant.  To keep this optimization "cheap",
> this functionality is only used if the constant multiplier has a few bits
> set (unless flag_expensive_optimizations), and we provide a special case
> fast-path implementation for the common case where the (non-constant)
> operand has no bits that are guaranteed to be set.  I have no evidence
> that this functionality causes performance issues, it's just that sparse
> multipliers provide the largest benefit to CCP.
>
> This patch has been tested on x86_64-pc-linux-gnu with "make bootstrap"
> and "make -k check" with no new failures.
>
> Ok for mainline?

OK.

Thanks,
Richard.

>
> 2021-08-09  Roger Sayle  <ro...@nextmovesoftware.com>
>
> gcc/ChangeLog
>         * tree-ssa-ccp.c (bit_value_mult_const): New helper function to
>         calculate the mask-value pair result of a multiplication by an
>         unsigned constant.
>         (bit_value_binop) [MULT_EXPR]:  Call it from here for
> multiplications
>         by non-negative constants.
>
> gcc/testsuite/ChangeLog
>         * gcc.dg/fold-ior-5.c: New test case.
>
> Roger
> --
>

Reply via email to