develooper Front page | perl.perl5.porters | Postings from June 2016

Re: [perl #128487] [Win32] signalling NaN is evasive on recent32-bit perls

Thread Previous | Thread Next
From:
Tony Cook
Date:
June 27, 2016 10:52
Subject:
Re: [perl #128487] [Win32] signalling NaN is evasive on recent32-bit perls
Message ID:
20160627105201.GA29470@mars.tony.develop-help.com
On Mon, Jun 27, 2016 at 02:50:28AM -0700, Sisyphus wrote:
> This report is a result of issues raised in
> http://www.perlmonks.org/?node_id=1166429
> 
> It affects "MSWin32-x86-multi-thread-64int" builds of (at least) perl 
> 5.22.0, 5.24.0 and
> 5.25.2.
> But "MSWin32-x64-multi-thread" builds of perl 5.22.0, 5.24.0 and 5.25.2 are 
> *not* affected.
> 
> Both of those architectures have nvtype of 'double' and ivtype of 'long 
> long' - and endianness is, of course, little-endian.
> 
> Example 1:
> =========
> 
> C:\_32\pscrpt>type t1.pl
> $snan = unpack 'd',  pack 'h16', scalar reverse '7ff0000000000001';
> print scalar reverse unpack 'h16', pack 'd', $snan;
> 
> C:\_32\pscrpt>perl -lw t1.pl
> 7ff8000000000001
> 
> A signalling NaN has been requested, but we're informed that we got a quiet 
> NaN.
> 
> Example 2: (needs 5.24.0 or later)
> =========
> 
> C:\_32\pscrpt>type t1.pl
> $snan = unpack 'd',  pack 'h16', scalar reverse '7ff0000000000001';
> print "\$snan issignalling: ", issignaling($snan);
> 
> $snan2 = 0;
> 
> setpayloadsig($snan2, 15);
> print "\$snan2 issignalling: ", issignaling($snan2);
> 
> print scalar reverse unpack 'h16', pack 'd', $snan2;
> 
> C:\_32\pscrpt>perl -MPOSIX=":nan_payload" -lw t1.pl
> $snan issignalling: 0
> $snan2 issignalling: 0
> 7ff800000000000f
> 
> Here we see that POSIX::issignaling also informs us that the signalling NaN 
> we requested in Example 1 is a quiet NaN.
> POSIX::issignaling further informs us that a NaN set using setpayloadsig is 
> a quiet NaN, too - and unpack/pack agrees.
> 
> Example 3: (also needs 5.24.0 or later)
> =========
> 
> C:\_32\pscrpt>type t1.pl
> use Inline C => <<'EOC';
> 
> typedef union {
>     double  d;
>     long long i;
> } BITS64;
> 
> double get_snan () {
>   BITS64 x;
> 
>   x.i = 0x7ff0000000000001;
> 
>   return x.d;
> }
> 
> EOC
> 
> $snan = get_snan();
> print "\$snan issignalling: ", issignaling($snan);
> print scalar reverse unpack 'h16', pack 'd', $snan;
> 
> C:\_32\pscrpt>perl -MPOSIX=":nan_payload" -lw t1.pl
> $snan issignalling: 0
> 7ff8000000000001
> 
> Again we are told that $snan, which should be signalling, is quiet. (We can 
> run this script on 5.22.0 if the issignaling call is removed - in which case 
> we still get output of 7ff8000000000001.)
> 
> I think this issue can also affect other configurations of Windows perl  (eg 
> "long double" builds and 32-bit builds where ivsize is 4) but I haven't 
> checked on that properly.
> 
> Output of perl -V for 5.24.0 follows.

It's a bug in the 32-bit x86 ABI, see:

https://rt.perl.org/Ticket/Display.html?id=125710

where we first saw the problem, and:

http://stackoverflow.com/questions/22816095/signalling-nan-was-corrupted-when-returning-from-x86-function-flds-fstps-of-x87

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57484#c12

Material which that perlmonks discussion appears to cover.

Tony

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About