3322 Commits

Author SHA1 Message Date
Matthias Krüger
accf61dd42
Rollup merge of #143293 - folkertdev:naked-function-kcfi, r=compiler-errors
fix `-Zsanitizer=kcfi` on `#[naked]` functions

fixes https://github.com/rust-lang/rust/issues/143266

With `-Zsanitizer=kcfi`, indirect calls happen via generated intermediate shim that forwards the call. The generated shim preserves the attributes of the original, including `#[unsafe(naked)]`. The shim is not a naked function though, and violates its invariants (like having a body that consists of a single `naked_asm!` call).

My fix here is to match on the `InstanceKind`, and only use `codegen_naked_asm` when the instance is not a `ReifyShim`. That does beg the question whether there are other `InstanceKind`s that could come up. As far as I can tell the answer is no: calling via `dyn` seems to work find, and `#[track_caller]` is disallowed in combination with `#[naked]`.

r? codegen
````@rustbot```` label +A-naked
cc ````@maurer```` ````@rcvalle````
2025-07-18 04:27:51 +02:00
usamoi
5bb6b9db30 remove no_gc_sections 2025-07-17 14:54:52 +08:00
León Orell Valerian Liehr
be5f8f299d
Rollup merge of #143388 - bjorn3:lto_refactors, r=compiler-errors
Various refactors to the LTO handling code

In particular reducing the sharing of code paths between fat and thin-LTO and making the fat LTO implementation more self-contained. This also moves some autodiff handling out of cg_ssa into cg_llvm given that Enzyme only works with LLVM anyway and an implementation for another backend may do things entirely differently. This will also make it a bit easier to split LTO handling out of the coordinator thread main loop into a separate loop, which should reduce the complexity of the coordinator thread.
2025-07-17 03:58:28 +02:00
Folkert de Vries
9c8ab89187
use codegen_instance_attrs where an instance is (easily) available 2025-07-16 23:24:32 +02:00
Folkert de Vries
ec0ff720d1
add codegen_instance_attrs query
and use it for naked functions
2025-07-16 21:38:58 +02:00
Folkert de Vries
f100767dce
fix -Zsanitizer=kcfi on #[naked] functions
And more broadly only codegen `InstanceKind::Item` using the naked
function codegen code. Other instance kinds should follow the normal
path.
2025-07-16 21:38:48 +02:00
Samuel Tardieu
b564ecf04b
Rollup merge of #143920 - oli-obk:cg-llvm-safety, r=jieyouxu
Make more of codegen_llvm safe

Best reviewed commit-by-commit.
2025-07-16 17:06:40 +02:00
Scott McMurray
4fa23d96bc Improve comments inside codegen_get_discr 2025-07-15 22:30:46 -07:00
Oli Scherer
7f95f04267 Eliminate all direct uses of LLVMMDStringInContext2 2025-07-14 08:27:08 +00:00
Anne Stijns
75561c446a Port #[link_ordinal] to the new attribute parsing infrastructure. 2025-07-13 11:51:01 +02:00
usamoi
f58accb8f3 pass --gc-sections if -Zexport-executable-symbols is enabled and improve tests 2025-07-13 16:27:47 +08:00
Scott McMurray
d5bcfb334b Simplify codegen for niche-encoded variant tests 2025-07-12 04:53:24 -07:00
bors
915e535244 Auto merge of #143810 - matthiaskrgr:rollup-iw7a23z, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - rust-lang/rust#143403 (Port several trait/coherence-related attributes the new attribute system)
 - rust-lang/rust#143633 (fix: correct assertion to check for 'noinline' attribute presence before removal)
 - rust-lang/rust#143647 (Clarify and expand documentation for std::sys_common dependency structure)
 - rust-lang/rust#143716 (compiler: doc/comment some codegen-for-functions interfaces)
 - rust-lang/rust#143747 (Add target maintainer information for aarch64-unknown-linux-musl)
 - rust-lang/rust#143759 (Fix typos in function names in the `target_feature` test)
 - rust-lang/rust#143767 (Bump `src/tools/x` to Edition 2024 and some cleanups)
 - rust-lang/rust#143769 (Remove support for SwitchInt edge effects in backward dataflow)
 - rust-lang/rust#143770 (build-helper: clippy fixes)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-07-12 10:46:43 +00:00
bors
2f9c9cede6 Auto merge of #143766 - matthiaskrgr:rollup-0x7t69s, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#142391 (rust: library: Add `setsid` method to `CommandExt` trait)
 - rust-lang/rust#143302 (`tests/ui`: A New Order [27/N])
 - rust-lang/rust#143303 (`tests/ui`: A New Order [28/28] FINAL PART)
 - rust-lang/rust#143568 (std: sys: net: uefi: tcp4: Add timeout support)
 - rust-lang/rust#143611 (Mention more APIs in `ParseIntError` docs)
 - rust-lang/rust#143661 (chore: Improve how the other suggestions message gets rendered)
 - rust-lang/rust#143708 (fix: Include frontmatter in -Zunpretty output )
 - rust-lang/rust#143718 (Make UB transmutes really UB in LLVM)

r? `@ghost`
`@rustbot` modify labels: rollup

