Use target-cpu=z13 on s390x codegen const vector test
The default s390x cpu(z10) does not have vector support. Setting target-cpu at least to z13 enables vectorisation for s390x architecture and makes the test pass.
Fix test simd/extract-insert-dyn on s390x
Fix the test for s390x by enabling s390x vector extension via `target_feature(enable = "vector")`(#127506). As this is is still gated by `#![feature(s390x_target_feature)]` we need that attribute also.
Fix the test for s390x by enabling s390x vector extension via
`target_feature(enable = "vector")`(#127506). As this is is still
gated by `#![feature(s390x_target_feature)]` we need that attribute
also.
The default s390x cpu(z10) does not have vector support. Setting
target-cpu at least to z13 enables vectorisation for s390x architecture
and makes the test pass.
Autodiff flags
Interestingly, it seems that some other projects have conflicts with exactly the same LLVM optimization passes as autodiff.
At least `LLVMRustOptimize` has exactly the flags that we need to disable problematic opt passes.
This PR enables us to compile code where users differentiate two identical functions in the same module. This has been especially common in test cases, but it's not impossible to encounter in the wild.
It also enables two new flags for testing/debugging. I consider writing an MCP to upgrade PrintPasses to be a standalone -Z flag, since it is *not* the same as `-Z print-llvm-passes`, which IMHO gives less useful output. A discussion can be found here: [#t-compiler/llvm > Print llvm passes. @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/187780-t-compiler.2Fllvm/topic/Print.20llvm.20passes.2E/near/511533038)
Finally, it improves `PrintModBefore` and `PrintModAfter`. They used to work reliable, but now we just schedule enzyme as part of an existing ModulePassManager (MPM). Since Enzyme is last in the MPM scheduling, PrintModBefore became very inaccurate. It used to print the input module, which we gave to the Enzyme and was great to create llvm-ir reproducer. However, lately the MPM would run the whole `default<O3>` pipeline, which heavily modifies the llvm module, before we pass it to Enzyme. That made it impossible to use the flag to create llvm-ir reproducers for Enzyme bugs. We now schedule a PrintModule pass just before Enzyme, solving this problem.
Based on the PrintPass output, it also _seems_ like changing `registerEnzymeAndPassPipeline(PB, true);` to `registerEnzymeAndPassPipeline(PB, false);` has no effect. In theory, the bool should tell Enzyme to schedule some helpful passes in the PassBuilder. However, since it doesn't do anything and I'm not 100% sure anymore on whether we really need it, I'll just disable it for now and postpone investigations.
r? ``@oli-obk``
closes#139471
Tracking:
- https://github.com/rust-lang/rust/issues/124509
mitigate MSVC alignment issue on x86-32
This implements mitigation for https://github.com/rust-lang/rust/issues/112480 by stopping to emit `align` attributes on loads and function arguments when building for a win32 MSVC target. MSVC is known to not properly align `u64` and similar types, and claiming to LLVM that everything is properly aligned increases the chance that this will cause problems.
Of course, the misalignment is still a bug, but we can't fix that bug, only MSVC can.
Also add an errata note to the platform support page warning users about this known problem.
try-job: `i686-msvc*`
make abi_unsupported_vector_types a hard error
Fixes https://github.com/rust-lang/rust/issues/116558 by completing the transition; see that issue for context. The lint was introduced with Rust 1.84 and this has been shown in cargo's future breakage reports since Rust 1.85, released 6 weeks ago, and so far we got 0 complaints by users. There's not even a backlink on the tracking issue. We did a [crater run](https://github.com/rust-lang/rust/pull/127731#issuecomment-2286736295) when the lint was originally added and found no breakage. So I don't think we need another crater run now, but I can do one if the team prefers that.
https://github.com/rust-lang/rust/issues/131800 is done, so for most current targets (in particular, all tier 1 and tier 2 targets) we have the information to implement this check (modulo the targets where we don't properly support SIMD vectors yet, see the sub-issues of https://github.com/rust-lang/rust/issues/116558). If a new target gets added in the future, it will default to reject all SIMD vector types until proper information is added, which is the default we want.
This will need approval by for `@rust-lang/lang.` Cc `@workingjubilee` `@veluca93`
try-job: test-various
try-job: armhf-gnu
try-job: dist-i586-gnu-i586-i686-musl
Stabilize `naked_functions`
tracking issue: https://github.com/rust-lang/rust/issues/90957
request for stabilization on tracking issue: https://github.com/rust-lang/rust/issues/90957#issuecomment-2539270352
reference PR: https://github.com/rust-lang/reference/pull/1689
# Request for Stabilization
Two years later, we're ready to try this again. Even though this issue is already marked as having passed FCP, given the amount of time that has passed and the changes in implementation strategy, we should follow the process again.
## Summary
The `naked_functions` feature has two main parts: the `#[naked]` function attribute, and the `naked_asm!` macro.
An example of a naked function:
```rust
const THREE: usize = 3;
#[naked]
pub extern "sysv64" fn add_n(number: usize) -> usize {
// SAFETY: the validity of the used registers
// is guaranteed according to the "sysv64" ABI
unsafe {
core::arch::naked_asm!(
"add rdi, {}",
"mov rax, rdi",
"ret",
const THREE,
)
}
}
```
When the `#[naked]` attribute is applied to a function, the compiler won't emit a [function prologue](https://en.wikipedia.org/wiki/Function_prologue_and_epilogue) or epilogue when generating code for this function. This attribute is analogous to [`__attribute__((naked))`](https://developer.arm.com/documentation/100067/0608/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----naked---function-attribute) in C. The use of this feature allows the programmer to have precise control over the assembly that is generated for a given function.
The body of a naked function must consist of a single `naked_asm!` invocation, a heavily restricted variant of the `asm!` macro: the only legal operands are `const` and `sym`, and the only legal options are `raw` and `att_syntax`. In lieu of specifying operands, the `naked_asm!` within a naked function relies on the function's calling convention to determine the validity of registers.
## Documentation
The Rust Reference: https://github.com/rust-lang/reference/pull/1689
(Previous PR: https://github.com/rust-lang/reference/pull/1153)
## Tests
* [tests/run-make/naked-symbol-visiblity](https://github.com/rust-lang/rust/tree/master/tests/codegen/naked-fn) verifies that `pub`, `#[no_mangle]` and `#[linkage = "..."]` work correctly for naked functions
* [tests/codegen/naked-fn](https://github.com/rust-lang/rust/tree/master/tests/codegen/naked-fn) has tests for function alignment, use of generics, and validates the exact assembly output on linux, macos, windows and thumb
* [tests/ui/asm/naked-*](https://github.com/rust-lang/rust/tree/master/tests/ui/asm) tests for incompatible attributes, generating errors around incorrect use of `naked_asm!`, etc
## Interaction with other (unstable) features
### [fn_align](https://github.com/rust-lang/rust/issues/82232)
Combining `#[naked]` with `#[repr(align(N))]` works well, and is tested e.g. here
- https://github.com/rust-lang/rust/blob/master/tests/codegen/naked-fn/aligned.rs
- https://github.com/rust-lang/rust/blob/master/tests/codegen/naked-fn/min-function-alignment.rs
It's tested extensively because we do need to explicitly support the `repr(align)` attribute (and make sure we e.g. don't mistake powers of two for number of bytes).
## History
This feature was originally proposed in [RFC 1201](https://github.com/rust-lang/rfcs/pull/1201), filed on 2015-07-10 and accepted on 2016-03-21. Support for this feature was added in [#32410](https://github.com/rust-lang/rust/pull/32410), landing on 2016-03-23. Development languished for several years as it was realized that the semantics given in RFC 1201 were insufficiently specific. To address this, a minimal subset of naked functions was specified by [RFC 2972](https://github.com/rust-lang/rfcs/pull/2972), filed on 2020-08-07 and accepted on 2021-11-16. Prior to the acceptance of RFC 2972, all of the stricter behavior specified by RFC 2972 was implemented as a series of warn-by-default lints that would trigger on existing uses of the `naked` attribute; these lints became hard errors in [#93153](https://github.com/rust-lang/rust/pull/93153) on 2022-01-22. As a result, today RFC 2972 has completely superseded RFC 1201 in describing the semantics of the `naked` attribute.
More recently, the `naked_asm!` macro was added to replace the earlier use of a heavily restricted `asm!` invocation. The `naked_asm!` name is clearer in error messages, and provides a place for documenting the specific requirements of inline assembly in naked functions.
The implementation strategy was changed to emitting a global assembly block. In effect, an extern function
```rust
extern "C" fn foo() {
core::arch::naked_asm!("ret")
}
```
is emitted as something similar to
```rust
core::arch::global_asm!(
"foo:",
"ret"
);
extern "C" {
fn foo();
}
```
The codegen approach was chosen over the llvm naked function attribute because:
- the rust compiler can guarantee the behavior (no sneaky additional instructions, no inlining, etc.)
- behavior is the same on all backends (llvm, cranelift, gcc, etc)
Finally, there is now an allow list of compatible attributes on naked functions, so that e.g. `#[inline]` is rejected with an error. The `#[target_feature]` attribute on naked functions was later made separately unstable, because implementing it is complex and we did not want to block naked functions themselves on how target features work on them. See also https://github.com/rust-lang/rust/issues/138568.
relevant PRs for these recent changes
- https://github.com/rust-lang/rust/pull/127853
- https://github.com/rust-lang/rust/pull/128651
- https://github.com/rust-lang/rust/pull/128004
- https://github.com/rust-lang/rust/pull/138570
-
### Various historical notes
#### `noreturn`
[RFC 2972](https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md) mentions that naked functions
> must have a body which contains only a single asm!() statement which:
> iii. must contain the noreturn option.
Instead of `asm!`, the current implementation mandates that the body contain a single `naked_asm!` statement. The `naked_asm!` macro is a heavily restricted version of the `asm!` macro, making it easier to talk about and document the rules of assembly in naked functions and give dedicated error messages.
For `naked_asm!`, the behavior of the `asm!`'s `noreturn` option is implicit. The `noreturn` option means that it is UB for control flow to fall through the end of the assembly block. With `asm!`, this option is usually used for blocks that diverge (and thus have no return and can be typed as `!`). With `naked_asm!`, the intent is different: usually naked funtions do return, but they must do so from within the assembly block. The `noreturn` option was used so that the compiler would not itself also insert a `ret` instruction at the very end.
#### padding / `ud2`
A `naked_asm!` block that violates the safety assumption that control flow must not fall through the end of the assembly block is UB. Because no return instruction is emitted, whatever bytes follow the naked function will be executed, resulting in truly undefined behavior. There has been discussion whether rustc should emit an invalid instruction (e.g. `ud2` on x86) after the `naked_asm!` block to at least fail early in the case of an invalid `naked_asm!`. It was however decided that it is more useful to guarantee that `#[naked]` functions NEVER contain any instructions besides those in the `naked_asm!` block.
# unresolved questions
None
r? ``@Amanieu``
I've validated the tests on x86_64 and aarch64
simd intrinsics with mask: accept unsigned integer masks, and fix some of the errors
It's not clear at all why the mask would have to be signed, it is anyway interpreted bitwise. The backend should just make sure that works no matter the surface-level type; our LLVM backend already does this correctly. The note of "the mask may be widened, which only has the correct behavior for signed integers" explains... nothing? Why can't the code do the widening correctly? If necessary, just cast to the signed type first...
Also while we are at it, fix the errors. For simd_masked_load/store, the errors talked about the "third argument" but they meant the first argument (the mask is the first argument there). They also used the wrong type for `expected_element`.
I have extremely low confidence in the GCC part of this PR.
See [discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/257879-project-portable-simd/topic/On.20the.20sign.20of.20masks)
Introduce and use specialized `//@ ignore-auxiliary` for test support files instead of using `//@ ignore-test`
### Summary
Add a semantically meaningful directive for ignoring test *auxiliary* files. This is for auxiliary files that *participate* in actual tests but should not be built by `compiletest` (i.e. these files are involved through `mod xxx;` or `include!()` or `#[path = "xxx"]`, etc.).
### Motivation
A specialized directive like `//@ ignore-auxiliary` makes it way easier to audit disabled tests via `//@ ignore-test`.
- These support files cannot use the canonical `auxiliary/` dir because they participate in module resolution or are included, or their relative paths can be important for test intention otherwise.
Follow-up to:
- #139705
- #139783
- #139740
See also discussions in:
- [#t-compiler > Directive name for non-test aux files?](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Directive.20name.20for.20non-test.20aux.20files.3F/with/512773817)
- [#t-compiler > Handling disabled `//@ ignore-test` tests](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Handling.20disabled.20.60.2F.2F.40.20ignore-test.60.20tests/with/512005974)
- [#t-compiler/meetings > [steering] 2025-04-11 Dealing with disabled tests](https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bsteering.5D.202025-04-11.20Dealing.20with.20disabled.20tests/with/511717981)
### Remarks on remaining unconditionally disabled tests under `tests/`
After this PR, against commit 79a272c640, only **14** remaining test files are disabled through `//@ ignore-test`:
<details>
<summary>Remaining `//@ ignore-test` files under `tests/`</summary>
```
tests/debuginfo/drop-locations.rs
4://@ ignore-test (broken, see #128971)
tests/rustdoc/macro-document-private-duplicate.rs
1://@ ignore-test (fails spuriously, see issue #89228)
tests/rustdoc/inline_cross/assoc-const-equality.rs
3://@ ignore-test (FIXME: #125092)
tests/ui/match/issue-27021.rs
7://@ ignore-test (#54987)
tests/ui/match/issue-26996.rs
7://@ ignore-test (#54987)
tests/ui/issues/issue-49298.rs
9://@ ignore-test (#54987)
tests/ui/issues/issue-59756.rs
2://@ ignore-test (rustfix needs multiple suggestions)
tests/ui/precondition-checks/write.rs
5://@ ignore-test (unimplemented)
tests/ui/precondition-checks/read.rs
5://@ ignore-test (unimplemented)
tests/ui/precondition-checks/write_bytes.rs
5://@ ignore-test (unimplemented)
tests/ui/explicit-tail-calls/drop-order.rs
2://@ ignore-test: tail calls are not implemented in rustc_codegen_ssa yet, so this causes 🧊
tests/ui/panics/panic-short-backtrace-windows-x86_64.rs
3://@ ignore-test (#92000)
tests/ui/json/json-bom-plus-crlf-multifile-aux.rs
3://@ ignore-test Not a test. Used by other tests
tests/ui/traits/next-solver/object-soundness-requires-generalization.rs
2://@ ignore-test (see #114196)
```
</details>
Of these, most are either **unimplemented**, or **spurious**, or **known-broken**. The outstanding one is `tests/ui/json/json-bom-plus-crlf-multifile-aux.rs` which I did not want to touch in *this* PR -- that aux file has load-bearing BOM and carriage returns and byte offset matters. I think those test files that require special encoding / BOM probably are better off as `run-make` tests. See #139968 for that aux file.
### Review advice
- Best reviewed commit-by-commit.
- The directive name diverged from the most voted `//@ auxiliary` because I think that's easy to confuse with `//@ aux-{crate,dir}`.
r? compiler
Autodiff batching2
~I will rebase it once my first PR landed.~ done.
This autodiff batch mode is more similar to scalar autodiff, since it still only takes one shadow argument.
However, that argument is supposed to be `width` times larger.
r? `@oli-obk`
Tracking:
- https://github.com/rust-lang/rust/issues/124509
Rollup of 9 pull requests
Successful merges:
- #135340 (Add `explicit_extern_abis` Feature and Enforce Explicit ABIs)
- #139440 (rustc_target: RISC-V: feature addition batch 2)
- #139667 (cfi: Remove #[no_sanitize(cfi)] for extern weak functions)
- #139828 (Don't require rigid alias's trait to hold)
- #139854 (Improve parse errors for stray lifetimes in type position)
- #139889 (Clean UI tests 3 of n)
- #139894 (Fix `opt-dist` CLI flag and make it work without LLD)
- #139900 (stepping into impls for normalization is unproductive)
- #139915 (replace some #[rustc_intrinsic] usage with use of the libcore declarations)
r? `@ghost`
`@rustbot` modify labels: rollup
fix for multiple `#[repr(align(N))]` on functions
tracking issue: https://github.com/rust-lang/rust/issues/82232
fixes https://github.com/rust-lang/rust/issues/132464
The behavior of align is specified at https://doc.rust-lang.org/reference/type-layout.html#r-layout.repr.alignment.align
> For align, if the specified alignment is less than the alignment of the type without the align modifier, then the alignment is unaffected.
So in effect that means that the maximum of the specified alignments should be chosen. That is also the current behavior for `align` on ADTs:
```rust
#![feature(fn_align)]
#[repr(C, align(32), align(64))]
struct Foo {
x: u64,
}
const _: () = assert!(core::mem::align_of::<Foo>() == 64);
// See the godbolt LLVM output: the alignment of this function is 32
#[no_mangle]
#[repr(align(32))]
#[repr(align(64))]
fn foo() {}
// The current logic just picks the first alignment: the alignment of this function is 64
#[no_mangle]
#[repr(align(64))]
#[repr(align(32))]
fn bar() {}
```
https://godbolt.org/z/scco435jEafa859f812/compiler/rustc_middle/src/ty/mod.rs (L1529-L1532)
The https://github.com/rust-lang/rust/issues/132464 issue is really about parsing/representing the attribute, which has already been improved and now uses the "parse, don't validate" attribute approach. That means the behavior is already different from what the issue describes: on current `main`, the first value is chosen. This PR fixes a logic error, where we just did not check for the effect of two or more `align` modifiers. In combination, that fixes the issue.
cc ``@jdonszelmann`` if you do have further thoughs here
enforce unsafe attributes in pre-2024 editions by default
New unsafe attributes should emit an error when used without the `unsafe(...)` in all editions.
The `no_mangle`, `link_section` and `export_name` attributes are exceptions, and can still be used without an unsafe in earlier editions. The only attributes for which this change is relevant right now are `#[ffi_const]` and `#[ffi_pure]`.
This change is required for making `#[unsafe(naked)]` sound in pre-2024 editions.
Move `select_unpredictable` to the `hint` module
There has been considerable discussion in both the ACP (rust-lang/libs-team#468) and tracking issue (#133962) about whether the `bool::select_unpredictable` method should be in `core::hint` instead.
I believe this is the right move for the following reasons:
- The documentation explicitly says that it is a hint, not a codegen guarantee.
- `bool` doesn't have a corresponding `select` method, and I don't think we should be adding one.
- This shouldn't be something that people reach for with auto-completion unless they specifically understand the interactions with branch prediction. Using conditional moves can easily make code *slower* by preventing the CPU from speculating past the condition due to the data dependency.
- Although currently `core::hint` only contains no-ops, this isn't a hard rule (for example `unreachable_unchecked` is a bit of a gray area). The documentation only status that the module contains "hints to compiler that affects how code should be emitted or optimized". This is consistent with what `select_unpredictable` does.
Use the chaining methods on PartialOrd for slices too
#138135 added these doc-hidden trait methods to improve the tuple codegen. This PR adds more implementations and callers so that the codegen for slice (and array) comparisons also improves.
Polymorphize `array::IntoIter`'s iterator impl
Today we emit all the iterator methods for every different array width. That's wasteful since the actual array length never even comes into it -- the indices used are from the separate `alive: IndexRange` field, not even the `N` const param.
This PR switches things so that an `array::IntoIter<T, N>` stores a `PolymorphicIter<[MaybeUninit<T>; N]>`, which we *unsize* to `PolymorphicIter<[MaybeUninit<T>]>` and call methods on that non-`Sized` type for all the iterator methods.
That also necessarily makes the layout consistent between the different lengths of arrays, because of the unsizing. Compare that to today <https://rust.godbolt.org/z/Prb4xMPrb>, where different widths can't even be deduped because the offset to the indices is different for different array widths.
Fix breakage when running compiletest with `--test-args=--edition=2015`
Compiletest has an `--edition` flag to change the default edition tests are run with. Unfortunately no test suite successfully executes when that flag is passed. If the edition is set to something greater than 2015 the breakage is expected, since the test suite currently supports only edition 2015 (Ferrous Systems will open an MCP about fixing that soonish). Surprisingly, the test suite is also broken if `--edition=2015` is passed to compiletest. This PR focuses on fixing the latter.
This PR fixes the two categories of failures happening when `--edition=2015` is passed:
* Some edition-specific tests set their edition through `//@ compile-flags` instead of `//@ edition`. Compiletest doesn't parse the compile flags, so it would see no `//@ edition` and add another `--edition` flag, leading to a rustc error.
* Compiletest would add the edition after `//@ compile-flags`, while some tests depend on flags passed to `//@ compile-flags` being the last flags in the rustc invocation.
Note that for the first category, I opted to manually go and replace all `//@ compile-flags` setting an edition with an explicit `//@ edition`. We could've changed compiletest to instead check whether an edition was set in `//@ compile-flags`, but I thought it was better to enforce a consistent way to set the edition in tests.
I also added the edition to the stamp, so that changing `--edition` results in tests being re-executed.
r? `@jieyouxu`
add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`
fixes https://github.com/rust-lang/rust/issues/137372
adds `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`, which contrary to their non-dyn counterparts allow a non-const index. Many platforms (but notably not x86_64 or aarch64) have dedicated instructions for this operation, which stdarch can emit with this change.
Future work is to also make the `Index` operation on the `Simd` type emit this operation, but the intrinsic can't be used directly. We'll need some MIR shenanigans for that.
r? `@ghost`
Ensure `swap_nonoverlapping` is really always untyped
This replaces #134954, which was arguably overcomplicated.
## Fixes#134713
Actually using the type passed to `ptr::swap_nonoverlapping` for anything other than its size + align turns out to not work, so this goes back to always erasing the types down to just bytes.
(Except in `const`, which keeps doing the same thing as before to preserve `@RalfJung's` fix from #134689)
## Fixes#134946
I'd previously moved the swapping to use auto-vectorization *on bytes*, but someone pointed out on Discord that the tail loop handling from that left a whole bunch of byte-by-byte swapping around. This goes back to manual tail handling to avoid that, then still triggers auto-vectorization on pointer-width values. (So you'll see `<4 x i64>` on `x86-64-v3` for example.)