http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54120
--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-01-07
16:34:14 UTC ---
Ah, ok, seems indeed to be HWI size related and also (due to an earlier bug)
related to the revision you've mentioned.
So, with an i686-linux -> hppa2.0w-hp-hpux11.11 cross this is reproduceable
with -O2 on:
extern unsigned int *kiss_seed_1;
extern unsigned int *kiss_seed_2;
unsigned int kiss_random_kernel(unsigned int * seed);
void
foo (double *x)
{
unsigned long long mask, kiss = ((unsigned long long) kiss_random_kernel
(kiss_seed_1)) << 32;
kiss += kiss_random_kernel (kiss_seed_2);
mask = ~ (unsigned long long) 0u << (64 - 53);
kiss = kiss & mask;
*x = (double) kiss * (0x1.p-64);
}
and the problem is that starting with r189366 VRP incorrectly does:
kiss_9 = kiss_8 & 0xfffffffffffff800;
- D.1358_10 = (double) kiss_9;
+ D.1363_17 = (signed int) kiss_9;
+ D.1358_10 = (double) D.1363_17;
The bugs seem to be in simplify_float_conversion_using_ranges and
range_fits_type_p. The simplify_float_conversion_using_ranges bug (now just
code consistency issue, before r189366 a real bug) is that the second
can_float_p is tested for != 0 (implicitly) instead of != CODE_FOR_nothing.
Starting with r189366 it doesn't make a real difference, before that
CODE_FOR_nothing was some big number and this fact hid the other bug.
>From the kiss_9 assignment, VRP determines vr to be
[0, 0xfffffffffffff800]
(in unsigned long long type).
And now the bug is that while range_fits_type_p (vr, 8, 0) and
range_fits_type_p (vr, 64, 0) correctly return false, such big 64-bit range
really doesn't fit into signed 8-bit or signed 64-bit range,
range_fits_type_p (vr, 16, 0) and range_fits_type_p (vr, 32, 0) incorrectly
return true - and for floatsidf2 there is a pattern, which is why we miscompile
it.