Skip to content

Ignore signedness for MO_XX_Conv

Sven Tennie requested to merge wip/supersven/fix-MO_XX_Conv-folding into master

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.

Edited by Sven Tennie

Merge request reports