Certain LLVM intrinsics, such as `llvm.wasm.throw`, can unwind. Marking
them as nounwind causes us to skip cleanup of locals and optimize out
`catch_unwind` under inlining or when `llvm.wasm.throw` is used directly
by user code.
The motivation for forcibly marking llvm.* as nounwind is no longer
present: most intrinsics are linked as `extern "C"` or other
non-unwinding ABIs, so we won't codegen `invoke` for them anyway.
Rename `tests/{assembly,codegen}` into `tests/{assembly,codegen}-llvm` and ignore these testsuites if configured backend doesn't match
Follow-up of https://github.com/rust-lang/rust/pull/144125.
This PR changes `compiletest` so that `asm` tests are only run if they match the current codegen backend. To better reflect it, I renamed the `tests/ui/asm` folder into `tests/ui/asm-llvm`. Like that, we can add new asm tests for other backends if we want without needing to add extra code to `compiletest`.
Next step will be to use the new code annotations added in rust-lang/rust#144125 to ignore ui tests failing in cg_gcc until it's fixed on our side.
cc `@antoyo` `@oli-obk`
r? `@Kobzol`
fix handling of base address for TypeId allocations
This fixes the problems discovered by ````@theemathas```` in https://github.com/rust-lang/rust/pull/142789:
- const-eval would sometimes consider TypeId pointers to be null
- the type ID is different in Miri than in regular executions
Both boil down to the same issue: the TypeId "allocation" has a guaranteed 0 base address, but const-eval assumes it was non-zero (like normal allocations) and Miri randomized it (like normal allocations).
r? ````@oli-obk````
Mitigate `#[align]` name resolution ambiguity regression with a rename
Mitigates beta regression rust-lang/rust#143834 after a beta backport.
### Background on the beta regression
The name resolution regression arises due to rust-lang/rust#142507 adding a new feature-gated built-in attribute named `#[align]`. However, unfortunately even [introducing new feature-gated unstable built-in attributes can break user code](https://www.github.com/rust-lang/rust/issues/134963) such as
```rs
macro_rules! align {
() => {
/* .. */
};
}
pub(crate) use align; // `use` here becomes ambiguous
```
### Mitigation approach
This PR renames `#[align]` to `#[rustc_align]` to mitigate the beta regression by:
1. Undoing the introduction of a new built-in attribute with a common name, i.e. `#[align]`.
2. Renaming `#[align]` to `#[rustc_align]`. The renamed attribute being `rustc_align` will not introduce new stable breakages, as attributes beginning with `rustc` are reserved and perma-unstable. This does mean existing nightly code using `fn_align` feature will additionally need to specify `#![feature(rustc_attrs)]`.
This PR is very much a short-term mitigation to alleviate time pressure from having to fully fix the current limitation of inevitable name resolution regressions that would arise from adding any built-in attributes. Long-term solutions are discussed in [#t-lang > namespacing macro attrs to reduce conflicts with new adds](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/namespacing.20macro.20attrs.20to.20reduce.20conflicts.20with.20new.20adds/with/529249622).
### Alternative mitigation options
[Various mitigation options were considered during the compiler triage meeting](https://github.com/rust-lang/rust/issues/143834#issuecomment-3084415277), and those consideration are partly reproduced here:
- Reverting the PR doesn't seem very minimal/trivial, and carries risks of its own.
- Rename to a less-common but aim-to-stabilization name is itself not safe nor convenient, because (1) that risks introducing new regressions (i.e. ambiguity against the new name), and (2) lang would have to FCP the new name hastily for the mitigation to land timely and have a chance to be backported. This also makes the path towards stabilization annoying.
- Rename the attribute to a rustc attribute, which will be perma-unstable and does not cause new ambiguities in stable code.
- This alleviates the time pressure to address *this* regression, or for lang to have to rush an FCP for some new name that can still break user code.
- This avoids backing out a whole implementation.
### Review advice
This PR is best reviewed commit-by-commit.
- Commit 1 adds a test `tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs` which demonstrates the current name resolution regression re. `align`. This test fails against current master.
- Commit 2 carries out the renames and test reblesses. Notably, commit 2 will cause `tests/ui/attributes/fn-align-nameres-ambiguity-143834.rs` to change from fail (nameres regression) to pass.
This PR, if the approach still seems acceptable, will need a beta-backport to address the beta regression.
rustc_public: de-StableMIR-ize
This PR updates relevant docs about StableMIR, basically just rewording StableMIR/SMIR to rustc_public/rustc_public's IR.
The README.md in the `rustc_public` crate is out-dated. I plan to rewrite it after we fork rustc_public into its own repository.
This PR doesn't change the fact that we still use `-Z unpretty=stable-mir` as a rustc parameter for printing the IR, since I feel it's a bit verbose and weird if we use `-Z unpretty=rustc-public-ir`. I was wondering if we can have a short and easy alias for rustc_public's IR.
gpu offload host code generation
r? ghost
This will generate most of the host side code to use llvm's offload feature.
The first PR will only handle automatic mem-transfers to and from the device.
So if a user calls a kernel, we will copy inputs back and forth, but we won't do the actual kernel launch.
Before merging, we will use LLVM's Info infrastructure to verify that the memcopies match what openmp offloa generates in C++. `LIBOMPTARGET_INFO=-1 ./my_rust_binary` should print that a memcpy to and later from the device is happening.
A follow-up PR will generate the actual device-side kernel which will then do computations on the GPU.
A third PR will implement manual host2device and device2host functionality, but the goal is to minimize cases where a user has to overwrite our default handling due to performance issues.
I'm trying to get a full MVP out first, so this just recognizes GPU functions based on magic names. The final frontend will obviously move this over to use proper macros, like I'm already doing it for the autodiff work.
This work will also be compatible with std::autodiff, so one can differentiate GPU kernels.
Tracking:
- https://github.com/rust-lang/rust/issues/131513
Debug impls for DropElaborators
It's a little weird that these just have a completely empty Debug impl. Now they're `ElaborateDropsCtxt { .. }` and `DropShimElaborator { .. }`.
Ban projecting into SIMD types [MCP838]
Closes https://github.com/rust-lang/compiler-team/issues/838
The actual compiler change here is tiny; there's just a bazillion tests to update.
~~Since I'm sure I've missed some, for now~~
~~r ghost~~
try-job: test-various
try-job: x86_64-gnu-nopt
Give a message with a span on MIR validation error
It was handy to get a source+line link for rust-lang/rust#143833, even if it's just to the function and not necessarily to the statement.
r? mir
Fix `-Ctarget-feature`s getting ignored after `crt-static`
The current behaviour introduced by commit a50a3b8e31 would discard any target features specified after `crt-static` (the only member of `RUSTC_SPECIFIC_FEATURES`). This is because it returned instead of continuing processing the next feature.
I wasn't entirely sure how the regression test should look like, but this one should do. If anyone has some suggestions, I'm happy to learn, it's my first test :)
I've confirmed that the test fails without the fix on `powerpc64le-unknown-linux-musl` and `x86_64-unknown-linux-gnu`.
cc ``@RalfJung``
Allow `Rvalue::Repeat` to return true in `rvalue_creates_operand` too
The conversation in https://github.com/rust-lang/rust/pull/143502#discussion_r2189410911 made be realize how easy this is to handle, since the only possibilty is ZSTs -- everything else ends up with the destination being `LocalKind::Memory` and thus doesn't call `codegen_rvalue_operand` at all.
This gets us perilously close to a world where `rvalue_creates_operand` only ever returns true. (See rust-lang/rust#143860 for more.)
Fixes for LLVM 21
This fixes compatibility issues with LLVM 21 without performing the actual upgrade. Split out from https://github.com/rust-lang/rust/pull/143684.
This fixes three issues:
* Updates the AMDGPU data layout for address space 8.
* Makes emit-arity-indicator.rs a no_core test, so it doesn't fail on non-x86 hosts.
* Explicitly sets the exception model for wasm, as this is no longer implied by `-wasm-enable-eh`.
The conversation in 143502 made be realize how easy this is to handle, since the only possibilty is ZSTs -- everything else ends up with the destination being `LocalKind::Memory` and thus doesn't call `codegen_rvalue_operand` at all.
This gets us perilously close to a world where `rvalue_creates_operand` only ever returns true. I'll try out such a world next :)
Prepare revert of 144013
This is a possible revert for rust-lang/rust#144013 causing issue rust-lang/rust#144168 (imo p-crit) to give us time to figure out a correct fix for rust-lang/rust#144013 without pressure. Feel free to close if it's an easy fix instead: r? `@petrochenkov`
Simplify discriminant codegen for niche-encoded variants which don't wrap across an integer boundary
Inspired by rust-lang/rust#139729, this attempts to be a much-simpler and more-localized change while still making a difference. (Specifically, this does not try to solve the problem with select-sinking, leaving that to be fixed by https://github.com/llvm/llvm-project/issues/134024 -- once it gets released -- instead of in rustc's codegen.)
What this *does* improve is checking for the variant in a 3+ variant enum when that variant is the type providing the niche. Something like `if let Foo::WithBool(_) = ...` previously compiled to `ugt(add(x, -2), 2)`, which is non-trivial to think about because it's depending on the unsigned wrapping to shift the 0/1 up above 2. With this PR it compiles to just `ult(x, 2)`, which is probably what you'd have written yourself if you were doing it by hand to look for "is this byte a bool?".
That's done by leaving most of the codegen alone, but adding a couple new special cases to the `is_niche` check. The default looks at the relative discriminant, but in the common cases where there's no wraparound involved, we can just check the original value, rather than the offsetted one.
The first commit just adds some tests, so the best way to see the effect of this change is to look at the second commit and how it updates the test expectations.
Rename `emit_unless` to `emit_unless_delay`
`emit_unless` is very unintuitive and confusing. The first impression is as if it will only emit if the parameter is true, without the altnative "delay as a bug".
`emit_unless_delay` expresses two things:
1. emit unless the `delay` parameter is true
2. either *emit immediately* or *delay as bug*
r? `@compiler-errors`
Be a bit more careful around exotic cycles in in the inliner
Copied from the comment here: https://github.com/rust-lang/rust/issues/143700#issuecomment-3053810353
---
```rust
#![feature(fn_traits)]
#[inline]
pub fn a() {
FnOnce::call_once(a, ());
FnOnce::call_once(b, ());
}
#[inline]
pub fn b() {
FnOnce::call_once(b, ());
FnOnce::call_once(a, ());
}
```
This should demonstrate the issue. For ease of discussion, I'm gonna call the two fn-def types `{a}` and `{b}`.
When collecting the cyclic local callees in `mir_callgraph_cyclic` for `a`, we first check the first call terminator in `a`. We end up calling process on `<{a} as FnOnce>::call_once`, which ends up visiting `a`'s instance again. This is cyclical. However, we don't end up marking `FnOnce::call_once` as a cyclical def id because it's a foreign item. That's fine.
When visiting the second call terminator in `a`, which is `<{b} as FnOnce>::call_once`, we end up recursing into `b`. We check the first terminator, which is `<{b} as FnOnce>::call_once`, but although that is its own mini cycle, it doesn't consider itself a cycle for the purpose of this query because it doesn't involve the *root*. However, when we visit the *second* terminator in `b`, which is `<{a} as FnOnce>::call_once`, we end up **erroneously** *not* considering that call to be cyclical since we've already inserted it into our set of seen instances, and as a consequence we don't recurse into it. This means that we never collect `b` as recursive.
Do this in the flipped case too, and we end up having two functions which mututally do not consider each other to be recursive participants. This leads to a query cycle.
---
I ended up also renaming some variables so I could more clearly understand their responsibilities in this code. Let me know if the renames are not welcome.
Fixes https://github.com/rust-lang/rust/issues/143700
r? `@cjgillot`