[GHC] #8250: cgrun072 (optllvm) failing
GHC
ghc-devs at haskell.org
Sat Sep 7 15:48:55 CEST 2013
#8250: cgrun072 (optllvm) failing
-------------------------------------+------------------------------------
Reporter: leroux | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (LLVM) | Version: 7.6.3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: Runtime crash | Difficulty: Unknown
Test Case: cgrun072 | Blocked By:
Blocking: | Related Tickets: 7902
-------------------------------------+------------------------------------
Comment (by rwbarton):
This is a sign-extension issue: the expected output is `2239642456 =
0x857e3b58`, which treated as a signed 32-bit integer is `2239642456 -
2^32 = -2055324840`. Obviously, `show` on a `Word32` shouldn't be
producing output starting with a minus sign!
* The NCG generates code for `MO_BSwap W32` that does the byte swap and
clears the high 32 bits of the result. (This isn't directly relevant to
this test failure, but provides context for the rest.)
* The LLVM backend generates LLVM code that does the byte swap and then
sign-extends the result to 64 bits, like this:
{{{
%ln2uw = trunc i64 %ln2uv to i32
%ln2ux = call ccc i32 (i32)* @llvm.bswap.i32( i32 %ln2uw )
%ln2uy = sext i32 %ln2ux to i64
}}}
The reason is that `genCallSimpleCast` does `castVars` before and after
the call to `llvm.swap.i32`, and `castVars` produces `LM_Sext` for a
widening conversion. That's what's causing the strange test output—the
payload of a `Word32#` isn't supposed to have any of the high 32 bits set.
* The primop `BSwap32Op` is documented as
{{{
primop BSwap32Op "byteSwap32#" Monadic Word# -> Word#
{Swap bytes in the lower 32 bits of a word. The higher bytes are
undefined. }
}}}
so both the NCG and LLVM backends are correct, and the test is wrong. It
should be doing
{{{
bswap32 :: Word32 -> Word32
bswap32 (W32# w#) = W32# (narrow32Word# (byteSwap32# w#))
}}}
and the same for `bswap16`.
* The definitions of `byteSwap32` and `byteSwap16` in `GHC.Word` are also
wrong for the same reason. They should be
{{{
byteSwap32 :: Word32 -> Word32
byteSwap32 (W32# w#) = W32# (narrow32Word# (byteSwap32# w#))
}}}
This doesn't currently make a difference, though, because base is built
(by default?) with the NCG, which happens to produce a zero-extended
result.
An alternative approach would be to redefine the `BSwap32Op` primop to
clear the higher bytes of its result. Then the LLVM backend would need to
be fixed somehow (looks a little tricky to me) but the cgrun072 test and
GHC.Word would be correct as they are.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8250#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list