Support input/output in vector registers of s390x inline assembly (under asm_experimental_reg feature)
This extends currently clobber-only vector registers (`vreg`) support to allow passing `#[repr(simd)]` types, floats (f32/f64/f128), and integers (i32/i64/i128) as input/output.
This is unstable and gated under new `#![feature(asm_experimental_reg)]` (tracking issue: https://github.com/rust-lang/rust/issues/133416). If the feature is not enabled, only clober is supported as before.
| Architecture | Register class | Target feature | Allowed types |
| ------------ | -------------- | -------------- | -------------- |
| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
This matches the list of types that are supported by the vector registers in LLVM:
https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td#L301-L313
In addition to `core::simd` types and floats listed above, custom `#[repr(simd)]` types of the same size and type are also allowed. All allowed types other than i32/f32/i64/f64/i128, and relevant target features are currently unstable.
Currently there is no SIMD type for s390x in `core::arch`, but this is tracked in https://github.com/rust-lang/rust/issues/130869.
cc https://github.com/rust-lang/rust/issues/130869 about vector facility support in s390x
cc https://github.com/rust-lang/rust/issues/125398 & https://github.com/rust-lang/rust/issues/116909 about f128 support in asm
`@rustbot` label +O-SystemZ +A-inline-assembly
Fix asm goto with outputs and move it to a separate feature gate
Tracking issue: #119364
This PR addresses 3 aspects of asm goto with outputs:
* Codegen is fixed. My initial implementation has an oversight which cause the output to be only stored in fallthrough path, but not in label blocks.
* Outputs can now be used with `options(noreturn)` if a label block is given.
* All of this is moved to a new feature gate, because we likely want to stabilise `asm_goto` before asm goto with outputs.
`@rustbot` labels: +A-inline-assembly +F-asm
There is a not-very-useful layering in the lexer, where
`TokenTreesReader` contains a `StringReader`. This commit combines them
and names the result `Lexer`, which is a more obvious name for it.
The methods of `Lexer` are now split across `mod.rs` and `tokentrees.rs`
which isn't ideal, but it doesn't seem worth moving a bunch of code to
avoid it.
add a test for target-feature-ABI warnings in closures and when calling extern fn
Also update the comment regarding the inheritance of target features into closures, to make it more clear that we really shouldn't do this right now.
only store valid proc macro item for doc link
Fixes#132743
The definition item can be detected if it is exported in the doc, so store these items rather than skipping.
r? `@petrochenkov`
When labels are present, the `noreturn` option really means that asm block
won't fallthrough -- if labels are present, then outputs can still be
meaningfully used.
A used function with no mappings has historically indicated a bug, but that
will no longer be the case after moving some fallible span-processing steps
into codegen.
Rollup of 6 pull requests
Successful merges:
- #133300 (inject_panic_runtime(): Avoid double negation for 'any non rlib')
- #133301 (Add code example for `wrapping_neg` method for signed integers)
- #133371 (remove is_trivially_const_drop)
- #133389 (Stabilize `const_float_methods`)
- #133398 (rustdoc: do not call to_string, it's already impl Display)
- #133405 (tidy: Distinguish between two different meanings of "style file")
r? `@ghost`
`@rustbot` modify labels: rollup
inject_panic_runtime(): Avoid double negation for 'any non rlib'
<details>
<summary>This PR originally did more things .Click to expand to see.</summary>
By not trying to inject a profiler runtime when only building an rlib. This logic already exists for the panic runtime.
This makes
RUSTFLAGS="-Cinstrument-coverage" cargo build -Zbuild-std=std,profiler_builtins
work. Note that you probably also need
`RUST_COMPILER_RT_FOR_PROFILER=$src/llvm-project/compiler-rt` in your environment.
cc #79401
# Demonstration
Before this fix you get these errors:
```console
$ rm -rf target ; RUST_COMPILER_RT_FOR_PROFILER=/home/martin/src/llvm-project/compiler-rt RUSTFLAGS="-Cinstrument-coverage" cargo +nightly build --release -Zbuild-std=std,profiler_builtins
error: `profiler_builtins` crate (required by compiler options) is not compatible with crate attribute `#![no_core]`
error[E0152]: found duplicate lang item `manually_drop`
= note: first definition in `core` loaded from /home/martin/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-d453bab70303062c.rlib
= note: second definition in the local crate (`core`)
```
With the fix the build succeeds:
```console
$ rm -rf target ; RUST_COMPILER_RT_FOR_PROFILER=/home/martin/src/llvm-project/compiler-rt RUSTFLAGS="-Cinstrument-coverage" cargo +stage1 build --release -Zbuild-std=std,profiler_builtins
Finished `release` profile [optimized] target(s) in 45.57s
```
And we can check code coverage. My example program looks like this:
```rs
fn main() {
if std::env::args_os().nth(1) == Some("write-file".into()) {
std::fs::write("hello.txt", "Hello, world!").unwrap();
} else {
println!("Hello, world!");
}
}
```
when the program prints to stdout:
```
$ LLVM_PROFILE_FILE=stdout.profraw ./target/release/hello-world
Hello, world!
```
we can see that `fs::write()` is not being used (note the `0`'s):
```console
$ /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse stdout.profraw -o stdout.profdata
$ /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show target/release/hello-world --sources /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/library/std/src/fs.rs --instr-profile stdout.profdata --color | grep -A 3 'pub fn write(&mut self, write: b
ool) -> &mut Self {'
1357| 0| pub fn write(&mut self, write: bool) -> &mut Self {
1358| 0| self.0.write(write);
1359| 0| self
1360| 0| }
```
but when we print to a file:
```console
$ LLVM_PROFILE_FILE=file.profraw ./target/release/hello-world write-file
```
the code coverage shows `fs::write()` as being used (note the `1`'s):
```console
$ /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-profdata merge -sparse file.profraw -o file.profdata
$ /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/bin/llvm-cov show target/release/hello-world --sources /home/martin/src/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/library/std/src/fs.rs --instr-profile file.profdata --color | grep -A 3 'pub fn write(&mut self, write: bool) -> &mut Self {'
1357| 1| pub fn write(&mut self, write: bool) -> &mut Self {
1358| 1| self.0.write(write);
1359| 1| self
1360| 1| }
```
</summary>
rustc: Fail fast when compiling a source file larger than 4 GiB
Currently if you try to compile a file that is larger than 4 GiB, `rustc` will first read the whole into memory before failing.
If we can read the metadata of the file, we can fail before reading the file.
Using `cc_args` panics when using `-Clinker-flavor=ld`, because the
arguments are in a form tailored for `-Clinker-flavor=gcc`.
So instead, we use `link_args` and let that wrap the arguments with the
appropriate `-Wl` or `-Xlinker` when needed.