On Mon, 30 Nov 2020, Jakub Jelinek wrote:

> Hi!
> 
> I have noticed that while my (already committed, thanks for review)
> patch works on x86, it doesn't work on powerpc*.  The problem is that
> we don't have lshr double-word optab (neither TImode nor for -m32 DImode),
> but as expander has code for double-word shift, that doesn't really matter.
> As the implementation is prepared to punt whenever something can't be
> expanded with OPTAB_DIRECT and in the end also punts if any library calls
> would be emitted, the optab_handler checks were just to save compile time.
> 
> On the other side, for even divisors, we know that (1 << bit) % (2 * x)
> for bit > 0 will never be equal to 1, because both dividend and divisor
> are even and so remainder will be even too, so we can save some compile time
> by adding an early exit.
> 
> The even divisors can be handled with the approach Thomas wrote about
> (perhaps generalized into divisors equal to what expand_doubleword_mod
> can handle times some power of two where we can handle power of two modulo
> cheaply), but that would be done in a different function...
> And we could use ctz to find the power of two...
> 
> Ok for trunk if it passes bootstrap/regtest on powerpc*?

OK.

Richard.

> 2020-11-30  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR rtl-optimization/97459
>       * optabs.c (expand_doubleword_mod): Punt early for even op1.
>       (expand_binop): Don't require lshr_optab double-word handler.
> 
> --- gcc/optabs.c.jj   2020-11-30 10:55:33.135963309 +0100
> +++ gcc/optabs.c      2020-11-30 11:40:54.768436219 +0100
> @@ -949,7 +949,7 @@ expand_doubleword_mult (machine_mode mod
>  static rtx
>  expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
>  {
> -  if (INTVAL (op1) <= 1)
> +  if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
>      return NULL_RTX;
>  
>    rtx_insn *last = get_last_insn ();
> @@ -2004,7 +2004,6 @@ expand_binop (machine_mode mode, optab b
>        && CONST_INT_P (op1)
>        && is_int_mode (mode, &int_mode)
>        && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
> -      && optab_handler (lshr_optab, int_mode) != CODE_FOR_nothing
>        && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
>        && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
>        && optimize_insn_for_speed_p ())
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to