[Bug rtl-optimization/82889] Unnecessary sign extension of int32 to int64
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Nov 8 15:11:00 GMT 2017
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.
More information about the Gcc-bugs
mailing list