Skip to content

Sub-word right-arithmetic-shifts appear to be wrong on x86

While validating bgamari/test-primops> in preparation for looking at #20594 (closed), I noticed that even the x86 NCG doesn't match the reference implementation. Specifically, consider this C-- program:

test() {
    bits64 ret;
    ret = %zx64(%shra(242::bits8, 1));
    return (ret);
}

I would expect this to return (242>>1) | (1<<7) == 249. However, when compiled with GHC 8.10.7 it returns 121, as demonstrated by this program:

{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE MagicHash #-}

module Main where

import GHC.Exts
import GHC.Ptr
import Foreign.Marshal.Alloc

foreign import prim "test" test :: Addr# -> Word#

main :: IO ()
main = do
  Ptr p <- callocBytes (1*1000*1000)
  print $ W# (test p)
Edited by Ben Gamari
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information