Ticket #2209 (closed merge: fixed)
MagicHash extraction is wrong on x86_64 with -fasm -O2
|Reported by:||quark||Owned by:||igloo|
|Operating System:||Linux||Architecture:||x86_64 (amd64)|
|Type of failure:||Difficulty:||Unknown|
|Test Case:||Blocked By:|
I am trying to directly get at the underlying IEEE representation of a Double with this code:
word64ToDouble :: Word64 -> Double word64ToDouble w@(W64# x) = D# (unsafeCoerce# x) doubleToWord64 :: Double -> Word64 doubleToWord64 d@(D# x) = W64# (unsafeCoerce# x)
I have, of course, checked "isEEE x" and "(sizeOf x) == 8" etc, to know that it is OK to do this.
This works on various x86 computers but fails on x86_64, when compiling with -fasm and -O2 (which I embedded with the OPTIONS pragma in the attached example).
The example shows that for a Double "2.0", the Word64 is wrong. And for a Word64 which should represent Nan, "isNaN" fails. Here is the output of the program on "x86_64" (the buggy system):
False: NaN 5697656 expect: 4611686018427387904
Here is the expected output as seen on x86 systems:
True 4611686018427387904 expect: 4611686018427387904
Note that if you insert a "trace" call to display the Integer, Word64, or Double, the example gives the right output! But when you take out the trace, it fails.
If a workaround for this problem can be identified, we would really appreciate it, as we are hitting this bug in code that we need to use but cannot workaround. If a fix is identified, it would be great if the fix made it into 6.8.3 (as we are happy to upgrade to that, rather than wait for a next stable release).
In our system, we do have a workaround for the "doubleToWord64" bug, but I cannot reproduce it in the small example. What we do is define the function like this:
doubleToWord64 :: Double -> Word64 doubleToWord64 d@(D# x) = if (d == d) then W64# (unsafeCoerce# x) else err ("doubleToWord64 " ++ show d)
This works in out system, but not in the attached example. And, again, we have no workaround for "word64ToDouble".