Ticket #2209 (closed merge: fixed)
MagicHash extraction is wrong on x86_64 with -fasm -O2
| Reported by: | quark | Owned by: | igloo |
|---|---|---|---|
| Priority: | normal | Milestone: | 6.8.3 |
| Component: | Compiler | Version: | 6.8.2 |
| Keywords: | Cc: | ravi | |
| Operating System: | Linux | Architecture: | x86_64 (amd64) |
| Type of failure: | Difficulty: | Unknown | |
| Test Case: | Blocked By: | ||
| Blocking: | Related Tickets: |
Description
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".

