Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/CmmToAsm/X86/CodeGen.hs
    ... ... @@ -6067,10 +6067,23 @@ genByteSwap width dst src = do
    6067 6067
           W64 | is32Bit -> do
    
    6068 6068
             let Reg64 dst_hi dst_lo = localReg64 dst
    
    6069 6069
             RegCode64 vcode rhi rlo <- iselExpr64 src
    
    6070
    -        return $ vcode `appOL`
    
    6071
    -                 toOL [ MOV II32 (OpReg rlo) (OpReg dst_hi),
    
    6072
    -                        MOV II32 (OpReg rhi) (OpReg dst_lo),
    
    6073
    -                        BSWAP II32 dst_hi,
    
    6070
    +        tmp <- getNewRegNat II32
    
    6071
    +        -- Swap the low and high halves of the register.
    
    6072
    +        --
    
    6073
    +        -- NB: if dst_hi == rhi, we must make sure to preserve the contents
    
    6074
    +        -- of rhi before writing to dst_hi (#25601).
    
    6075
    +        let shuffle = if dst_hi == rhi && dst_lo == rlo then
    
    6076
    +                        toOL [ MOV II32 (OpReg rhi) (OpReg tmp),
    
    6077
    +                               MOV II32 (OpReg rlo) (OpReg dst_hi),
    
    6078
    +                               MOV II32 (OpReg tmp) (OpReg dst_lo) ]
    
    6079
    +                      else if dst_hi == rhi then
    
    6080
    +                        toOL [ MOV II32 (OpReg rhi) (OpReg dst_lo),
    
    6081
    +                               MOV II32 (OpReg rlo) (OpReg dst_hi) ]
    
    6082
    +                      else
    
    6083
    +                        toOL [ MOV II32 (OpReg rlo) (OpReg dst_hi),
    
    6084
    +                               MOV II32 (OpReg rhi) (OpReg dst_lo) ]
    
    6085
    +        return $ vcode `appOL` shuffle `appOL`
    
    6086
    +                 toOL [ BSWAP II32 dst_hi,
    
    6074 6087
                             BSWAP II32 dst_lo ]
    
    6075 6088
           W16 -> do
    
    6076 6089
             let dst_r = getLocalRegReg dst
    

  • testsuite/tests/cmm/should_run/T25601.hs
    1
    +{-# LANGUAGE UnboxedTuples #-}
    
    2
    +{-# LANGUAGE MagicHash #-}
    
    3
    +{-# LANGUAGE ForeignFunctionInterface #-}
    
    4
    +{-# LANGUAGE GHCForeignImportPrim #-}
    
    5
    +{-# LANGUAGE UnliftedFFITypes #-}
    
    6
    +
    
    7
    +import Numeric
    
    8
    +import GHC.Prim
    
    9
    +import GHC.Word
    
    10
    +import GHC.IO
    
    11
    +import GHC.Ptr
    
    12
    +import Data.List
    
    13
    +import qualified Data.ByteString as BS
    
    14
    +
    
    15
    +foreign import prim "test" c_test :: Addr# -> State# RealWorld -> (# State# RealWorld, Word64# #)
    
    16
    +
    
    17
    +main :: IO ()
    
    18
    +main = do
    
    19
    +    let bs = BS.pack $ take 100000 [ fromIntegral i | i <- [(1 :: Int) ..] ]
    
    20
    +    n <- BS.useAsCString bs $ \(Ptr addr) -> IO $ \s ->
    
    21
    +      case c_test addr s of (# s', n #) -> (# s', W64# n #)
    
    22
    +    print $ showHex n ""

  • testsuite/tests/cmm/should_run/T25601.stdout
    1
    +"f3f1ffffffffffff"

  • testsuite/tests/cmm/should_run/T25601a.cmm
    1
    +#include "Cmm.h"
    
    2
    +
    
    3
    +test ( W_ buffer ) {
    
    4
    +  bits64 ret;
    
    5
    +  (ret) = prim %bswap64(%neg(%zx64(bits16[buffer + (12 :: W_)])));
    
    6
    +  return (ret);
    
    7
    +}

  • testsuite/tests/cmm/should_run/all.T
    ... ... @@ -47,3 +47,8 @@ test('AtomicFetch',
    47 47
          ],
    
    48 48
          multi_compile_and_run,
    
    49 49
          ['AtomicFetch', [('AtomicFetch_cmm.cmm', '')], ''])
    
    50
    +
    
    51
    +test('T25601',
    
    52
    +     [req_cmm],
    
    53
    +     multi_compile_and_run,
    
    54
    +     ['T25601', [('T25601a.cmm', '')], ''])