February 01, 2012
On 01/02/12 00:45, Martin Nowak wrote:
> On Tue, 31 Jan 2012 20:48:56 +0100, Jacob Carlborg <doob@me.com> wrote:
>
>> On 2012-01-31 19:56, Martin Nowak wrote:
>>> On Tue, 31 Jan 2012 18:13:29 +0100, Trass3r <un@known.com> wrote:
>>>
>>>>> Can anyone confirm this?
>>>>> If yes, bug in clang, dmd or phobos?
>>>>
>>>> Note that the dmd testsuite passes for me.
>>>
>>> Clang behaves differently, but it's probably not a bug.
>>>
>>> ----
>>> #include <stdio.h>
>>> #include <math.h>
>>>
>>> int main()
>>> {
>>> long double foo = NAN;
>>> double a = foo;
>>> double b = NAN;
>>> double c = fabs(NAN);
>>> printf("%Lf %d\n", foo, (int)signbit(foo));
>>> printf("%f %d\n", a, (int)signbit(a));
>>> printf("%f %d\n", b, (int)signbit(b));
>>> printf("%f %d\n", c, (int)signbit(c));
>>> }
>>> ----
>>>
>>> double a = foo; // seems like "FSTP m64fp" doesn't preserve the sign bit
>>>
>>> We need to fix the code in PortInitializer::PortInitializer() which
>>> relies on
>>> sign preserving of NaN size conversions.
>>
>> I thought Clang would be compatible with GCC.
>>
>
> I think it's undefined behavior to rely on the exact representation of NaN.
>
>  From what I've seen whether "a" ends up with a sign or not depends on
> processor
> internal state and is not specified by Intel, clang emits different code
> thus the difference.
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1486.htm

The behaviour of the sign bit is completely specified in the x86 manuals. As that link says, the C standard got it wrong in a couple of places.
The one thing which is implementation specific is that on Intel, an 80 bit load of a signalling NaN doesn't raise an exception, whereas it does on AMD. I don't know what Via does.

Also, when an invalid operation occurs, the exact bit pattern you get is implementation specific. For example on PowerPC you get a different bit pattern for 0/0 compared to sqrt(-1), while on x86 you get the same bit pattern for all of them. But, it is mandatory that NaN payloads be preserved. (Except for casts from double <-> float, that must obviously destroy the payload, probably in an implementation-specific way).






February 01, 2012
> The behaviour of the sign bit is completely specified in the x86
> manuals. As that link says, the C standard got it wrong in a couple of
> places.
> The one thing which is implementation specific is that on Intel, an 80
> bit load of a signalling NaN doesn't raise an exception, whereas it does
> on AMD. I don't know what Via does.

just a question:

would it be a good idea to test this platform specific behavior
in the phobos unit-tests?

produce "an 80 bit load of a signalling NaN"
check:
  intel: do not raise
  amd: do raise
  via: ...

maybe only for showing that D is aware of this special cases?
February 01, 2012
On 01/02/12 09:44, dennis luehring wrote:
>> The behaviour of the sign bit is completely specified in the x86
>> manuals. As that link says, the C standard got it wrong in a couple of
>> places.
>> The one thing which is implementation specific is that on Intel, an 80
>> bit load of a signalling NaN doesn't raise an exception, whereas it does
>> on AMD. I don't know what Via does.
>
> just a question:
>
> would it be a good idea to test this platform specific behavior
> in the phobos unit-tests?
>
> produce "an 80 bit load of a signalling NaN"
> check:
> intel: do not raise
> amd: do raise
> via: ...
>
> maybe only for showing that D is aware of this special cases?

It doesn't matter very much. If you load, and then do any operation (such as add) you'll get an exception. AMD will trigger one instruction earlier.
Hardly anybody knows this -- I haven't found any references to it. It's in wikipedia, but the entry that mentions it was written by me!

There is an underlying problem we have though. What _is_ T.init?
If a variable of type T is default initialized as "this is uninitialized", what is T.init?

In most cases, the compiler should give you a "variable XXX is used before set" error anyway.
February 01, 2012
On Wed, 01 Feb 2012 10:58:12 +0100, Don Clugston <dac@nospam.com> wrote:

> On 01/02/12 09:44, dennis luehring wrote:
>>> The behaviour of the sign bit is completely specified in the x86
>>> manuals. As that link says, the C standard got it wrong in a couple of
>>> places.
>>> The one thing which is implementation specific is that on Intel, an 80
>>> bit load of a signalling NaN doesn't raise an exception, whereas it does
>>> on AMD. I don't know what Via does.
>>
>> just a question:
>>
>> would it be a good idea to test this platform specific behavior
>> in the phobos unit-tests?
>>
>> produce "an 80 bit load of a signalling NaN"
>> check:
>> intel: do not raise
>> amd: do raise
>> via: ...
>>
>> maybe only for showing that D is aware of this special cases?
>
> It doesn't matter very much. If you load, and then do any operation (such as add) you'll get an exception. AMD will trigger one instruction earlier.
> Hardly anybody knows this -- I haven't found any references to it. It's in wikipedia, but the entry that mentions it was written by me!
>
> There is an underlying problem we have though. What _is_ T.init?
> If a variable of type T is default initialized as "this is uninitialized", what is T.init?
>
> In most cases, the compiler should give you a "variable XXX is used before set" error anyway.

"long double val = NAN;"
This is sNaN for Clang and qNaN for GCC.

--------------
At least on my Intel loading a sNaN and storing it in a double adds a sign.
--------------
import std.stdio, std.math;

void main()
{
    ubyte[10] snan = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x7F];
    ubyte[10] qnan = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x7F];
    real srval = 0, qrval = 0;
    double sdval = 0, qdval = 0;

    asm
    {
        fld  real ptr   snan[RBP];
        fst  double ptr sdval[RBP];
        fstp real ptr   srval[RBP];
        fld  real ptr   qnan[RBP];
        fst  double ptr qdval[RBP];
        fstp real ptr   qrval[RBP];
    }
    writefln("%s %s %s %s", srval, signbit(srval), sdval, signbit(sdval));
    writefln("%s %s %s %s", qrval, signbit(qrval), qdval, signbit(qdval));
}
--------------
nan 0 nan 1
nan 0 nan 0
1 2
Next ›   Last »