2a59d27e69
LLVM 12–17 have been dropped for Nixpkgs 25.11. As discussed recently on Matrix, this backports upstream changes to allow the use of LLVM 20 for all GHC versions from 9.4.8 onward. I looked over GHC commits mentioning LLVM since the release of 9.4.8, and read the discussions and issues around the relevant bumps, and attempted to be quite thorough, but I obviously cannot guarantee that this is wholly comprehensive. It seems like upstream generally bumps the upper bound on the basis of “it builds successfully for me”, with specific adaptations for new versions being fairly uncommon and only coming for obvious build blockers or reactively in response to bug reports. I have backported both kinds of changes here. For some commits, trivial conflict resolutions and adaptations were required. It would be possible to pass the affected files to `fetchpatch` as `excludes` and keep smaller fix‐up patches in tree in some cases, but I opted to keep it simple and vendor complete backport patches instead. I did not attempt to backport every single change to the LLVM backend, only those that seemed directly relevant to support for newer versions; if you’d get the same issue with the older LLVM, that’s just a GHC bug. These changes should actually make it easier to cross‐compile for new architectures, as more recent LLVMs will have better support for newer platforms, and it will be easier to backport GHC changes to enable new platforms with less drift in the backend. These patches do result in two breaking changes. Firstly, the minimum LLVM version is bumped to 13 across the board. This is irrelevant for Nixpkgs as we pin a specific LLVM version anyway, and versions below LLVM 18 will be removed imminently. Secondly, support for the hidden `-fno-llvm-tbaa` flag is dropped. This can be replaced with custom `-optlo` flags to control the passes more directly, but the main use of this undocumented flag appears to have been to [work around] the lack of support for newer LLVM versions, anyway. [work around]: <https://gitlab.haskell.org/ghc/ghc/-/issues/22220> I successfully built the following on `aarch64-linux`: * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc948` * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc967` * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc984` * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc9102` * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc9121` * `pkgsCross.armv7l-hf-multiplatform.buildPackages.haskell.compiler.ghc9122` * `pkgsCross.riscv64.haskell.compiler.ghc948` The GHC 9.4.8 with an ARMv7 host platform segfaults when I try to run GHC, though e.g. `ghc-pkg --help` runs successfully. The GHC 9.10.3 build targeting ARMv7 crashed inside `llc(1)`, so I tried RISC‐V, which has some platform mismatch issue relating to `libffi`, so I tried z/Architecture, which failed with an invalid floating point constant in the LLVM IR, so I tried 64‐bit MIPS, which failed with a different `libffi` issue, so I tried 32‐bit MIPS, which failed to compile `compiler-rt`, so I gave up. I confirmed that both of the ARMv7 issues reproduce with944e8fd4f4, the revision before they were bumped from their old versions of LLVM, so these are not regressions. I built a test program with the ARMv7 cross‐compilers and confirmed that they run on the AArch64 builder. I also confirmed that the cross‐compiled RISC‐V GHC successfully runs under `qemu-riscv64(1)`. It will only try to build programs via the C backend, though, as that is the only option for unregisterised™ targets, so it’s not clear to me how useful LLVM support in 9.4.8 really is for bootstrapping new platforms; I guess even RISC‐V would require more backporting work to produce a cross‐compiled GHC that will use LLVM to compile its own input. I didn’t bother setting up all the binfmt machinery to get it through compiling and running a test program, but it at least makes the attempt. (cherry picked from commitb6be8a03a7)
138 lines
5.7 KiB
Diff
138 lines
5.7 KiB
Diff
From 646d62e74c16be785ef08735ae5b24f4af6bcf78 Mon Sep 17 00:00:00 2001
|
|
From: Ben Gamari <ben@smart-cactus.org>
|
|
Date: Tue, 22 Aug 2023 13:26:58 -0400
|
|
Subject: [PATCH] llvmGen: Don't pass stack alignment via command line
|
|
|
|
As of https://reviews.llvm.org/D103048 LLVM no longer supports the
|
|
`-stack-alignment=...` flag. Instead this information is passed via a
|
|
module flag metadata node.
|
|
|
|
This requires dropping support for LLVM 11 and 12.
|
|
|
|
Fixes #23870
|
|
|
|
(cherry picked from commit e9af2cf3f16ab60b5c79ed91df95359b11784df6)
|
|
---
|
|
compiler/GHC/CmmToLlvm.hs | 29 ++++++++++++++++++++++++-
|
|
compiler/GHC/CmmToLlvm/Config.hs | 1 +
|
|
compiler/GHC/Driver/Config/CmmToLlvm.hs | 1 +
|
|
compiler/GHC/Driver/Pipeline/Execute.hs | 7 ------
|
|
configure.ac | 2 +-
|
|
5 files changed, 31 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/compiler/GHC/CmmToLlvm.hs b/compiler/GHC/CmmToLlvm.hs
|
|
index 7d48693765..b9036daef1 100644
|
|
--- a/compiler/GHC/CmmToLlvm.hs
|
|
+++ b/compiler/GHC/CmmToLlvm.hs
|
|
@@ -190,7 +190,7 @@ cmmLlvmGen _ = return ()
|
|
|
|
cmmMetaLlvmPrelude :: LlvmM ()
|
|
cmmMetaLlvmPrelude = do
|
|
- metas <- flip mapM stgTBAA $ \(uniq, name, parent) -> do
|
|
+ tbaa_metas <- flip mapM stgTBAA $ \(uniq, name, parent) -> do
|
|
-- Generate / lookup meta data IDs
|
|
tbaaId <- getMetaUniqueId
|
|
setUniqMeta uniq tbaaId
|
|
@@ -203,9 +203,36 @@ cmmMetaLlvmPrelude = do
|
|
-- just a name on its own. Previously `null` was accepted as the
|
|
-- name.
|
|
Nothing -> [ MetaStr name ]
|
|
+
|
|
+ platform <- getPlatform
|
|
+ cfg <- getConfig
|
|
+ let stack_alignment_metas =
|
|
+ case platformArch platform of
|
|
+ ArchX86_64 | llvmCgAvxEnabled cfg -> [mkStackAlignmentMeta 32]
|
|
+ _ -> []
|
|
+ module_flags_metas <- mkModuleFlagsMeta stack_alignment_metas
|
|
+ let metas = tbaa_metas ++ module_flags_metas
|
|
cfg <- getConfig
|
|
renderLlvm $ ppLlvmMetas cfg metas
|
|
|
|
+mkNamedMeta :: LMString -> [MetaExpr] -> LlvmM [MetaDecl]
|
|
+mkNamedMeta name exprs = do
|
|
+ (ids, decls) <- unzip <$> mapM f exprs
|
|
+ return $ decls ++ [MetaNamed name ids]
|
|
+ where
|
|
+ f expr = do
|
|
+ i <- getMetaUniqueId
|
|
+ return (i, MetaUnnamed i expr)
|
|
+
|
|
+mkModuleFlagsMeta :: [ModuleFlag] -> LlvmM [MetaDecl]
|
|
+mkModuleFlagsMeta =
|
|
+ mkNamedMeta "llvm.module.flags" . map moduleFlagToMetaExpr
|
|
+
|
|
+mkStackAlignmentMeta :: Integer -> ModuleFlag
|
|
+mkStackAlignmentMeta alignment =
|
|
+ ModuleFlag MFBError "override-stack-alignment" (MetaLit $ LMIntLit alignment i32)
|
|
+
|
|
+
|
|
-- -----------------------------------------------------------------------------
|
|
-- | Marks variables as used where necessary
|
|
--
|
|
diff --git a/compiler/GHC/CmmToLlvm/Config.hs b/compiler/GHC/CmmToLlvm/Config.hs
|
|
index 649a33c2f6..ecab7fdcc1 100644
|
|
--- a/compiler/GHC/CmmToLlvm/Config.hs
|
|
+++ b/compiler/GHC/CmmToLlvm/Config.hs
|
|
@@ -36,6 +36,7 @@ data LlvmCgConfig = LlvmCgConfig
|
|
, llvmCgContext :: !SDocContext -- ^ Context for LLVM code generation
|
|
, llvmCgFillUndefWithGarbage :: !Bool -- ^ Fill undefined literals with garbage values
|
|
, llvmCgSplitSection :: !Bool -- ^ Split sections
|
|
+ , llvmCgAvxEnabled :: !Bool
|
|
, llvmCgBmiVersion :: Maybe BmiVersion -- ^ (x86) BMI instructions
|
|
, llvmCgLlvmVersion :: Maybe LlvmVersion -- ^ version of Llvm we're using
|
|
, llvmCgDoWarn :: !Bool -- ^ True ==> warn unsupported Llvm version
|
|
diff --git a/compiler/GHC/Driver/Config/CmmToLlvm.hs b/compiler/GHC/Driver/Config/CmmToLlvm.hs
|
|
index 8097bbec7e..752ba987ca 100644
|
|
--- a/compiler/GHC/Driver/Config/CmmToLlvm.hs
|
|
+++ b/compiler/GHC/Driver/Config/CmmToLlvm.hs
|
|
@@ -23,6 +23,7 @@ initLlvmCgConfig logger config_cache dflags = do
|
|
, llvmCgContext = initSDocContext dflags PprCode
|
|
, llvmCgFillUndefWithGarbage = gopt Opt_LlvmFillUndefWithGarbage dflags
|
|
, llvmCgSplitSection = gopt Opt_SplitSections dflags
|
|
+ , llvmCgAvxEnabled = isAvxEnabled dflags
|
|
, llvmCgBmiVersion = case platformArch (targetPlatform dflags) of
|
|
ArchX86_64 -> bmiVersion dflags
|
|
ArchX86 -> bmiVersion dflags
|
|
diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs
|
|
index fac2a595f2..4fa72be475 100644
|
|
--- a/compiler/GHC/Driver/Pipeline/Execute.hs
|
|
+++ b/compiler/GHC/Driver/Pipeline/Execute.hs
|
|
@@ -992,8 +992,6 @@ llvmOptions llvm_config dflags =
|
|
[("-enable-tbaa -tbaa", "-enable-tbaa") | gopt Opt_LlvmTBAA dflags ]
|
|
++ [("-relocation-model=" ++ rmodel
|
|
,"-relocation-model=" ++ rmodel) | not (null rmodel)]
|
|
- ++ [("-stack-alignment=" ++ (show align)
|
|
- ,"-stack-alignment=" ++ (show align)) | align > 0 ]
|
|
|
|
-- Additional llc flags
|
|
++ [("", "-mcpu=" ++ mcpu) | not (null mcpu)
|
|
@@ -1012,11 +1010,6 @@ llvmOptions llvm_config dflags =
|
|
|
|
platform = targetPlatform dflags
|
|
|
|
- align :: Int
|
|
- align = case platformArch platform of
|
|
- ArchX86_64 | isAvxEnabled dflags -> 32
|
|
- _ -> 0
|
|
-
|
|
attrs :: String
|
|
attrs = intercalate "," $ mattr
|
|
++ ["+sse42" | isSse4_2Enabled dflags ]
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 16f2e8b339..0440d5051b 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -555,7 +555,7 @@ AC_SUBST(InstallNameToolCmd)
|
|
# tools we are looking for. In the past, GHC supported a number of
|
|
# versions of LLVM simultaneously, but that stopped working around
|
|
# 3.5/3.6 release of LLVM.
|
|
-LlvmMinVersion=11 # inclusive
|
|
+LlvmMinVersion=13 # inclusive
|
|
LlvmMaxVersion=16 # not inclusive
|
|
AC_SUBST([LlvmMinVersion])
|
|
AC_SUBST([LlvmMaxVersion])
|
|
--
|
|
2.50.1
|
|
|