Several LLVM versions have a bug in SelectionDAG that causes
miscompilations around conditional poisions. This was exposed due to
Rust 1.97.0 exercising the involved code path heavily and generating
segfaulting code, but the bug existed beforehand as well. The patch was
made to LLVM 23, but the tests have many conflicts, so this is a manual
backport. This backport was made by:
- applying the code change to `llvm/lib`
- hand-updating `test/CodeGen/Mips/cmov.ll` with the same diff as the PR
- updating the rest with `utils/update_llc_test_checks.py` from the LLVM
source tree, and verifying the diff against the one in the PR.
The last step made this a rather large and gnarly patch, but it's mostly
mechanical.
Rust issue: https://github.com/rust-lang/rust/issues/159035
LLVM issue: https://github.com/llvm/llvm-project/issues/208611
LLVM PR: https://github.com/llvm/llvm-project/pull/208683
Scope:
- Combination of
- Textual matches of "baseNameOf (toString"
- Redundant toString calls I've found with my latest
"lazy paths" nix branch as they force lazy fetches into
the store. More info and new PR soon.
- Only cases I believe are worthwhile or easily determined
I've determined the validity by
- testing llvmPackages instantiation
- figuring out which types can pass into any particular
toString call - "human fuzzy type checker"
Behavior considerations by type:
- `path`: converted back to a string *without* context
`baseNameOf` does not copy things to the store on its own,
equivalent to its behavior for string inputs
- `null`: converted to `""` -> may be valid input!
ok if "" would not have been acceptable anyway
- `string` itself: passed through identically -> trivial
- `attrset` with `outPath`: same coercion as built into
the `baseNameOf` function -> trivial
- other atomic types: generally not sensible inputs to
`baseNameOf` -> fuzzy but true
MLIRConfig.cmake unconditionally overwrites MLIR_TABLEGEN_EXE and does
not create an imported target, breaking standalone builds that provide
their own mlir-tblgen binary (e.g. Nix sandboxed builds).
The patch adds guards to respect caller-set MLIR_TABLEGEN_EXE,
MLIR_PDLL_TABLEGEN_EXE, and MLIR_SRC_SHARDER_TABLEGEN_EXE values, and
auto-creates an imported mlir-tblgen target for downstream consumers.
This replaces the previous dummy-target workaround in flang's
CMakeLists.txt.
Upstream issue: https://github.com/llvm/llvm-project/issues/150986
Co-authored-by: Alexander Bantyev <balsoft@balsoft.ru>
Wire flang into llvmPackages as a first-class Fortran compiler. flang
is built standalone on top of the LLVM/clang package set rather than
bundled into the llvm derivation, with passthru metadata
(`langFortran`, `isFlang`, `isClang`, `hardeningUnsupportedFlags`) so
cc-wrapper and downstream tooling can detect and adapt to it.
Driver compatibility patches backported from upstream are applied
selectively per LLVM version:
* `use-xflang-in-diagnostics` is applied to LLVM 20 and newer; it
teaches the driver to suggest `-Xflang` instead of `-Xclang` in
error messages for options only available to `flang -fc1`.
* `warn-on-fbuiltin-and-fno-builtin` and
`accept-and-ignore-some-gfortran-optimization-flags` are applied
to LLVM 20 and 21 only. LLVM 22 has equivalent behaviour merged
upstream (`warn_drv_invalid_argument_for_flang` and
`clang_ignored_gcc_optimization_f_Group` handling in
clang/lib/Driver/ToolChains/Flang.cpp), so the patches are skipped
there.
Patches live under pkgs/development/compilers/llvm/21/flang/ and are
shared across versions via patches.nix. They are applied to a private
libclang variant rather than the flang source tree because standalone
flang resolves driver/option definitions through the installed libclang
package.
Two focused passthru tests are added:
* `compile-smoke` exercises basic compilation and `@response-file`
handling.
* `driver-flags` covers wrapper flag isolation
(`NIX_CFLAGS_COMPILE` must not leak into flang;
`NIX_FFLAGS_COMPILE` must reach it), the backported driver
diagnostics, and regression coverage for previously hard-erroring
flags.
Build on the earlier standalone flang work by @picostove.
Co-authored-by: stove <stove@rivosinc.com>
Co-authored-by: acture <acture@gmail.com>
Co-authored-by: Alyssa Ross <hi@alyssa.is>
Add a standalone derivation for LLVM's flang-rt runtime libraries
(libFortranRuntime, libFortranDecimal). flang-rt is a runtimes-style
package: building it requires running a working flang binary at *build*
time, but the produced libraries are linked into derivations targeting
the *host*.
The runtime is therefore wired up using `buildFlang`, sourced from
`buildLlvmPackages.flang-unwrapped` so that the build-platform flang
(spliced via the LLVM package set) compiles the runtime, while the
resulting libraries are still produced for the host platform. This
mirrors the existing `buildLlvmTools.tblgen` / `buildLlvmPackages.tblgen`
pattern used elsewhere in the LLVM package set.
`unwrapped` rather than the wrapped flang is used because flang-rt's
CMake glue invokes the compiler directly and does not need (or want)
Nix's cc-wrapper resource-dir and rpath plumbing during the runtime
build.
flang-rt only consumes LLVM's CMake helpers and the build-time flang;
it does not link against MLIR or libclang, so neither MLIR_DIR nor
CLANG_DIR is passed and the unused empty `dev` output is omitted.
Co-authored-by: stove <stove@rivosinc.com>
Co-authored-by: acture <acture@gmail.com>
Build on the initial LLVM Flang wrapper work by exposing the needed clang passthru and teaching cc-wrapper about flang-specific flag handling.
Co-authored-by: stove <stove@rivosinc.com>
Co-authored-by: acture <acture@gmail.com>
Co-authored-by: Emily <hello@emily.moe>
Co-authored-by: Philip Taron <philip.taron@gmail.com>
We were removing a test that failed on armv6l. In LLVM 20, this test was
moved to a different directory, causing the build to fail. It is not
clear if the test still needs to be removed after this reorganization,
and I don't have hardware that can do a native armv6l build of LLVM.
clangd can take arguments also via environment variable CLANGD_FLAGS.
This has to be respected in the wrapper, which checks whether a
--query-driver was provided.
LLVM stdenvs lack a set of `__atomic_*` routines that compilers
sometimes rely on, making it impossible to build certain C programs in
them. The reason we lack these routines is that we're using neither
compiler-rt's implementation of them (which was disabled by default a
long time ago) nor gcc's implementation (libatomic). See #391740 for a
more detailed explanation and an example of program that cannot be built.
Since no particular preference was expressed as to which approach
should be used to solve this, I'm going with LLVM's implementation
and recommended setup, which seems to be used also in AIX, Fuchsia
and Apple platforms. This consists of enabling a CMake flag,
`COMPILER_RT_BUILD_STANDALONE_LIBATOMIC`, which causes the routines to
be built and shipped in a separate DSO (placing them in a DSO instead
of `builtins.a` is needed for correctness, as it ensures the lock
section is unique in memory).
As with the other builtins, I'm symlinking this DSO to `libatomic.so` so
that downstream packages don't need specific/complicated logic for LLVM.
Other details:
- For static platforms, since no dynamic linking is expected at all, it
should be correct to ship the symbols in `builtins.a`.
So, that's what I'm doing in those cases.
- Since v19, compiler-rt allows using pthread locks rather than ad-hoc
ones for the atomic routines. Since this plays better with
instrumentation, I'm enabling this whenever libc is available.
- It would be nice to put the DSO in a separate output / derivation, so
that the rest of compiler-rt isn't pulled into the runtime closure,
but it isn't high prio since compiler-rt doesn't pull in dependencies
other than libc, libc++ and unwinder.
Fixes: https://github.com/NixOS/nixpkgs/issues/311930