Ignore signedness for MO_XX_Conv
Ignore signedness for MO_XX_Conv
as it is used on (unsigned) words, too. Interpreting them as signed may lead to weird conversions / sign-extensions: E.g. on RISCV64 this conversion happened for a Word32# -> Word64#
:
%MO_XX_Conv_W32_W64(4294967293 :: W32) -> CmmLit (CmmInt (-3) W64)
-3
(64bit fffffffffffffffd
) is the sign extended value of 4294967293
(32bit 0xfffffffd
).
I spotted this on the wip/supersven/ghc-9.10-riscv-ncg
branch.
The written contract for MO_XX_Conv
is likely wrong:
| MO_XX_Conv Width Width -- int -> int; puts no requirements on the
-- contents of upper bits when extending;
-- narrowing is simply truncation; the only
-- expectation is that we can recover the
-- original value by applying the opposite
-- MO_XX_Conv, e.g.,
-- MO_XX_CONV W64 W8 (MO_XX_CONV W8 W64 x)
-- is equivalent to just x.
(https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/Cmm/MachOp.hs?ref_type=heads#L147)
In some contexts the upper bits matter depending on the type.