Message ID | 20201130105212.GG3788@tucnak |
---|---|
State | New |
Headers | show |
Series | Improve double-word mod even on powerpc [PR97459] | expand |
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 <jakub@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 > >
--- 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 ())