https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104522
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Uroš Bizjak from comment #5)
> (In reply to Richard Biener from comment #4)
> > But I do wonder whether real_from_target needs fixing to handle invalid
> > input gracefully which is ultimatively decode_ieee_extended?
>
> long double foo (void)
> {
> union { int i[4]; long double ld; } __tmp
> = { .i = { 0x1, 0, 0x4000, 0 } };
> return __tmp.ld;
> }
>
> This will fail compilation (-O -dP), without -dP (which avoids printing),
> the constant in the memory is wrong:
>
> .LC0:
> .long 1
> .long 0
> .long 0 <--- here should be 16384
> .long 0
That's because encode_ieee_extended detects this (.uexp == 2) as denormal
and does
case rvc_normal:
{
int exp = REAL_EXP (r);
/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
whereas the intermediate representation is 0.F x 2**exp.
Which means we're off by one.
Except for Motorola, which consider exp=0 and explicit
integer bit set to continue to be normalized. In theory
this discrepancy has been taken care of by the difference
in fmt->emin in round_for_format. */
if (denormal)
exp = 0;
we do call round_for_format in advance but that does nothing here.
One question would be if native_interpret_real needs to call round_for_format
as well if that's the entity that's supposed to fixup "invalid" FP
encodings.