try-job: i686-gnu-nopt-1
try-job: test-various
2025-07-12 07:44:04 +00:00
Matthias Krüger
b18064f2f2
Rollup merge of #143716 - workingjubilee:document-some-codegen-backend-stuff, r=bjorn3,fee1-dead
compiler: doc/comment some codegen-for-functions interfaces

An out-of-date comment gets updated and some underdocumented functions get documented.
2025-07-11 19:45:24 +02:00
Jubilee Young
39f7707fea compiler: comment on some call-related codegen fn in cg_ssa
Partially documents the situation due to LLVM CFI.
2025-07-11 01:08:21 -07:00
Matthias Krüger
e43481e362
Rollup merge of #143718 - scottmcm:ub-transmute-is-ub, r=WaffleLapkin
Make UB transmutes really UB in LLVM

Ralf suggested in <https://github.com/rust-lang/rust/pull/143410#discussion_r2184928123> that UB transmutes shouldn't be trapping, which happened for the one path *that* PR was changing, but there's another path as well, so *this* PR changes that other path to match.

r? codegen
2025-07-11 07:35:22 +02:00
bors
855e0fe46e Auto merge of #142911 - mejrs:unsized, r=compiler-errors
Remove support for dynamic allocas

Followup to rust-lang/rust#141811
2025-07-11 05:27:32 +00:00
Matthias Krüger
b11e9e31dd
Rollup merge of #143446 - usamoi:export-executable-symbols, r=bjorn3,oli-obk
use `--dynamic-list` for exporting executable symbols

closes rust-lang/rust#101610
cc rust-lang/rust#84161

https://sourceware.org/binutils/docs-2.39/ld/VERSION.html:

> --dynamic-list=dynamic-list-file
Specify the name of a dynamic list file to the linker. This is typically used when creating shared libraries to specify a list of global symbols whose references shouldn’t be bound to the definition within the shared library, or creating dynamically linked executables to specify a list of symbols which should be added to the symbol table in the executable. This option is only meaningful on ELF platforms which support shared libraries.

`ld.lld --help`:

>   --dynamic-list=<file>: Similar to --export-dynamic-symbol-list. When creating a shared object, this additionally implies -Bsymbolic but does not set DF_SYMBOLIC

>  --export-dynamic-symbol-list=file: Read a list of dynamic symbol patterns. Apply --export-dynamic-symbol on each pattern

>  --export-dynamic-symbol=glob: (executable) Put matched symbols in the dynamic symbol table. (shared object) References to matched non-local STV_DEFAULT symbols shouldn't be bound to definitions within the shared object. Does not imply -Bsymbolic.

>  --export-dynamic: Put symbols in the dynamic symbol table

Use `--dynamic-list` because it's older than `--export-dynamic-symbol-list` (binutils 2.35)

try-job: dist-i586-gnu-i586-i686-musl
2025-07-10 20:28:46 +02:00
Scott McMurray
f5fc8727db Add BuilderMethods::unreachable_nonterminator
So places that need `unreachable` but in the middle of a basic block can call that instead of figuring out the best way to do it.
2025-07-10 09:17:28 -07:00
bors
cf3fb768db Auto merge of #143696 - oli-obk:constable-type-id2, r=RalfJung
Add opaque TypeId handles for CTFE

Reopen of https://github.com/rust-lang/rust/pull/142789#issuecomment-3053155043 after some bors insta-merge chaos

r? `@RalfJung`
2025-07-10 07:04:03 +00:00
Scott McMurray
58d7c2d5a7 Make UB transmutes really UB in LLVM
Ralf suggested in <https://github.com/rust-lang/rust/pull/143410#discussion_r2184928123> that UB transmutes shouldn't be trapping, which happened for the one path that PR was changing, but there's another path as well, so this PR changes that other path to match.
2025-07-09 22:30:15 -07:00
bors
e3fccdd4a1 Auto merge of #143502 - scottmcm:aggregate-simd, r=oli-obk
Let `rvalue_creates_operand` return true for *all* `Rvalue::Aggregate`s

~~Draft for now because it's built on Ralf's rust-lang/rust#143291~~

Inspired by https://github.com/rust-lang/rust/pull/138759#discussion_r2156375342 where I noticed that we were nearly at this point, plus the comments I was writing in rust-lang/rust#143410 that reminded me a type-dependent `true` is fine.

This PR splits the `OperandRef::builder` logic out to a separate type, with the updates needed to handle SIMD as well.  In doing so, that makes the existing `Aggregate` path in `codegen_rvalue_operand` capable of handing SIMD values just fine.

As a result, we no longer need to do layout calculations for aggregate result types when running the analysis to determine which things can be SSA in codegen.
2025-07-09 16:37:20 +00:00
Oli Scherer
486ffda9dc Add opaque TypeId handles for CTFE 2025-07-09 16:37:11 +00:00
usamoi
bf6d29d558 use --dynamic-list for exporting executable symbols 2025-07-09 22:40:11 +08:00
bors
34097a38af Auto merge of #140525 - lqd:stabilize-lld, r=petrochenkov
Use lld by default on `x86_64-unknown-linux-gnu` stable

This PR and stabilization report is joint work with `@Kobzol.`

#### Use LLD on `x86_64-unknown-linux-gnu` by default, and stabilize `-Clinker-features=-lld` and `-Clink-self-contained=-linker`

