Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
bfa6b70f
by ARATA Mizuki at 2025-06-06T05:49:24-04:00
5 changed files:
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- + testsuite/tests/cmm/should_run/T25601.hs
- + testsuite/tests/cmm/should_run/T25601.stdout
- + testsuite/tests/cmm/should_run/T25601a.cmm
- testsuite/tests/cmm/should_run/all.T
Changes:
... | ... | @@ -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
|
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 "" |
1 | +"f3f1ffffffffffff" |
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 | +} |
... | ... | @@ -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', '')], '']) |