https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119103

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #10)
> (In reply to Jakub Jelinek from comment #9)
> > Shouldn't we optimize this in match.pd when global range says it is ok or
> > during vrp/evrp using local ranges?  I mean turn the int shift into
> > {,un}signed {char,short} one depending on the shift amount range and casts
> > before/after the shift.
> 
> Sure, but I think this is orthogonal to the addressed issues.  I think
> there are a lot of targets that cannot do shifts on smaller than word_mode
> so the question is whether the demotion would result in extensions that
> are hard to eliminate later?  There were talks about a promotion pass
> on GIMPLE in the past as well.

We should have both demotion and promotion passes, demotion allows to avoid
computation of things we won't ever need to compute due to later casts, and
promotion (before/during vectorization for vectorized loops to make the
vectorized loop use fewer vector sizes and before expansion if targets prefer
so) might result in better code generation over leaving things up to
ree/ext-dse/combine and similar passes.

Right now, we do aggressive demotion only during FE folding, e.g. on
unsigned char
foo (unsigned char a, unsigned char b)
{
  unsigned char c = a + b;
  unsigned char d = a >> b;
  unsigned char e = a << b;
  return a * b * c;
}
the addition and multiplications are demoted to 8-bit, but this only works
inside of single statements; and shifts are never demoted because the shift
counts could be in the range [bitsize of narrower type, bitsize of int-1], plus
we don't have range info in the FEs.
We don't demote e.g. for
unsigned char
foo (unsigned char a, unsigned char b)
{
  int c = a + b;
  unsigned char d = c;
  int e = a * b;
  unsigned char f = e;
  int g = f * c;
  return g;
}

And promotion is something we do during expansion if targets can't do sub-word
or sub-32-bit arithmetics.

Reply via email to