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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |law at gcc dot gnu.org,
                   |                            |uros at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That is because the signed integer pos needs to be extended to 64-bit sizetype
for the array index and we only have the knowledge that pos is >= 0 in that
part of code during vrp passes and so the expansion or REE pass or similar
can't easily figure out that ZERO_EXTEND could be used the same as SIGN_EXTEND
and pick one that is cheaper.
Note, even using:
int
foo (int *table, int *ht, unsigned hash, unsigned mask)
{
  unsigned long probe, i;
  for (probe = hash & mask, i = 1;; ++i)
    {
      int pos = ht[probe];
      if (pos >= 0)
        {
          if (table[(unsigned) pos] == 42)
            return 1;
        }
      else if (pos & 1)
        return 0;
      probe += i;
      probe &= mask;
    }
}
doesn't help, because vrp pass optimize away the unsigned cast, because it
knows that pos in that chunk of code is >= 0, but not in others, so it can't be
preserved in range information.

Note we don't even optimize
int x;

long long
foo (void)
{
  if (x < -1)
    return 73;
  int y = x + 1;
  return y;
}
where the value range for y is known to be [0, INT_MAX] and so we should know
that when extending y to wider type both zero and sign extension give the same
result.  Dunno how the middle-end would know that zero_extend is cheaper though
(in this case really for free), perhaps the REE pass ought to know that.

Reply via email to