Andreas Klebinger pushed to branch wip/andreask/9.10.4-batch1 at Glasgow Haskell Compiler / GHC Commits: 91389fdf by Ben Gamari at 2026-10-30T11:35:27+01:00 Cmm/Parser: Add surface syntax for Mul2 MachOps These are otherwise very hard to test in isolation. (cherry picked from commit ef5470a226dd8fe84df500a6a68672548624559e) - - - - - 8981fe7a by sheaf at 2026-10-30T11:35:27+01:00 Fix AArch64 clobbering bug for MUL2 On AArch64, the code generator could clobber one of the input operands when computing the lower bits of a MUL2 operation. This rendered invalid the subsequent computation of the high bits. This commit fixes that by using a temporary register. The register allocator can remove the redundant move in the common case when the registers do not conflict. Fixes #27046 (cherry picked from commit c9015f0953e72829e89ac768b6ad9ece34c7e187) - - - - - ed19e629 by mangoiv at 2026-10-30T11:35:27+01:00 libraries/process: bump submodule to v1.6.30.0 - bump the submodule to the appropriate tag - suppress benign warning resulting from the change (cherry picked from commit d9ea2d76545452a7df567b162340079cb024a40c) - - - - - b20f08ad by Zubin Duggal at 2026-10-30T11:35:27+01:00 rts: fix validate build with gcc 16. `__attribute__((regparm(1)))` is ignored on x86_64 and now gcc warns that it is ignored: rts/sm/Evac.h:35:1: error: error: ‘regparm’ attribute ignored [-Werror=attributes] See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=ccead81bbc39668376eb5cf47066ac... Fixes #27366 (cherry picked from commit 9438bec7117433bbc70449d4288f6ee32dbbbec4) - - - - - 9 changed files: - + changelog.d/T27046 - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - libraries/process - rts/sm/Evac.h - testsuite/driver/testlib.py - + testsuite/tests/codeGen/should_run/T27046.hs - + testsuite/tests/codeGen/should_run/T27046_cmm.cmm - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== changelog.d/T27046 ===================================== @@ -0,0 +1,9 @@ +section: compiler +issues: #27046 +mrs: !16031 +synopsis: + Avoid AArch64 register clobbering bug in MUL2 +description: + Fixes an issue in which, on AArch64, code generation for the MUL2 operation + could clobber one of the input operands when computing the lower bits, which + rendered invalid the subsequent computation of the high bits. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1164,6 +1164,8 @@ callishMachOps platform = listToUFM $ , allWidths "fetch_nand" (\w -> MO_AtomicRMW w AMO_Nand) , allWidths "fetch_or" (\w -> MO_AtomicRMW w AMO_Or) , allWidths "fetch_xor" (\w -> MO_AtomicRMW w AMO_Xor) + , allWidths "mul2_" (\w -> MO_S_Mul2 w) + , allWidths "mul2u_" (\w -> MO_U_Mul2 w) ] where allWidths ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -1694,11 +1694,17 @@ genCCall target dest_regs arg_regs bid = do let lo = getRegisterReg platform (CmmLocal dst_lo) hi = getRegisterReg platform (CmmLocal dst_hi) nd = getRegisterReg platform (CmmLocal dst_needed) + -- Generate a fresh virtual register for the low word computation. + -- This avoids clobbering reg_a or reg_b in the first MUL instruction, + -- which could for example happen if 'lo' and 'reg_a' are the same + -- virtual register. + tmp_lo <- getNewRegNat II64 return ( code_x `appOL` code_y `snocOL` - MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + MUL (OpReg W64 tmp_lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + MOV (OpReg W64 lo) (OpReg W64 tmp_lo) `snocOL` -- Are all high bits equal to the sign bit of the low word? -- nd = (hi == ASR(lo,width-1)) ? 1 : 0 CMP (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL` ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit f7d51387ba7f7f6079f3a9d5ce011ad9359b7dbb +Subproject commit 11fd247ad33208da7a914acf15d4a09d64a6a4c4 ===================================== rts/sm/Evac.h ===================================== @@ -6,7 +6,7 @@ * * Documentation on the architecture of the Garbage Collector can be * found in the online commentary: - * + * * https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/storage/gc * * ---------------------------------------------------------------------------*/ @@ -25,7 +25,9 @@ // registers EAX, EDX, and ECX instead of on the stack. Functions that // take a variable number of arguments will continue to be passed all of // their arguments on the stack. -#if __GNUC__ >= 2 && (defined(x86_64_HOST_ARCH) || defined(i386_HOST_ARCH)) +// On x86-64 the attribute has no effect (the first argument is already +// passed in a register) and GCC 16 warns that it is ignored. +#if defined(i386_HOST_ARCH) #define REGPARM1 __attribute__((regparm(1))) #else #define REGPARM1 ===================================== testsuite/driver/testlib.py ===================================== @@ -2723,7 +2723,19 @@ def normalise_errmsg(s: str) -> str: # clang may warn about unused argument when used as assembler s = re.sub('.*warning: argument unused during compilation:.*\n', '', s) # Emscripten displays cache info and old emcc doesn't support EMCC_LOGGING=0 - s = re.sub('cache:INFO: .*\n', '', s) + s = drop_lines_containing(s, 'cache:INFO:') + # Old emcc warns when we export HEAP8 but new one requires it (see #26290) + s = s.replace('warning: invalid item in EXPORTED_RUNTIME_METHODS: HEAP8\nwarning: invalid item in EXPORTED_RUNTIME_METHODS: HEAPU8\nemcc: warning: warnings in JS library compilation [-Wjs-compiler]\n','') + + if opsys('darwin'): + # on newer versions of MacOS X, the shipped ranlib warns about object files with no symbols, + # however, these are completely benign stubs. + # See https://gitlab.haskell.org/ghc/ghc/-/issues/27116 + s = modify_lines(s, lambda l: re.sub(r'.*ranlib:.*has no symbols', '', l)) + # we also want to remove linker warnings having to do with undefined dynamic_lookup in combination with + # making a single weak symbol undefined as this is dependent on other linker flags + # See also https://github.com/haskell/process/pull/377 + s = drop_lines_containing(s, 'ld: warning: -U option is redundant when using -undefined dynamic_lookup') return s ===================================== testsuite/tests/codeGen/should_run/T27046.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE ForeignFunctionInterface, GHCForeignImportPrim, UnliftedFFITypes #-} + +module Main where + +import Control.Monad + ( unless ) +import Data.Bits + ( shiftL ) +import GHC.Exts + ( Int64# ) +import GHC.Int + ( Int64(..) ) + +foreign import prim "test_mul2_clobber" + test_mul2_clobber :: Int64# -> Int64# -> Int64# + +main :: IO () +main = do + let + I64# x = 1 `shiftL` 32 + hi = I64# $ test_mul2_clobber x x + + unless ( hi == 1 ) $ + error $ unlines + [ "Incorrect result for Mul2 operation." + , "Expected high word: 1" + , " Actual high word: " ++ show hi + ] ===================================== testsuite/tests/codeGen/should_run/T27046_cmm.cmm ===================================== @@ -0,0 +1,13 @@ +#include "Cmm.h" + +// Test for #27046 +test_mul2_clobber (bits64 x, bits64 y) +{ + bits64 hi, nd; + + // Deliberately alias the destination 'lo' with the source 'x' + // This forces the NCG to use the same virtual register for both. + (nd, hi, x) = prim %mul2_64(x, y); + + return (hi); +} ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -253,6 +253,13 @@ test('T24893', normal, compile_and_run, ['-O']) test('T26061', normal, compile_and_run, ['']) test('T26537', normal, compile_and_run, ['-O2 -fregs-graph']) test('T24016', normal, compile_and_run, ['-O1 -fPIC']) +test('T27046', + [ req_cmm + , when(arch('i386'), skip) # i386 does not support MO_S_Mul2 W64 + , when(arch('wasm32'), skip) + , js_skip + , when(unregisterised(), skip) # pprCallishMachOp_for_C: MO_S_Mul2 W64 not supported + ], compile_and_run, ['T27046_cmm.cmm']) # Check that GHC-generated finalizers run on Darwin. The Apple linker doesn't # support --wrap, so we can't intercept hs_spt_remove directly. Instead we View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3764e95ca5ba389cfb332756000eeb8... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3764e95ca5ba389cfb332756000eeb8... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Andreas Klebinger (@AndreasK)