This PR proposes making LLD the default linker on the `x86_64-unknown-linux-gnu` target for the artifacts we distribute, and also stabilizing the `-Clinker-features=-lld` and `-Clink-self-contained=-linker` codegen options to make it possible to opt out.

LLD has been used as the default linker on nightly and CI on this target since May 2024 ([PR](https://github.com/rust-lang/rust/pull/124129), [blog post](https://blog.rust-lang.org/2024/05/17/enabling-rust-lld-on-linux.html)), and it seems like it is working fine, so we would like to propose stabilizing it.

The main motivation for using LLD instead of the default BFD linker is improving [compilation times](https://perf.rust-lang.org/compare.html?start=b3e117044c7f707293edc040edb93e7ec5f7040a&end=baed03c51a68376c1789cc373581eea0daf89967&stat=instructions%3Au&tab=compile). For example, in the linked benchmark, it makes incremental recompilation of `ripgrep` in `debug` more than twice faster. Another benefit is that Rust compilation becomes more consistent and self-contained, because we will use a known version of the LLD linker, rather than "whatever GNU ld version is on the user's system".

Due to the performance benefit being so huge, many people already opt into using LLD (or other fast linkers, such as mold) using various approaches ([1](https://github.com/search?type=code&q=%2Flinker-flavor%5B%3D+%5Dgnu-lld-cc%2F), [2](https://github.com/search?type=code&q=%2Flinker-features%5B%3D+%5D%5C%2Blld%2F), [3](https://github.com/search?type=code&q=language%3Atoml+%22-fuse-ld%3Dlld%22), [4](https://github.com/search?type=code&q=language%3Arust+%22-fuse-ld%3Dlld%22)). By making LLD the default linker on the `x86_64-unknown-linux-gnu` target, we will be able to speed up Rust compilation out of the box, without users having to opt in or know about it.

> You can find an extended version of this stabilization report which includes analysis of crater results and more data [here](https://hackmd.io/tFDifkUcSLGoHPBRIl0z8w?view).

## What is being stabilized
- `rust-lld` being used as the default linker on the `x86_64-unknown-linux-gnu` target.
    - Note that `rust-lld` is being enabled by default in the compiler artifacts distributed by our CI/rustup. It is still possible to use the system linker by default using `rust.lld = false` in `bootstrap.toml`, which can be useful e.g. for some Linux distros that might not want to use the LLD we distribute.
    - This is done by activating the LLD linker feature and using the self-contained linker on that target. Both of which are also usable on the CLI, if some opt outs are necessary, as described below.
- `-Clinker-features=-lld` on the `x86_64-unknown-linux-gnu` target. This codegen option tells rustc to disable using the LLD linker.
    - Note that other options for this codegen flag (`cc`) remain unstable.
    - Note that only the opt-out is being stabilized, and only for `x86_64-unknown-linux-gnu`: opting in, or using the flag on other targets would still need to pass `-Zunstable-options`.
    - This flag is being stabilized so that users can opt out of LLD on stable, which would it turn also opt out of using the self-contained linker (since it's an LLD).
- `-Clink-self-contained=-linker`. This codegen option tells rustc to use the self-contained linker. It's not particularly useful to turn it on by itself, but when enabled and combined with `-Clinker-features=+lld`, rustc will use the `rust-lld` linker wrapper shipped with the compiler toolchain, instead of some `lld` binary that the linker driver will find in the `PATH`.
    - Note that other options for this codegen flag (other than the previously stable `y/yes/n/no`).
    - Note that only the opt-out is being stabilized, and only for `x86_64-unknown-linux-gnu`: opting in, or using this flag on other targets would still need to pass `-Zunstable-options`.
    - This flag is being stabilized so that users can opt out of using self-contained linking on stable. Doing this would then fall back to using the system `lld`.

To opt out of using LLD, `RUSTFLAGS="-Clinker-features=-lld"` would be used. To opt out of using `rust-lld`, falling back to the LLD installed on the system, `RUSTFLAGS="-Clink-self-contained=-linker"` would be used.

## Tests

When enabling `rust-lld` on nightly, we also switched x64 linux to use it at stage >= 1, meaning that all tests have been running with lld since May 2024, on CI as well as contributors' machines. (Post opt-dist tests also had been using it when running their test subset earlier than that).

There are also a few tests dedicated to the CLI behavior, or ensuring the default linker is indeed the one we expect:

- [link-self-contained-consistency](1117bc1e6c/tests/ui/linking/link-self-contained-consistency.rs): Checks that `-Clink-self-contained` options are not inconsistent (i.e. that passing both `+linker` and `-linker` is an error).
- [link-self-contained-unstable](1117bc1e6c/tests/ui/linking/link-self-contained-unstable.rs): Checks that only the `-linker` and `y/yes/n/no` options for `-Clink-self-contained` are stable.
- [linker-features-unstable-cc](1117bc1e6c/tests/ui/linking/linker-features-unstable-cc.rs): Checks that only the non-lld options of `-Clinker-features` are unstable.
- [linker-features-lld-disallowed](1117bc1e6c/tests/ui/linking/linker-features-lld-disallowed.rs): Checks that `-Clinker-features=-lld` is only stable on `x86_64-unknown-linux-gnu`.
- [link-self-contained-linker-disallowed](1117bc1e6c/tests/ui/linking/link-self-contained-linker-disallowed.rs): Checks that `-Clink-self-contained=-linker` is only stable on `x86_64-unknown-linux-gnu`.
- [no-gc-encapsulation-symbols](1117bc1e6c/tests/ui/linking/no-gc-encapsulation-symbols.rs): Checks that that linker encapsulation symbols are not garbage collected by LLD, so that crates like [linkme](https://github.com/dtolnay/linkme) still work.
- [rust-lld](1117bc1e6c/tests/run-make/rust-lld): Checks that LLD is actually used when enabled with `-Clinker-features=+lld` and `-Clink-self-contained=+linker`.
- [rust-lld-x86_64-unknown-linux-gnu](1117bc1e6c/tests/run-make/rust-lld-x86_64-unknown-linux-gnu): Checks that LLD is used by default on `x86_64-unknown-linux-gnu` when the bootstrap `rust.lld` config option is `true`.
- [rust-lld-x86_64-unknown-linux-gnu-dist](1117bc1e6c/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist): Dist test that checks that our distributed `x86_64-unknown-linux-gnu` archives actually use LLD by default.

## Ecosystem impact
As already stated, LLD has been used as the default linker on x64 Linux on nightly for almost a year, and we haven't seen any blockers to stabilization in that time. There were a handful of issues reported, these are discussed later below.

Furthermore, two crater runs ([November 2023](https://crater-reports.s3.amazonaws.com/pr-117684-2/index.html), [February 2025](https://crater-reports.s3.amazonaws.com/pr-137044-3/index.html)), were performed to test the impact of using LLD as the default linker. A triage of the earlier crater run was previously done [here](https://hackmd.io/OAJxlxc6Te6YUot9ftYSKQ), but all the important findings from both crater runs are reported below.

Below is a list of compatibility differences between BFD and LLD that we have encountered. There is a more thorough list of differences in [this post](https://maskray.me/blog/2020-12-19-lld-and-gnu-linker-incompatibilities) from the current LLD maintainer. From that post, "99.9% pieces of software work with ld.lld without a change".

---

### `.ctors/.dtors` sections
[#128286](https://github.com/rust-lang/rust/issues/128286) reported an issue where LLD was unable to link certain CUDA library was using these sections that were using the `.ctors/.dtors` ELF sections. These were deprecated a long time ago (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770), replaced with a more modern `.init_array/.fini_array` sections. LLD doesn't (and won't) support these sections ([1](https://github.com/llvm/llvm-project/issues/68071), [2](https://github.com/llvm/llvm-project/issues/30572)), so if they appear in input object files, the linked artifact might produce incorrect behavior, because e.g. some global variables might not get initialized properly.

However, the usage of `.ctors/.dtors` should be very rare in practice. We have performed a [crater run](https://github.com/rust-lang/rust/pull/137044) to test this. It has identified only 8 crates where the `.ctors/.dtors` section is occurring in the final linked artifact. It was caused by a few crates using the `.ctors` link section manually, and by using a very (~6 year) old version of the [ctor](https://crates.io/crates/ctor) crate.

[Crater run analysis](https://hackmd.io/tFDifkUcSLGoHPBRIl0z8w?view#ctorsdtors-sections)

**Possible workaround**
It is possible to [detect](e5e2316712) if `.ctors/.dtors` section is present in the final linked artifact (LLD will keep it there, but it won't be populated), and warn users about it. This check is very cheap and doesn't even appear on [perf](https://github.com/rust-lang/rust/pull/112049#issuecomment-2661125340). We have benchmarked the check on a 240 MiB Chrome binary, where it took 0.8ms with page cache flushed, and 0.06ms with page cache primed (which should be the common case, as the linked artifact is written to disk just before the check is performed).

In theory, this could be also solved with a linker script that moves `.ctors` to `.init_array`.

We think that these sections should be so rare that it is not worth it to implement any workarounds for now.

---

### Different garbage collection behavior
[#130397](https://github.com/rust-lang/rust/issues/130397) reported an issue where LLD prunes a local symbol, so it is missing in the linked artifact. However, BFD keeps the same symbol, so it is a regression. This is caused by a difference in linker garbage collection.

Rust uses `--gc-sections` and puts each function into a separate linker section, which prunes unused code. There is some code (specifically the somewhat popular [linkme](https://github.com/dtolnay/linkme) crate) that (arguably ab-)uses so called linker encapsulation symbols to achieve distributed slices.

BFD (2.37+) uses a conservative linking mode that works as intended with this behavior, but it might slightly increase binary size of the linked artifact. LLD does not use this workaround by default, which causes the sections to be eliminated, but it can be made to use the conservative mode using [`-z nostart-stop-gc`](https://lld.llvm.org/ELF/start-stop-gc.html#z-start-stop-gc).

To avoid this issue, we told LLD to use the [conservative mode](https://github.com/rust-lang/rust/pull/137685), which maintains backwards compatibility with BFD. We found that it has [no effect](https://github.com/rust-lang/rust/pull/112049#issuecomment-2666028775) on compilation performance and binary size in our benchmark suite. With this change, `linkme` works. Since then, rust-lang/rust#140872 removed `linkme` distributed slice's dependence on conservative GC behavior, so this PR also removes that conservative mode: no transition period is necessary, as the PR immediately fixed the crate with no source changes.

[Crater run analysis](https://hackmd.io/tFDifkUcSLGoHPBRIl0z8w?view#Different-garbage-collection-behavior)

---

### Various uncommon issues

A small number of issues that only occurred in a handful of instances were found in crater, and it is unclear if LLD is at fault or if there is some other issue that was not detected with BFD.

You can examine these [here](https://hackmd.io/tFDifkUcSLGoHPBRIl0z8w?view#Various-uncommon-issues).

---

### Missing jobserver support
LLD doesn't support the jobserver protocol for limiting the number of threads used, it simply defaults to using all available cores, and is one of the reasons why it's faster than BFD. However, this should mostly be a non-issue, because most of the linking done during high parallelism sections of `cargo build` is linking of build scripts and proc macros, which are typically very fast to link (e.g. ~50ms), and a potential oversubscription of cores thus doesn't hurt that much.

When the final artifact is linked (which typically takes the most time), there should be no other sources of parallelism conflicts from compiling other code, so LLD should be able to use all available threads.

That being said, it is a difference of behavior, where previously a `-j` flag was generally not using more cpu than the specified limit. It can be impactful in some resource-constrained systems, but to be clear that is already the case today due to [cargo parallelism](https://github.com/rust-lang/cargo/issues/9157). This could be one reason to opt out of using `rust-lld` on some systems.

LLD has support for limiting the number of threads to use, so in theory rustc could try to get all the jobserver tokens available and use that as lld's thread limit. It'd still be suboptimal as new tokens would not be dynamically detected, and we could be using less threads than available.

We did a benchmark on a real-world crate that shows that using multiple LLD threads for intermediate artifacts doesn't seem to have a performance effect. You can find it [here](https://hackmd.io/tFDifkUcSLGoHPBRIl0z8w?view#Missing-jobserver-support).

---

#### Opting out of LLD in the ecosystem
We have also examined repositories where people opted out of LLD on nightly, using [this GitHub query](https://github.com/search?q=%22linker-features%3D-lld%22&type=code). The summary can be found below:

<details>
<summary>Summary of LLD opt outs</summary>

> This examination was performed on 2025-03-09.

Here we briefly examine the most common reasons why people use `-Zlinker-features=-lld`, based on comments and git history.

- Nix/NixOS ([1](59d703dff5/flake.nix (L33)), [2](3cc3449fc1/.cargo/config.toml (L4)), [3](32bdb17ced/.cargo/config.toml (L2)), [4](f5f657d014/Cargo.toml (L4)), [5](e4266f5c55/.cargo/config.toml (L10)), [6](22a4aef24e/README.md (L78)), [7](2222d53474/.cargo/config.toml (L2)), [8](b2ffa59d3e/.cargo/config.toml (L4)), [9](3ead4ef9c7/.cargo/config.toml (L2)), [10](ca6b8c8a5d/work/examples/lsp-client/src/extension.ts (L94)))
    - There was an [issue](https://github.com/NixOS/nixpkgs/issues/312661) with LLD, which seems to have been fixed with https://github.com/NixOS/nixpkgs/pull/314268.
 It's unclear whether that fixed all the Nix issues though.
- Issues with linkme ([1](ef388619ff/.cargo/config.toml (L4)), [2](be0fc5827f/README.md (L20)), [3](c5d8444d56/rust/.cargo/config.toml (L6)), [4](5b4cc1a519/.cargo/config.toml (L3)), [5](4e27c7de2a/.github/workflows/ci.yml (L82)), [6](8fe60c12bc/.github/workflows/code-coverage.yml (L48)), [7](c8b4683798/.github/workflows/ci.yml (L74)))
    - These should be resolved with the conservative garbage collection ([#137685](https://github.com/rust-lang/rust/pull/137685)).
- Bazel ([1](1823f69ed8/.bazelrc (L71))), WASM ([1](ca6b8c8a5d/work/examples/wasm-build.sh (L37)), [2](2bf99037ca/build.sh (L21))), uncategorized ([2](5118be6b9e/.cargo/config.toml (L3)), [3](45020c7e1d/.cargo/config.toml (L209)), [4](042eb835f7/README.md (L89)), [5](fd0b300676/exercises/.cargo/config.toml (L13)), [6](be65f2ec92/.github/workflows/rust.yml (L20)))
    - Reason unclear.
</details>

## History
The idea to use a faster linker by default has been on the radar for quite some time ([#39915](https://github.com/rust-lang/rust/issues/39915), [#71515](https://github.com/rust-lang/rust/issues/71515)). There were [very early attempts](https://github.com/rust-lang/rust/pull/29974) to use the gold linker by default, but these had to be [reverted](https://github.com/rust-lang/rust/pull/30913) because of compatibility issues. Support for LLD was implemented back in [2017](https://github.com/rust-lang/rust/pull/40018), but it has not been made default yet, except for some more niche targets, such as [WASM](https://github.com/rust-lang/rust/pull/48125), [ARM Cortex](https://github.com/rust-lang/rust/pull/53648) or [RISC-V](https://github.com/rust-lang/rust/pull/53822).

It took quite some time to figure out how should the interface for selecting the linker (and the way it is invoked) look like, as it differs a lot between different platforms, linkers and compiler drivers. During that time, LLD has matured and achieved [almost perfect compatibility](https://maskray.me/blog/2020-12-19-lld-and-gnu-linker-incompatibilities) with the default Linux linker (BFD).

- [#56351](https://github.com/rust-lang/rust/pull/56351) stabilized `-Clinker-flavor`, which is used to determine how to invoke the linker. It is especially useful on targets where selecting the linker directly with `-Clinker` is not possible or is impractical.
    - December 2018, author `@davidtwco,` reviewer `@nagisa`
- [#76158](https://github.com/rust-lang/rust/pull/76158) stabilized `-Clink-self-contained=[y|n]`, which allows overriding the compiler's heuristic for deciding whether it should use self-contained or external tools (linker, sanitizers, libc, etc.). It only allowed using the self-contained mode either for everything (`y`) or nothing (`n`), but did not allow granular choice.
    - September 2020, author `@mati864,` reviewer `@petrochenkov`
- [#85961](https://github.com/rust-lang/rust/pull/85961) implemented the `-Zgcc-ld` flag, which was a hacky way of opting into LLD usage.
    - June 2021, author `@sledgehammervampire,` reviewer `@petrochenkov`
- [MCP 510](https://github.com/rust-lang/compiler-team/issues/510) proposed stabilizing the behavior of `-Zgcc-ld` using more granular flags (`-Clink-self-contained=linker -Clinker-flavor=gcc-lld`).
    - Initially implemented in [#96827](https://github.com/rust-lang/rust/pull/96827), but `@petrochenkov` [suggested](https://github.com/rust-lang/rust/pull/96827#issuecomment-1208441595) a slightly different approach.
    - The PR was split into [#96884](https://github.com/rust-lang/rust/pull/96884), where it was decided what will be the individual components of `-Clink-self-contained=linker`.
    - And [#96401](https://github.com/rust-lang/rust/pull/96401), which implemented the `-Clinker-flavor` part.
    - The MCP was finally implemented in [#112910](https://github.com/rust-lang/rust/pull/112910).
    - [#116514](https://github.com/rust-lang/rust/pull/116514) then removed `-Zgcc-ld`, as it was replaced by `-Clinker-flavor=gnu-lld-cc` + `-Clink-self-contained=linker`.
    - April 2022 - October 2023, author `@lqd,` reviewer `@petrochenkov`

- Various linker handling refactorings were performed in the meantime: [#97375](https://github.com/rust-lang/rust/pull/97375), [#98212](https://github.com/rust-lang/rust/pull/98212), [#100126](https://github.com/rust-lang/rust/pull/100126), [#100552](https://github.com/rust-lang/rust/pull/100552), [#102836](https://github.com/rust-lang/rust/pull/102836), [#110807](https://github.com/rust-lang/rust/pull/110807), [#101988](https://github.com/rust-lang/rust/pull/101988), [#116515](https://github.com/rust-lang/rust/pull/116515)

- The implementation of linker flavors with LLD was causing a sort of a combinatorial explosion of various options.
[#119906](https://github.com/rust-lang/rust/pull/119906) suggested a different approach for linker flavors (described [here](https://github.com/rust-lang/rust/pull/119906#issuecomment-1894088306)), where the individual flavors could be enabled separately using `+/-` (e.g. `+lld`).
    - After some back and forth, this idea was moved to `-Clinker-features` (see [comment 1](https://github.com/rust-lang/rust/pull/119906#issuecomment-1895693162) and [comment 2](https://github.com/rust-lang/rust/pull/119906#issuecomment-1980801438)), which was implemented in [#123656](https://github.com/rust-lang/rust/pull/123656).
    - April 2024, author `@lqd,` reviewer `@petrochenkov`
- [#124129](https://github.com/rust-lang/rust/pull/124129) enabled LLD by default on nightly.
    - April 2024, author `@lqd,` reviewer `@petrochenkov`
- [#137685](https://github.com/rust-lang/rust/pull/137685), [#137926](https://github.com/rust-lang/rust/pull/137926) enabled the conservative gargage collection mode (`-znostart-stop-gc`) to improve compatibility with BFD.
    - February 2025, author `@lqd,` reviewer `@petrochenkov` (implementation), author `@kobzol,` reviewer `@lqd` (test)
- [#96025](https://github.com/rust-lang/rust/pull/96025) (April 2022), [#117684](https://github.com/rust-lang/rust/pull/117684) (November 2023), [#137044](https://github.com/rust-lang/rust/pull/137044) (February 2025): crater runs.

## Unresolved questions/concerns
- Is changing the linker considered a breaking change? In (hopefully very rare) cases, it might break some existing code. It should mostly only affect the final linked artifact, so it should be easy to opt out.
- Similarly, is the single-threaded behavior of such tools encompassed in our stability guarantee: it can be observed via the `-j` job limit (though I believe we have/had some open issues on sometimes using more CPU resources than the job count limit implied). As mentioned above, LLD does not support the jobserver protocol.
- A concern [was raised](https://github.com/rust-lang/rust/issues/71515#issuecomment-2612370229) about increased memory usage of LLD. We should probably let users know about the possibly increased memory usage, and jobserver incompatibility: we did so when announcing this landing on nightly.
- LLD seems to produce [slightly larger](https://perf.rust-lang.org/compare.html?start=b3e117044c7f707293edc040edb93e7ec5f7040a&end=baed03c51a68376c1789cc373581eea0daf89967&stat=size%3Alinked_artifact&tab=compile) binary artifacts. This can be partially clawed back using Identical Code Folding (`-Clink-args=-Wl,--icf=all`).
- Should we detect the outdated `.ctors/.dtors` sections to provide a better error message, even if that should be rare in practice?

---

### Next steps

After the FCP completes:
- we should land this PR at the beginning of a beta cycle, to maximize time for testing
- keep an eye on the beta crater run results for possible linker issues (or do a dedicated beta crater run with only this change)
- release a blog post announcing the change, and asking for testing feedback of the appropriate beta
- depending on feedback, or if a period of testing of 6 weeks is not long enough, we could keep this change on beta for another cycle

---

Development, testing, try builds were done in https://github.com/rust-lang/rust/pull/138645.

r? `@petrochenkov`
`@rustbot` label +needs-fcp +T-compiler
2025-07-08 22:24:06 +00:00
mejrs
25eb3829e5 Error on moving unsized values rather than ICE'ing 2025-07-08 22:37:12 +02:00
Matthias Krüger
bc9b313cb5
Rollup merge of #143402 - GrigorenkoPV:attributes/link_attrs, r=jdonszelmann
Port several linking (linkage?) related attributes the new attribute system

This ports:
- `#[export_stable]`
- `#[ffi_const]`
- `#[ffi_pure]`
- `#[rustc_std_internal_symbol]`

Part of rust-lang/rust#131229

r? ``@oli-obk``
2025-07-08 19:29:37 +02:00
Rémy Rakic
5059315e28 remove -znostart-stop-gc workaround
Now that `#[used(linker)]` is the default on ELF, we don't need to use the
`-znostart-stop-gc` link-arg workaround to match bfd's behavior when
using lld.
2025-07-08 10:24:11 +00:00
Rémy Rakic
2e6d82c9c9 stabilize -Clinker-features=-lld on x64 linux
This stabilizes a subset of the `-Clinker-features` components on x64 linux:
the lld opt-out.

The opt-in is not stabilized, as interactions with other stable flags require
more internal work, but are not needed for stabilizing using rust-lld by default.

Similarly, since we only switch to rust-lld on x64 linux, the opt-out is
only stabilized there. Other targets still require `-Zunstable-options`
to use it.
2025-07-08 09:04:21 +00:00
Scott McMurray
8cf2c71243 Let rvalue_creates_operand return true for *all* Rvalue::Aggregates
Inspired by <https://github.com/rust-lang/rust/pull/138759#discussion_r2156375342> where I noticed that we were nearly at this point, plus the comments I was writing in 143410 that reminded me a type-dependent `true` is fine.

This PR splits the `OperandRef::builder` logic out to a separate type, with the updates needed to handle SIMD as well.  In doing so, that makes the existing `Aggregate` path in `codegen_rvalue_operand` capable of handing SIMD values just fine.

As a result, we no longer need to do layout calculations for aggregate result types when running the analysis to determine which things can be SSA in codegen.
2025-07-07 23:08:10 -07:00
mejrs
49421d1fa3 Remove support for dynamic allocas 2025-07-07 23:04:06 +02:00
bors
2f8eeb2bba Auto merge of #143182 - xdoardo:more-addrspace, r=workingjubilee
Allow custom default address spaces and parse `p-` specifications in the datalayout string

Some targets, such as CHERI, use as default an address space different from the "normal" default address space `0` (in the case of CHERI, [200 is used](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-877.pdf)). Currently, `rustc` does not allow to specify custom address spaces and does not take into consideration [`p-` specifications in the datalayout string](https://llvm.org/docs/LangRef.html#langref-datalayout).

This patch tries to mitigate these problems by allowing targets to define a custom default address space (while keeping the default value to address space `0`) and adding the code to parse the `p-` specifications in `rustc_abi`. The main changes are that `TargetDataLayout` now uses functions to refer to pointer-related informations, instead of having specific fields for the size and alignment of pointers in the default address space; furthermore, the two `pointer_size` and `pointer_align` fields in `TargetDataLayout` are replaced with an `FxHashMap` that holds info for all the possible address spaces, as parsed by the `p-` specifications.

The potential performance drawbacks of not having ad-hoc fields for the default address space will be tested in this PR's CI run.

r? workingjubilee
2025-07-07 17:28:14 +00:00
Pavel Grigorenko
4f0b0b0f01 Port #[rustc_std_internal_symbol] to the new attribute system 2025-07-07 14:59:52 +03:00
Pavel Grigorenko
5d7771e50d Port #[ffi_pure] to the new attribute system 2025-07-07 14:59:01 +03:00
Pavel Grigorenko
99a9fe1b22 Port #[ffi_const] to the new attribute system 2025-07-07 14:52:52 +03:00
许杰友 Jieyou Xu (Joe)
4ba4b5f24f
Rollup merge of #143482 - ia0:fix, r=fee1-dead
Fix short linker error output

This PR does 2 things:

- It removes the braces when there's a single element. This is required since brace expansion (at least in bash and zsh) only triggers if there's at least 2 elements.

- It removes the extra `.rlib` suffixes of the elements. See https://github.com/rust-lang/rust/pull/135707#discussion_r2185212393 for context.

Running `cargo +stage1 build` on the following program:

```rust
unsafe extern "C" {
    fn foo() -> libc::c_int;
}

fn main() {
    let x = unsafe { foo() } as u32;
    // println!("{}", data_encoding::BASE64.encode(&x.to_le_bytes()));
}
```

Gives the following diff before and after the PR:

```diff
-/tmp/foo/target/debug/deps/{liblibc-faf416f178830595.rlib}.rlib
+/tmp/foo/target/debug/deps/liblibc-faf416f178830595.rlib
```

Running on the same program with the additional dependency, we get the following diff:

```diff
-/tmp/foo/target/debug/deps/{liblibc-faf416f178830595.rlib,libdata_encoding-84bb5aadfa9e8839.rlib}.rlib
+/tmp/foo/target/debug/deps/{liblibc-faf416f178830595,libdata_encoding-84bb5aadfa9e8839}.rlib
```
2025-07-07 19:45:40 +08:00
Edoardo Marangoni
93f1201c06
compiler: Parse p- specs in datalayout string, allow definition of custom default data address space 2025-07-07 09:04:53 +02:00
Julien Cretin
cdbdd8a4ad
Reverse comparison order
Co-authored-by: beef <ent3rm4n@gmail.com>
2025-07-07 08:49:10 +02:00
Jules Bertholet
97a7b9b1b4
Remove repr(align) code 2025-07-06 16:56:39 -04:00
Jonathan Brouwer
3fa0ec91d8
Rewrite empty attribute lint
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
2025-07-06 09:51:35 +02:00
Ralf Jung
3cd13f72a2 codegen_ssa: replace a Result by an Either 2025-07-05 15:53:56 +02:00
ia0
db0b491258 Fix short linker error output
This PR does 2 things:

- It removes the braces when there's a single element. This is required since brace expansion (at
  least in bash and zsh) only triggers if there's at least 2 elements.

- It removes the extra `.rlib` suffixes of the elements. See
  https://github.com/rust-lang/rust/pull/135707#discussion_r2185212393 for context.

Running `cargo +stage1 build` on the following program:

```rust
unsafe extern "C" {
    fn foo() -> libc::c_int;
}

fn main() {
    let x = unsafe { foo() } as u32;
    // println!("{}", data_encoding::BASE64.encode(&x.to_le_bytes()));
}
```

Gives the following diff before and after the PR:

```diff
-/tmp/foo/target/debug/deps/{liblibc-faf416f178830595.rlib}.rlib
+/tmp/foo/target/debug/deps/liblibc-faf416f178830595.rlib
```

Running on the same program with the additional dependency, we get the following diff:

```diff
-/tmp/foo/target/debug/deps/{liblibc-faf416f178830595.rlib,libdata_encoding-84bb5aadfa9e8839.rlib}.rlib
+/tmp/foo/target/debug/deps/{liblibc-faf416f178830595,libdata_encoding-84bb5aadfa9e8839}.rlib
```

Do we want to add a UI test?
2025-07-05 11:07:03 +02:00
Jubilee
33eb552ceb
Rollup merge of #143410 - scottmcm:redo-transmute-again, r=RalfJung,workingjubilee
Block SIMD in transmute_immediate; delete `OperandValueKind`

Vectors have been causing me problems for years in this code, for example https://github.com/rust-lang/rust/pull/110021#discussion_r1160975086 and https://github.com/rust-lang/rust/pull/143194

See conversation in <https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/near/526262799>.

By blocking SIMD in `transmute_immediate` it can be simplified to just take the `Scalar`s involved -- the backend types can be gotten from those `Scalar`s, rather than needing to be passed.  And there's an assert added to ICE it if it does get hit.

Accordingly, this changes `rvalue_creates_operand` to not send SIMD transmutes through the operand path, but to always go through memory instead, like they did back before rust-lang/rust#108442.

And thanks to those changes, I could also remove the `OperandValueKind` type that I added back then which `@RalfJung` rightly considers pretty sketchy.

cc `@folkertdev` `@workingjubilee` from the zulip conversation too
2025-07-04 23:26:24 -07:00
Scott McMurray
4e615272bf Address PR feedback 2025-07-04 12:29:27 -07:00
Scott McMurray
e0c54c3a9b Rename transmute_immediatetransmute_scalar 2025-07-04 10:35:51 -07:00
Scott McMurray
caeacba78a Allow all MIR Aggregates to take the operand path (if layout permits) 2025-07-03 22:53:19 -07:00
Scott McMurray
5292554337 Block SIMD in transmute_immediate; delete OperandValueKind
See conversation in <https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/near/526262799>.
2025-07-03 22:23:15 -07:00
bjorn3
21026cae8d Merge run_fat_lto, optimize_fat and autodiff into run_and_optimize_fat_lto 2025-07-03 16:22:32 +00:00
bjorn3
8d63c7a1d6 Remove unused config param from WriteBackendMethods::autodiff 2025-07-03 16:13:25 +00:00