diff --git a/.github/workflows/flux.yml b/.github/workflows/flux.yml index 3433b04284b87..ad1370c04f807 100644 --- a/.github/workflows/flux.yml +++ b/.github/workflows/flux.yml @@ -9,7 +9,7 @@ on: env: FIXPOINT_VERSION: "556104ba5508891c357b0bdf819ce706e93d9349" - FLUX_VERSION: "844e2fc0caa6aa96d72f2fcb627a27bf2495d82e" + FLUX_VERSION: "f6bdf90c54ad6eed51b25c125f251cac01cfe170" jobs: check-flux-on-core: diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 95b0962b08241..541c99c828dc0 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -195,6 +195,25 @@ jobs: run: ./ci/update-musl.sh - run: cargo clippy --workspace --all-targets + build-custom: + name: Build custom target + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install Rust + run: | + rustup update nightly --no-self-update + rustup default nightly + rustup component add rust-src + - uses: Swatinem/rust-cache@v2 + - run: | + # Ensure we can build with custom target.json files (these can interact + # poorly with build scripts) + cargo build -p compiler_builtins -p libm \ + --target etc/thumbv7em-none-eabi-renamed.json \ + -Zbuild-std=core + benchmarks: name: Benchmarks timeout-minutes: 20 @@ -331,6 +350,7 @@ jobs: success: needs: - benchmarks + - build-custom - clippy - extensive - miri diff --git a/library/compiler-builtins/builtins-test-intrinsics/build.rs b/library/compiler-builtins/builtins-test-intrinsics/build.rs index 89b126ff2b2ed..b82581262f7b0 100644 --- a/library/compiler-builtins/builtins-test-intrinsics/build.rs +++ b/library/compiler-builtins/builtins-test-intrinsics/build.rs @@ -6,6 +6,5 @@ fn main() { println!("cargo::rerun-if-changed=../configure.rs"); let target = builtins_configure::Target::from_env(); - builtins_configure::configure_f16_f128(&target); builtins_configure::configure_aliases(&target); } diff --git a/library/compiler-builtins/builtins-test/benches/float_cmp.rs b/library/compiler-builtins/builtins-test/benches/float_cmp.rs index 87a89efb5a4fe..da29b5d313263 100644 --- a/library/compiler-builtins/builtins-test/benches/float_cmp.rs +++ b/library/compiler-builtins/builtins-test/benches/float_cmp.rs @@ -177,6 +177,7 @@ float_bench! { ], } +#[cfg(f128_enabled)] float_bench! { name: cmp_f128_gt, sig: (a: f128, b: f128) -> CmpResult, @@ -189,6 +190,7 @@ float_bench! { asm: [] } +#[cfg(f128_enabled)] float_bench! { name: cmp_f128_unord, sig: (a: f128, b: f128) -> CmpResult, diff --git a/library/compiler-builtins/builtins-test/build.rs b/library/compiler-builtins/builtins-test/build.rs index e8f4eb4dd22eb..5b2dcd12ef86f 100644 --- a/library/compiler-builtins/builtins-test/build.rs +++ b/library/compiler-builtins/builtins-test/build.rs @@ -116,5 +116,4 @@ fn main() { } builtins_configure::configure_aliases(&target); - builtins_configure::configure_f16_f128(&target); } diff --git a/library/compiler-builtins/builtins-test/tests/conv.rs b/library/compiler-builtins/builtins-test/tests/conv.rs index 491915d9bb172..7d729364faefb 100644 --- a/library/compiler-builtins/builtins-test/tests/conv.rs +++ b/library/compiler-builtins/builtins-test/tests/conv.rs @@ -118,7 +118,7 @@ mod i_to_f { i128, __floattidf; } - #[cfg(not(feature = "no-f16-f128"))] + #[cfg(f128_enabled)] #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"), u32, __floatunsitf; @@ -129,7 +129,7 @@ mod i_to_f { i128, __floattitf; } - #[cfg(not(feature = "no-f16-f128"))] + #[cfg(f128_enabled)] #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"), u32, __floatunsikf; diff --git a/library/compiler-builtins/builtins-test/tests/div_rem.rs b/library/compiler-builtins/builtins-test/tests/div_rem.rs index 5ae653cc90cc4..e8327f9b4b865 100644 --- a/library/compiler-builtins/builtins-test/tests/div_rem.rs +++ b/library/compiler-builtins/builtins-test/tests/div_rem.rs @@ -147,7 +147,7 @@ mod float_div { f64, __divdf3, Double, all(); } - #[cfg(not(feature = "no-f16-f128"))] + #[cfg(f128_enabled)] #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] float! { f128, __divtf3, Quad, @@ -156,7 +156,7 @@ mod float_div { not(any(feature = "no-sys-f128", all(target_arch = "aarch64", target_os = "linux"))); } - #[cfg(not(feature = "no-f16-f128"))] + #[cfg(f128_enabled)] #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] float! { f128, __divkf3, Quad, not(feature = "no-sys-f128"); diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index 27b9686eac644..8b7965bb2056d 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -54,29 +54,26 @@ symcheck=(cargo run -p symbol-check --release) [[ "$target" = "wasm"* ]] && symcheck+=(--features wasm) symcheck+=(-- build-and-check) -"${symcheck[@]}" -p compiler_builtins --target "$target" -"${symcheck[@]}" -p compiler_builtins --target "$target" --release -"${symcheck[@]}" -p compiler_builtins --target "$target" --features c -"${symcheck[@]}" -p compiler_builtins --target "$target" --features c --release -"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-asm -"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-asm --release -"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-f16-f128 -"${symcheck[@]}" -p compiler_builtins --target "$target" --features no-f16-f128 --release +"${symcheck[@]}" "$target" -- -p compiler_builtins +"${symcheck[@]}" "$target" -- -p compiler_builtins --release +"${symcheck[@]}" "$target" -- -p compiler_builtins --features c +"${symcheck[@]}" "$target" -- -p compiler_builtins --features c --release +"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm +"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-asm --release +"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128 +"${symcheck[@]}" "$target" -- -p compiler_builtins --features no-f16-f128 --release run_intrinsics_test() { - args=( - --target "$target" --verbose \ - --manifest-path builtins-test-intrinsics/Cargo.toml - ) - args+=( "$@" ) + build_args=(--verbose --manifest-path builtins-test-intrinsics/Cargo.toml) + build_args+=("$@") # symcheck also checks the results of builtins-test-intrinsics - "${symcheck[@]}" "${args[@]}" + "${symcheck[@]}" "$target" -- "${build_args[@]}" # FIXME: we get access violations on Windows, our entrypoint may need to # be tweaked. if [ "${BUILD_ONLY:-}" != "1" ] && ! [[ "$target" = *"windows"* ]]; then - cargo run "${args[@]}" + cargo run --target "$target" "${build_args[@]}" fi } diff --git a/library/compiler-builtins/compiler-builtins/Cargo.toml b/library/compiler-builtins/compiler-builtins/Cargo.toml index c5446cd76e326..3ccb05f73fb84 100644 --- a/library/compiler-builtins/compiler-builtins/Cargo.toml +++ b/library/compiler-builtins/compiler-builtins/Cargo.toml @@ -19,6 +19,8 @@ links = "compiler-rt" bench = false doctest = false test = false +# make sure this crate isn't included in public standard library docs +doc = false [dependencies] core = { path = "../../core", optional = true } diff --git a/library/compiler-builtins/compiler-builtins/build.rs b/library/compiler-builtins/compiler-builtins/build.rs index 018899faf1d44..8f51c12b535dc 100644 --- a/library/compiler-builtins/compiler-builtins/build.rs +++ b/library/compiler-builtins/compiler-builtins/build.rs @@ -2,7 +2,7 @@ mod configure; use std::env; -use configure::{Target, configure_aliases, configure_f16_f128}; +use configure::{Target, configure_aliases}; fn main() { println!("cargo::rerun-if-changed=build.rs"); @@ -12,7 +12,6 @@ fn main() { let cwd = env::current_dir().unwrap(); configure_check_cfg(); - configure_f16_f128(&target); configure_aliases(&target); configure_libm(&target); diff --git a/library/compiler-builtins/compiler-builtins/configure.rs b/library/compiler-builtins/compiler-builtins/configure.rs index d825f35a9aa05..9721ddf090c6f 100644 --- a/library/compiler-builtins/compiler-builtins/configure.rs +++ b/library/compiler-builtins/compiler-builtins/configure.rs @@ -1,6 +1,7 @@ // Configuration that is shared between `compiler_builtins` and `builtins_test`. -use std::env; +use std::process::{Command, Stdio}; +use std::{env, str}; #[derive(Debug)] #[allow(dead_code)] @@ -16,6 +17,8 @@ pub struct Target { pub pointer_width: u8, pub little_endian: bool, pub features: Vec, + pub reliable_f128: bool, + pub reliable_f16: bool, } impl Target { @@ -32,6 +35,26 @@ impl Target { .map(|s| s.to_lowercase().replace("_", "-")) .collect(); + // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used + // to get consistent output regardless of channel (`f16`/`f128` config options are hidden + // on stable otherwise). + let mut cmd = Command::new(env::var("RUSTC").unwrap()); + cmd.args(["--print=cfg", "--target", &triple]) + .env("RUSTC_BOOTSTRAP", "1") + .stderr(Stdio::inherit()); + let out = cmd + .output() + .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}")); + let rustc_cfg = str::from_utf8(&out.stdout).unwrap(); + + // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe + // choice and leave `f16` and `f128` disabled. + let rustc_output_ok = out.status.success(); + let reliable_f128 = + rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128"); + let reliable_f16 = + rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16"); + Self { triple, triple_split, @@ -51,6 +74,8 @@ impl Target { .split(",") .map(ToOwned::to_owned) .collect(), + reliable_f128, + reliable_f16, } } @@ -74,63 +99,24 @@ pub fn configure_aliases(target: &Target) { if target.triple_split[0] == "thumbv6m" || target.triple_split[0] == "thumbv8m.base" { println!("cargo:rustc-cfg=thumb_1") } -} - -/// Configure whether or not `f16` and `f128` support should be enabled. -pub fn configure_f16_f128(target: &Target) { - // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means - // that the backend will not crash when using these types and generates code that can be called - // without crashing (no infinite recursion). This does not mean that the platform doesn't have - // ABI or other bugs. - // - // We do this here rather than in `rust-lang/rust` because configuring via cargo features is - // not straightforward. - // - // Original source of this list: - // - let f16_enabled = match target.arch.as_str() { - // Unsupported - "arm64ec" => false, - // Selection failure - "s390x" => false, - // Infinite recursion - "csky" => false, - "hexagon" => false, - "powerpc" | "powerpc64" => false, - "sparc" | "sparc64" => false, - "wasm32" | "wasm64" => false, - // Most everything else works as of LLVM 19 - _ => true, - }; - let f128_enabled = match target.arch.as_str() { - // Unsupported (libcall is not supported) - "amdgpu" => false, - // Unsupported - "arm64ec" => false, - // FIXME(llvm20): fixed by - "mips64" | "mips64r6" => false, - // Selection failure - "nvptx64" => false, - // Selection failure - "powerpc64" if &target.os == "aix" => false, - // Selection failure - "sparc" => false, - // Most everything else works as of LLVM 19 - _ => true, - }; + /* Not all backends support `f16` and `f128` to the same level on all architectures, so we + * need to disable things if the compiler may crash. See configuration at: + * * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432 + * * https://github.com/rust-lang/rustc_codegen_gcc/blob/4b5c44b14166083eef8d71f15f5ea1f53fc976a0/src/lib.rs#L496-L507 + * * https://github.com/rust-lang/rustc_codegen_cranelift/blob/c713ffab3c6e28ab4b4dd4e392330f786ea657ad/src/lib.rs#L196-L226 + */ - // If the feature is set, disable these types. - let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some(); + // If the feature is set, disable both of these types. + let no_f16_f128 = target.cargo_features.iter().any(|s| s == "no-f16-f128"); println!("cargo::rustc-check-cfg=cfg(f16_enabled)"); - println!("cargo::rustc-check-cfg=cfg(f128_enabled)"); - - if f16_enabled && !disable_both { + if target.reliable_f16 && !no_f16_f128 { println!("cargo::rustc-cfg=f16_enabled"); } - if f128_enabled && !disable_both { + println!("cargo::rustc-check-cfg=cfg(f128_enabled)"); + if target.reliable_f128 && !no_f16_f128 { println!("cargo::rustc-cfg=f128_enabled"); } } diff --git a/library/compiler-builtins/compiler-builtins/src/aarch64.rs b/library/compiler-builtins/compiler-builtins/src/aarch64.rs index 80392187c89b4..a72b30d29f0ba 100644 --- a/library/compiler-builtins/compiler-builtins/src/aarch64.rs +++ b/library/compiler-builtins/compiler-builtins/src/aarch64.rs @@ -5,7 +5,7 @@ use core::intrinsics; intrinsics! { #[unsafe(naked)] #[cfg(all(target_os = "uefi", not(feature = "no-asm")))] - pub unsafe extern "C" fn __chkstk() { + pub unsafe extern "custom" fn __chkstk() { core::arch::naked_asm!( ".p2align 2", "lsl x16, x15, #4", diff --git a/library/compiler-builtins/compiler-builtins/src/arm.rs b/library/compiler-builtins/compiler-builtins/src/arm.rs index a7d84e49b3493..fbec93ca4312e 100644 --- a/library/compiler-builtins/compiler-builtins/src/arm.rs +++ b/library/compiler-builtins/compiler-builtins/src/arm.rs @@ -9,11 +9,10 @@ unsafe extern "C" { } // SAFETY: these are defined in compiler-builtins -// FIXME(extern_custom), this isn't always the correct ABI -unsafe extern "aapcs" { +unsafe extern "custom" { // AAPCS is not always the correct ABI for these intrinsics, but we only use this to // forward another `__aeabi_` call so it doesn't matter. - fn __aeabi_idiv(a: i32, b: i32) -> i32; + fn __aeabi_idiv(); } intrinsics! { @@ -21,7 +20,7 @@ intrinsics! { // custom calling convention which can't be implemented using a normal Rust function. #[unsafe(naked)] #[cfg(not(target_env = "msvc"))] - pub unsafe extern "C" fn __aeabi_uidivmod() { + pub unsafe extern "custom" fn __aeabi_uidivmod() { core::arch::naked_asm!( "push {{lr}}", "sub sp, sp, #4", @@ -35,7 +34,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_uldivmod() { + pub unsafe extern "custom" fn __aeabi_uldivmod() { core::arch::naked_asm!( "push {{r4, lr}}", "sub sp, sp, #16", @@ -51,7 +50,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_idivmod() { + pub unsafe extern "custom" fn __aeabi_idivmod() { core::arch::naked_asm!( "push {{r0, r1, r4, lr}}", "bl {trampoline}", @@ -64,7 +63,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __aeabi_ldivmod() { + pub unsafe extern "custom" fn __aeabi_ldivmod() { core::arch::naked_asm!( "push {{r4, lr}}", "sub sp, sp, #16", @@ -135,8 +134,8 @@ intrinsics! { /// eight bytes. #[cfg(not(target_vendor = "apple"))] pub unsafe extern "aapcs" fn __aeabi_memcpy8(dst: *mut u8, src: *const u8, n: usize) { - debug_assert!(dst.addr() & 7 == 0); - debug_assert!(src.addr() & 7 == 0); + debug_assert!(dst.addr().is_multiple_of(8)); + debug_assert!(src.addr().is_multiple_of(8)); // SAFETY: memcpy preconditions apply, less strict alignment. unsafe { __aeabi_memcpy4(dst, src, n) }; @@ -161,8 +160,8 @@ intrinsics! { /// four bytes. #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memmove4(dst: *mut u8, src: *const u8, n: usize) { - debug_assert!(dst.addr() & 3 == 0); - debug_assert!(src.addr() & 3 == 0); + debug_assert!(dst.addr().is_multiple_of(4)); + debug_assert!(src.addr().is_multiple_of(4)); // SAFETY: same preconditions, less strict aligment. unsafe { __aeabi_memmove(dst, src, n) }; @@ -176,8 +175,8 @@ intrinsics! { /// eight bytes. #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memmove8(dst: *mut u8, src: *const u8, n: usize) { - debug_assert!(dst.addr() & 7 == 0); - debug_assert!(src.addr() & 7 == 0); + debug_assert!(dst.addr().is_multiple_of(8)); + debug_assert!(src.addr().is_multiple_of(8)); // SAFETY: memmove preconditions apply, less strict alignment. unsafe { __aeabi_memmove(dst, src, n) }; @@ -236,7 +235,7 @@ intrinsics! { /// eight bytes. #[cfg(not(target_vendor = "apple"))] pub unsafe extern "aapcs" fn __aeabi_memset8(dst: *mut u8, n: usize, c: i32) { - debug_assert!(dst.addr() & 7 == 0); + debug_assert!(dst.addr().is_multiple_of(8)); // SAFETY: memset preconditions apply, less strict alignment. unsafe { __aeabi_memset4(dst, n, c) }; @@ -261,7 +260,7 @@ intrinsics! { /// four bytes. #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memclr4(dst: *mut u8, n: usize) { - debug_assert!(dst.addr() & 3 == 0); + debug_assert!(dst.addr().is_multiple_of(4)); // SAFETY: memclr preconditions apply, less strict alignment. unsafe { __aeabi_memset4(dst, n, 0) }; @@ -275,7 +274,7 @@ intrinsics! { /// eight bytes. #[cfg(not(any(target_vendor = "apple", target_env = "msvc")))] pub unsafe extern "aapcs" fn __aeabi_memclr8(dst: *mut u8, n: usize) { - debug_assert!(dst.addr() & 7 == 0); + debug_assert!(dst.addr().is_multiple_of(8)); // SAFETY: memclr preconditions apply, less strict alignment. unsafe { __aeabi_memset4(dst, n, 0) }; diff --git a/library/compiler-builtins/compiler-builtins/src/int/udiv.rs b/library/compiler-builtins/compiler-builtins/src/int/udiv.rs index b9dee63c4cc7a..017a81ac91490 100644 --- a/library/compiler-builtins/compiler-builtins/src/int/udiv.rs +++ b/library/compiler-builtins/compiler-builtins/src/int/udiv.rs @@ -44,7 +44,7 @@ intrinsics! { } #[unsafe(naked)] - pub unsafe extern "C" fn __udivmodqi4() { + pub unsafe extern "custom" fn __udivmodqi4() { // compute unsigned 8-bit `n / d` and `n % d`. // // Note: GCC implements a [non-standard calling convention](https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention) for this function. diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index 1cec39d8b41bb..fe0ad81dd3a3d 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -1,11 +1,13 @@ #![cfg_attr(feature = "compiler-builtins", compiler_builtins)] #![cfg_attr(all(target_family = "wasm"), feature(wasm_numeric_instr))] +#![feature(abi_custom)] #![feature(abi_unadjusted)] #![feature(asm_experimental_arch)] #![feature(cfg_target_has_atomic)] #![feature(compiler_builtins)] #![feature(core_intrinsics)] #![feature(linkage)] +#![feature(asm_cfg)] #![feature(naked_functions)] #![feature(repr_simd)] #![feature(macro_metavar_expr_concat)] diff --git a/library/compiler-builtins/compiler-builtins/src/probestack.rs b/library/compiler-builtins/compiler-builtins/src/probestack.rs index 1441fd73b8d6f..f4105dde57e66 100644 --- a/library/compiler-builtins/compiler-builtins/src/probestack.rs +++ b/library/compiler-builtins/compiler-builtins/src/probestack.rs @@ -52,36 +52,12 @@ // Our goal here is to touch each page between %rsp+8 and %rsp+8-%rax, // ensuring that if any pages are unmapped we'll make a page fault. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // The ABI here is that the stack frame size is located in `%rax`. Upon // return we're not supposed to modify `%rsp` or `%rax`. #[cfg(target_arch = "x86_64")] #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { - #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))] - macro_rules! ret { - () => { - "ret" - }; - } - - #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] - macro_rules! ret { - // for this target, [manually patch for LVI]. - // - // [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions - () => { - " - pop %r11 - lfence - jmp *%r11 - " - }; - } - +pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc @@ -131,8 +107,18 @@ pub unsafe extern "C" fn __rust_probestack() { .cfi_def_cfa_register %rsp .cfi_adjust_cfa_offset -8 ", - ret!(), - " + #[cfg(not(all(target_env = "sgx", target_vendor = "fortanix")))] + " ret", + #[cfg(all(target_env = "sgx", target_vendor = "fortanix"))] + " + // for this target, [manually patch for LVI]. + // + // [manually patch for LVI]: https://software.intel.com/security-software-guidance/insights/deep-dive-load-value-injection#specialinstructions + pop %r11 + lfence + jmp *%r11 + ", + " .cfi_endproc ", options(att_syntax) @@ -144,13 +130,10 @@ pub unsafe extern "C" fn __rust_probestack() { // that on Unix we're expected to restore everything as it was, this // function basically can't tamper with anything. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // The ABI here is the same as x86_64, except everything is 32-bits large. #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { +pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc @@ -192,9 +175,6 @@ pub unsafe extern "C" fn __rust_probestack() { // probestack function will also do things like _chkstk in MSVC. // So we need to sub %ax %sp in probestack when arch is x86. // -// FIXME(abi_custom): This function is unsafe because it uses a custom ABI, -// it does not actually match `extern "C"`. -// // REF: Rust commit(74e80468347) // rust\src\llvm-project\llvm\lib\Target\X86\X86FrameLowering.cpp: 805 // Comments in LLVM: @@ -203,7 +183,7 @@ pub unsafe extern "C" fn __rust_probestack() { // themselves. #[unsafe(naked)] #[rustc_std_internal_symbol] -pub unsafe extern "C" fn __rust_probestack() { +pub unsafe extern "custom" fn __rust_probestack() { core::arch::naked_asm!( " .cfi_startproc diff --git a/library/compiler-builtins/compiler-builtins/src/x86.rs b/library/compiler-builtins/compiler-builtins/src/x86.rs index 01152d9c79869..16e50922a9454 100644 --- a/library/compiler-builtins/compiler-builtins/src/x86.rs +++ b/library/compiler-builtins/compiler-builtins/src/x86.rs @@ -2,7 +2,7 @@ use core::intrinsics; -// NOTE These functions are implemented using assembly because they using a custom +// NOTE These functions are implemented using assembly because they use a custom // calling convention which can't be implemented using a normal Rust function // NOTE These functions are never mangled as they are not tested against compiler-rt @@ -13,10 +13,10 @@ intrinsics! { any(all(windows, target_env = "gnu"), target_os = "uefi"), not(feature = "no-asm") ))] - pub unsafe extern "C" fn __chkstk() { + pub unsafe extern "custom" fn __chkstk() { core::arch::naked_asm!( - "jmp __alloca", // Jump to __alloca since fallthrough may be unreliable" - options(att_syntax) + "jmp {}", // Jump to __alloca since fallthrough may be unreliable" + sym crate::x86::_alloca::_alloca, ); } @@ -25,7 +25,7 @@ intrinsics! { any(all(windows, target_env = "gnu"), target_os = "uefi"), not(feature = "no-asm") ))] - pub unsafe extern "C" fn _alloca() { + pub unsafe extern "custom" fn _alloca() { // __chkstk and _alloca are the same function core::arch::naked_asm!( "push %ecx", diff --git a/library/compiler-builtins/compiler-builtins/src/x86_64.rs b/library/compiler-builtins/compiler-builtins/src/x86_64.rs index fc1190f79b237..9b7133b482e4e 100644 --- a/library/compiler-builtins/compiler-builtins/src/x86_64.rs +++ b/library/compiler-builtins/compiler-builtins/src/x86_64.rs @@ -2,7 +2,7 @@ use core::intrinsics; -// NOTE These functions are implemented using assembly because they using a custom +// NOTE These functions are implemented using assembly because they use a custom // calling convention which can't be implemented using a normal Rust function // NOTE These functions are never mangled as they are not tested against compiler-rt @@ -17,7 +17,7 @@ intrinsics! { ), not(feature = "no-asm") ))] - pub unsafe extern "C" fn ___chkstk_ms() { + pub unsafe extern "custom" fn ___chkstk_ms() { core::arch::naked_asm!( "push %rcx", "push %rax", diff --git a/library/compiler-builtins/crates/josh-sync/Cargo.toml b/library/compiler-builtins/crates/josh-sync/Cargo.toml index 1f3bb376d6d91..8e2e891db5426 100644 --- a/library/compiler-builtins/crates/josh-sync/Cargo.toml +++ b/library/compiler-builtins/crates/josh-sync/Cargo.toml @@ -5,3 +5,4 @@ publish = false [dependencies] directories = "6.0.0" +regex-lite = "0.1.6" diff --git a/library/compiler-builtins/crates/josh-sync/src/sync.rs b/library/compiler-builtins/crates/josh-sync/src/sync.rs index 003cf187d8301..2d89d2d1cea2f 100644 --- a/library/compiler-builtins/crates/josh-sync/src/sync.rs +++ b/library/compiler-builtins/crates/josh-sync/src/sync.rs @@ -1,8 +1,11 @@ +use std::borrow::Cow; use std::net::{SocketAddr, TcpStream}; use std::process::{Command, Stdio, exit}; use std::time::Duration; use std::{env, fs, process, thread}; +use regex_lite::Regex; + const JOSH_PORT: u16 = 42042; const DEFAULT_PR_BRANCH: &str = "update-builtins"; @@ -77,6 +80,7 @@ impl GitSync { "--depth=1", ]); let new_summary = check_output(["git", "log", "-1", "--format=%h %s", &new_upstream_base]); + let new_summary = replace_references(&new_summary, &self.upstream_repo); // Update rust-version file. As a separate commit, since making it part of // the merge has confused the heck out of josh in the past. @@ -297,6 +301,13 @@ fn check_output_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) -> String::from_utf8(out.stdout.trim_ascii().to_vec()).expect("non-UTF8 output") } +/// Replace `#1234`-style issue/PR references with `repo#1234` to ensure links work across +/// repositories. +fn replace_references<'a>(s: &'a str, repo: &str) -> Cow<'a, str> { + let re = Regex::new(r"\B(?P#\d+)\b").unwrap(); + re.replace(s, &format!("{repo}$id")) +} + /// Create a wrapper that stops Josh on drop. pub struct Josh(process::Child); @@ -369,3 +380,22 @@ impl Drop for Josh { self.0.kill().expect("failed to SIGKILL josh-proxy"); } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_replace() { + assert_eq!(replace_references("#1234", "r-l/rust"), "r-l/rust#1234"); + assert_eq!(replace_references("#1234x", "r-l/rust"), "#1234x"); + assert_eq!( + replace_references("merge #1234", "r-l/rust"), + "merge r-l/rust#1234" + ); + assert_eq!( + replace_references("foo/bar#1234", "r-l/rust"), + "foo/bar#1234" + ); + } +} diff --git a/library/compiler-builtins/crates/libm-macros/src/lib.rs b/library/compiler-builtins/crates/libm-macros/src/lib.rs index 482da974ca89f..7efa1488f570e 100644 --- a/library/compiler-builtins/crates/libm-macros/src/lib.rs +++ b/library/compiler-builtins/crates/libm-macros/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(let_chains)] - mod enums; mod parse; mod shared; diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs index d83cd318d6a95..1312a71797032 100644 --- a/library/compiler-builtins/crates/symbol-check/src/main.rs +++ b/library/compiler-builtins/crates/symbol-check/src/main.rs @@ -8,7 +8,9 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use object::read::archive::{ArchiveFile, ArchiveMember}; -use object::{Object, ObjectSymbol, Symbol, SymbolKind, SymbolScope, SymbolSection}; +use object::{ + File as ObjFile, Object, ObjectSymbol, Symbol, SymbolKind, SymbolScope, SymbolSection, +}; use serde_json::Value; const CHECK_LIBRARIES: &[&str] = &["compiler_builtins", "builtins_test_intrinsics"]; @@ -16,10 +18,12 @@ const CHECK_EXTENSIONS: &[Option<&str>] = &[Some("rlib"), Some("a"), Some("exe") const USAGE: &str = "Usage: - symbol-check build-and-check CARGO_ARGS ... + symbol-check build-and-check [TARGET] -- CARGO_BUILD_ARGS ... -Cargo will get invoked with `CARGO_ARGS` and all output +Cargo will get invoked with `CARGO_ARGS` and the specified target. All output `compiler_builtins*.rlib` files will be checked. + +If TARGET is not specified, the host target is used. "; fn main() { @@ -28,13 +32,13 @@ fn main() { let args_ref = args.iter().map(String::as_str).collect::>(); match &args_ref[1..] { - ["build-and-check", rest @ ..] if !rest.is_empty() => { - let paths = exec_cargo_with_args(rest); - for path in paths { - println!("Checking {}", path.display()); - verify_no_duplicates(&path); - verify_core_symbols(&path); - } + ["build-and-check", target, "--", args @ ..] if !args.is_empty() => { + check_cargo_args(args); + run_build_and_check(target, args); + } + ["build-and-check", "--", args @ ..] if !args.is_empty() => { + check_cargo_args(args); + run_build_and_check(&host_target(), args); } _ => { println!("{USAGE}"); @@ -43,14 +47,54 @@ fn main() { } } +/// Make sure `--target` isn't passed to avoid confusion (since it should be proivded only once, +/// positionally). +fn check_cargo_args(args: &[&str]) { + for arg in args { + assert!( + !arg.contains("--target"), + "target must be passed positionally. {USAGE}" + ); + } +} + +fn run_build_and_check(target: &str, args: &[&str]) { + let paths = exec_cargo_with_args(target, args); + for path in paths { + println!("Checking {}", path.display()); + let archive = Archive::from_path(&path); + + verify_no_duplicates(&archive); + verify_core_symbols(&archive); + } +} + +fn host_target() -> String { + let out = Command::new("rustc") + .arg("--version") + .arg("--verbose") + .output() + .unwrap(); + assert!(out.status.success()); + let out = String::from_utf8(out.stdout).unwrap(); + out.lines() + .find_map(|s| s.strip_prefix("host: ")) + .unwrap() + .to_owned() +} + /// Run `cargo build` with the provided additional arguments, collecting the list of created /// libraries. -fn exec_cargo_with_args(args: &[&str]) -> Vec { +fn exec_cargo_with_args(target: &str, args: &[&str]) -> Vec { let mut cmd = Command::new("cargo"); - cmd.arg("build") - .arg("--message-format=json") - .args(args) - .stdout(Stdio::piped()); + cmd.args([ + "build", + "--target", + target, + "--message-format=json-diagnostic-rendered-ansi", + ]) + .args(args) + .stdout(Stdio::piped()); println!("running: {cmd:?}"); let mut child = cmd.spawn().expect("failed to launch Cargo"); @@ -61,11 +105,21 @@ fn exec_cargo_with_args(args: &[&str]) -> Vec { for line in reader.lines() { let line = line.expect("failed to read line"); - println!("{line}"); // tee to stdout - - // Select only steps that create files let j: Value = serde_json::from_str(&line).expect("failed to deserialize"); - if j["reason"] != "compiler-artifact" { + let reason = &j["reason"]; + + // Forward output that is meant to be user-facing + if reason == "compiler-message" { + println!("{}", j["message"]["rendered"].as_str().unwrap()); + } else if reason == "build-finished" { + println!("build finshed. success: {}", j["success"]); + } else if reason == "build-script-executed" { + let pretty = serde_json::to_string_pretty(&j).unwrap(); + println!("build script output: {pretty}",); + } + + // Only interested in the artifact list now + if reason != "compiler-artifact" { continue; } @@ -133,12 +187,12 @@ impl SymInfo { /// Note that this will also locate cases where a symbol is weakly defined in more than one place. /// Technically there are no linker errors that will come from this, but it keeps our binary more /// straightforward and saves some distribution size. -fn verify_no_duplicates(path: &Path) { +fn verify_no_duplicates(archive: &Archive) { let mut syms = BTreeMap::::new(); let mut dups = Vec::new(); let mut found_any = false; - for_each_symbol(path, |symbol, member| { + archive.for_each_symbol(|symbol, member| { // Only check defined globals if !symbol.is_global() || symbol.is_undefined() { return; @@ -185,12 +239,12 @@ fn verify_no_duplicates(path: &Path) { } /// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined. -fn verify_core_symbols(path: &Path) { +fn verify_core_symbols(archive: &Archive) { let mut defined = BTreeSet::new(); let mut undefined = Vec::new(); let mut has_symbols = false; - for_each_symbol(path, |symbol, member| { + archive.for_each_symbol(|symbol, member| { has_symbols = true; // Find only symbols from `core` @@ -219,14 +273,40 @@ fn verify_core_symbols(path: &Path) { println!(" success: no undefined references to core found"); } -/// For a given archive path, do something with each symbol. -fn for_each_symbol(path: &Path, mut f: impl FnMut(Symbol, &ArchiveMember)) { - let data = fs::read(path).expect("reading file failed"); - let archive = ArchiveFile::parse(data.as_slice()).expect("archive parse failed"); - for member in archive.members() { - let member = member.expect("failed to access member"); - let obj_data = member.data(&*data).expect("failed to access object"); - let obj = object::File::parse(obj_data).expect("failed to parse object"); - obj.symbols().for_each(|sym| f(sym, &member)); +/// Thin wrapper for owning data used by `object`. +struct Archive { + data: Vec, +} + +impl Archive { + fn from_path(path: &Path) -> Self { + Self { + data: fs::read(path).expect("reading file failed"), + } + } + + fn file(&self) -> ArchiveFile<'_> { + ArchiveFile::parse(self.data.as_slice()).expect("archive parse failed") + } + + /// For a given archive, do something with each object file. + fn for_each_object(&self, mut f: impl FnMut(ObjFile, &ArchiveMember)) { + let archive = self.file(); + + for member in archive.members() { + let member = member.expect("failed to access member"); + let obj_data = member + .data(self.data.as_slice()) + .expect("failed to access object"); + let obj = ObjFile::parse(obj_data).expect("failed to parse object"); + f(obj, &member); + } + } + + /// For a given archive, do something with each symbol. + fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ArchiveMember)) { + self.for_each_object(|obj, member| { + obj.symbols().for_each(|sym| f(sym, member)); + }); } } diff --git a/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json new file mode 100644 index 0000000000000..81273d44e4965 --- /dev/null +++ b/library/compiler-builtins/etc/thumbv7em-none-eabi-renamed.json @@ -0,0 +1,23 @@ +{ + "abi": "eabi", + "arch": "arm", + "c-enum-min-bits": 8, + "crt-objects-fallback": "false", + "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", + "emit-debug-gdb-scripts": false, + "frame-pointer": "always", + "linker": "rust-lld", + "linker-flavor": "gnu-lld", + "llvm-floatabi": "soft", + "llvm-target": "thumbv7em-none-eabi", + "max-atomic-width": 32, + "metadata": { + "description": "Bare ARMv7E-M", + "host_tools": false, + "std": false, + "tier": 2 + }, + "panic-strategy": "abort", + "relocation-model": "static", + "target-pointer-width": "32" +} diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs index a0928a29f9992..02ee13f804f16 100644 --- a/library/compiler-builtins/libm-test/benches/icount.rs +++ b/library/compiler-builtins/libm-test/benches/icount.rs @@ -119,6 +119,22 @@ fn icount_bench_u256_add(cases: Vec<(u256, u256)>) { } } +#[library_benchmark] +#[bench::linspace(setup_u256_add())] +fn icount_bench_u256_sub(cases: Vec<(u256, u256)>) { + for (x, y) in cases.iter().copied() { + black_box(black_box(x) - black_box(y)); + } +} + +#[library_benchmark] +#[bench::linspace(setup_u256_shift())] +fn icount_bench_u256_shl(cases: Vec<(u256, u32)>) { + for (x, y) in cases.iter().copied() { + black_box(black_box(x) << black_box(y)); + } +} + #[library_benchmark] #[bench::linspace(setup_u256_shift())] fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) { @@ -129,7 +145,7 @@ fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) { library_benchmark_group!( name = icount_bench_u128_group; - benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_shr + benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_sub, icount_bench_u256_shl, icount_bench_u256_shr ); #[library_benchmark] diff --git a/library/compiler-builtins/libm-test/tests/u256.rs b/library/compiler-builtins/libm-test/tests/u256.rs index 8cbb3ad226f67..d1c5cfbcc586d 100644 --- a/library/compiler-builtins/libm-test/tests/u256.rs +++ b/library/compiler-builtins/libm-test/tests/u256.rs @@ -111,12 +111,54 @@ fn mp_u256_add() { let y = random_u256(&mut rng); assign_bigint(&mut bx, x); assign_bigint(&mut by, y); - let actual = x + y; + let actual = if u256::MAX - x >= y { + x + y + } else { + // otherwise (u256::MAX - x) < y, so the wrapped result is + // (x + y) - (u256::MAX + 1) == y - (u256::MAX - x) - 1 + y - (u256::MAX - x) - 1_u128.widen() + }; bx += &by; check_one(|| hexu(x), || Some(hexu(y)), actual, &mut bx); } } +#[test] +fn mp_u256_sub() { + let mut rng = ChaCha8Rng::from_seed(*SEED); + let mut bx = BigInt::new(); + let mut by = BigInt::new(); + + for _ in 0..bigint_fuzz_iteration_count() { + let x = random_u256(&mut rng); + let y = random_u256(&mut rng); + assign_bigint(&mut bx, x); + assign_bigint(&mut by, y); + + // since the operators (may) panic on overflow, + // we should test something that doesn't + let actual = if x >= y { x - y } else { y - x }; + bx -= &by; + bx.abs_mut(); + check_one(|| hexu(x), || Some(hexu(y)), actual, &mut bx); + } +} + +#[test] +fn mp_u256_shl() { + let mut rng = ChaCha8Rng::from_seed(*SEED); + let mut bx = BigInt::new(); + + for _ in 0..bigint_fuzz_iteration_count() { + let x = random_u256(&mut rng); + let shift: u32 = rng.random_range(0..256); + assign_bigint(&mut bx, x); + let actual = x << shift; + bx <<= shift; + check_one(|| hexu(x), || Some(shift.to_string()), actual, &mut bx); + } +} + #[test] fn mp_u256_shr() { let mut rng = ChaCha8Rng::from_seed(*SEED); @@ -124,7 +166,7 @@ fn mp_u256_shr() { for _ in 0..bigint_fuzz_iteration_count() { let x = random_u256(&mut rng); - let shift: u32 = rng.random_range(0..255); + let shift: u32 = rng.random_range(0..256); assign_bigint(&mut bx, x); let actual = x >> shift; bx >>= shift; diff --git a/library/compiler-builtins/libm-test/tests/z_extensive/run.rs b/library/compiler-builtins/libm-test/tests/z_extensive/run.rs index f2ba6a4a0e3e6..e04e00c6d743a 100644 --- a/library/compiler-builtins/libm-test/tests/z_extensive/run.rs +++ b/library/compiler-builtins/libm-test/tests/z_extensive/run.rs @@ -197,15 +197,15 @@ impl Progress { fn update(&self, completed: u64, input: impl fmt::Debug) { // Infrequently update the progress bar. - if completed % 20_000 == 0 { + if completed.is_multiple_of(20_000) { self.pb.set_position(completed); } - if completed % 500_000 == 0 { + if completed.is_multiple_of(500_000) { self.pb.set_message(format!("input: {input:<24?}")); } - if !self.is_tty && completed % 5_000_000 == 0 { + if !self.is_tty && completed.is_multiple_of(5_000_000) { let len = self.pb.length().unwrap_or_default(); eprintln!( "[{elapsed:3?}s {percent:3.0}%] {name} \ diff --git a/library/compiler-builtins/libm/configure.rs b/library/compiler-builtins/libm/configure.rs index 2a497c7b11790..f9100d2d58b26 100644 --- a/library/compiler-builtins/libm/configure.rs +++ b/library/compiler-builtins/libm/configure.rs @@ -1,7 +1,8 @@ // Configuration shared with both libm and libm-test -use std::env; use std::path::PathBuf; +use std::process::{Command, Stdio}; +use std::{env, str}; #[allow(dead_code)] pub struct Config { @@ -9,6 +10,7 @@ pub struct Config { pub out_dir: PathBuf, pub opt_level: String, pub cargo_features: Vec, + pub target_triple: String, pub target_arch: String, pub target_env: String, pub target_family: Option, @@ -16,10 +18,13 @@ pub struct Config { pub target_string: String, pub target_vendor: String, pub target_features: Vec, + pub reliable_f128: bool, + pub reliable_f16: bool, } impl Config { pub fn from_env() -> Self { + let target_triple = env::var("TARGET").unwrap(); let target_features = env::var("CARGO_CFG_TARGET_FEATURE") .map(|feats| feats.split(',').map(ToOwned::to_owned).collect()) .unwrap_or_default(); @@ -28,7 +33,28 @@ impl Config { .map(|s| s.to_lowercase().replace("_", "-")) .collect(); + // Query rustc for options that Cargo does not provide env for. The bootstrap hack is used + // to get consistent output regardless of channel (`f16`/`f128` config options are hidden + // on stable otherwise). + let mut cmd = Command::new(env::var("RUSTC").unwrap()); + cmd.args(["--print=cfg", "--target", &target_triple]) + .env("RUSTC_BOOTSTRAP", "1") + .stderr(Stdio::inherit()); + let out = cmd + .output() + .unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}")); + let rustc_cfg = str::from_utf8(&out.stdout).unwrap(); + + // If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe + // choice and leave `f16` and `f128` disabled. + let rustc_output_ok = out.status.success(); + let reliable_f128 = + rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128"); + let reliable_f16 = + rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16"); + Self { + target_triple, manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()), out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()), opt_level: env::var("OPT_LEVEL").unwrap(), @@ -40,6 +66,8 @@ impl Config { target_string: env::var("TARGET").unwrap(), target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(), target_features, + reliable_f128, + reliable_f16, } } } @@ -128,62 +156,18 @@ fn emit_f16_f128_cfg(cfg: &Config) { return; } - // Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means - // that the backend will not crash when using these types and generates code that can be called - // without crashing (no infinite recursion). This does not mean that the platform doesn't have - // ABI or other bugs. - // - // We do this here rather than in `rust-lang/rust` because configuring via cargo features is - // not straightforward. - // - // Original source of this list: - // - let f16_enabled = match cfg.target_arch.as_str() { - // Unsupported - "arm64ec" => false, - // Selection failure - "s390x" => false, - // Infinite recursion - // FIXME(llvm): loongarch fixed by - "csky" => false, - "hexagon" => false, - "loongarch64" => false, - "mips" | "mips64" | "mips32r6" | "mips64r6" => false, - "powerpc" | "powerpc64" => false, - "sparc" | "sparc64" => false, - "wasm32" | "wasm64" => false, - // Most everything else works as of LLVM 19 - _ => true, - }; - - let f128_enabled = match cfg.target_arch.as_str() { - // Unsupported (libcall is not supported) - "amdgpu" => false, - // Unsupported - "arm64ec" => false, - // Selection failure - "mips64" | "mips64r6" => false, - // Selection failure - "nvptx64" => false, - // Selection failure - "powerpc64" if &cfg.target_os == "aix" => false, - // Selection failure - "sparc" => false, - // Most everything else works as of LLVM 19 - _ => true, - }; - - // If the feature is set, disable these types. - let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some(); + /* See the compiler-builtins configure file for info about the meaning of these options */ - println!("cargo:rustc-check-cfg=cfg(f16_enabled)"); - println!("cargo:rustc-check-cfg=cfg(f128_enabled)"); + // If the feature is set, disable both of these types. + let no_f16_f128 = cfg.cargo_features.iter().any(|s| s == "no-f16-f128"); - if f16_enabled && !disable_both { + println!("cargo:rustc-check-cfg=cfg(f16_enabled)"); + if cfg.reliable_f16 && !no_f16_f128 { println!("cargo:rustc-cfg=f16_enabled"); } - if f128_enabled && !disable_both { + println!("cargo:rustc-check-cfg=cfg(f128_enabled)"); + if cfg.reliable_f128 && !no_f16_f128 { println!("cargo:rustc-cfg=f128_enabled"); } } diff --git a/library/compiler-builtins/libm/src/math/support/big.rs b/library/compiler-builtins/libm/src/math/support/big.rs index 8a52d86cc9827..b7f1285424956 100644 --- a/library/compiler-builtins/libm/src/math/support/big.rs +++ b/library/compiler-builtins/libm/src/math/support/big.rs @@ -11,10 +11,10 @@ const U128_LO_MASK: u128 = u64::MAX as u128; /// A 256-bit unsigned integer represented as two 128-bit native-endian limbs. #[allow(non_camel_case_types)] -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)] pub struct u256 { - pub lo: u128, pub hi: u128, + pub lo: u128, } impl u256 { @@ -28,17 +28,17 @@ impl u256 { pub fn signed(self) -> i256 { i256 { lo: self.lo, - hi: self.hi, + hi: self.hi as i128, } } } /// A 256-bit signed integer represented as two 128-bit native-endian limbs. #[allow(non_camel_case_types)] -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)] pub struct i256 { + pub hi: i128, pub lo: u128, - pub hi: u128, } impl i256 { @@ -47,7 +47,7 @@ impl i256 { pub fn unsigned(self) -> u256 { u256 { lo: self.lo, - hi: self.hi, + hi: self.hi as u128, } } } @@ -73,17 +73,17 @@ impl MinInt for i256 { type Unsigned = u256; - const SIGNED: bool = false; + const SIGNED: bool = true; const BITS: u32 = 256; const ZERO: Self = Self { lo: 0, hi: 0 }; const ONE: Self = Self { lo: 1, hi: 0 }; const MIN: Self = Self { - lo: 0, - hi: 1 << 127, + lo: u128::MIN, + hi: i128::MIN, }; const MAX: Self = Self { lo: u128::MAX, - hi: u128::MAX >> 1, + hi: i128::MAX, }; } @@ -109,60 +109,86 @@ macro_rules! impl_common { } } - impl ops::Shl for $ty { + impl ops::Add for $ty { type Output = Self; - fn shl(self, _rhs: u32) -> Self::Output { - unimplemented!("only used to meet trait bounds") + fn add(self, rhs: Self) -> Self::Output { + let (lo, carry) = self.lo.overflowing_add(rhs.lo); + let (hi, of) = Int::carrying_add(self.hi, rhs.hi, carry); + debug_assert!(!of, "attempt to add with overflow"); + Self { lo, hi } } } - }; -} -impl_common!(i256); -impl_common!(u256); + impl ops::Sub for $ty { + type Output = Self; -impl ops::Add for u256 { - type Output = Self; + fn sub(self, rhs: Self) -> Self::Output { + let (lo, borrow) = self.lo.overflowing_sub(rhs.lo); + let (hi, of) = Int::borrowing_sub(self.hi, rhs.hi, borrow); + debug_assert!(!of, "attempt to subtract with overflow"); + Self { lo, hi } + } + } - fn add(self, rhs: Self) -> Self::Output { - let (lo, carry) = self.lo.overflowing_add(rhs.lo); - let hi = self.hi.wrapping_add(carry as u128).wrapping_add(rhs.hi); + impl ops::Shl for $ty { + type Output = Self; - Self { lo, hi } - } -} + fn shl(mut self, rhs: u32) -> Self::Output { + debug_assert!(rhs < Self::BITS, "attempt to shift left with overflow"); -impl ops::Shr for u256 { - type Output = Self; + let half_bits = Self::BITS / 2; + let low_mask = half_bits - 1; + let s = rhs & low_mask; - fn shr(mut self, rhs: u32) -> Self::Output { - debug_assert!(rhs < Self::BITS, "attempted to shift right with overflow"); - if rhs >= Self::BITS { - return Self::ZERO; - } + let lo = self.lo; + let hi = self.hi; - if rhs == 0 { - return self; - } + self.lo = lo << s; - if rhs < 128 { - self.lo >>= rhs; - self.lo |= self.hi << (128 - rhs); - } else { - self.lo = self.hi >> (rhs - 128); + if rhs & half_bits == 0 { + self.hi = (lo >> (low_mask ^ s) >> 1) as _; + self.hi |= hi << s; + } else { + self.hi = self.lo as _; + self.lo = 0; + } + self + } } - if rhs < 128 { - self.hi >>= rhs; - } else { - self.hi = 0; - } + impl ops::Shr for $ty { + type Output = Self; - self - } + fn shr(mut self, rhs: u32) -> Self::Output { + debug_assert!(rhs < Self::BITS, "attempt to shift right with overflow"); + + let half_bits = Self::BITS / 2; + let low_mask = half_bits - 1; + let s = rhs & low_mask; + + let lo = self.lo; + let hi = self.hi; + + self.hi = hi >> s; + + #[allow(unused_comparisons)] + if rhs & half_bits == 0 { + self.lo = (hi << (low_mask ^ s) << 1) as _; + self.lo |= lo >> s; + } else { + self.lo = self.hi as _; + self.hi = if hi < 0 { !0 } else { 0 }; + } + self + } + } + }; } +impl_common!(i256); +impl_common!(u256); + impl HInt for u128 { type D = u256; @@ -200,7 +226,7 @@ impl HInt for u128 { } fn widen_hi(self) -> Self::D { - self.widen() << ::BITS + u256 { lo: 0, hi: self } } } @@ -208,11 +234,10 @@ impl HInt for i128 { type D = i256; fn widen(self) -> Self::D { - let mut ret = self.unsigned().zero_widen().signed(); - if self.is_negative() { - ret.hi = u128::MAX; + i256 { + lo: self as u128, + hi: if self < 0 { -1 } else { 0 }, } - ret } fn zero_widen(self) -> Self::D { @@ -228,7 +253,7 @@ impl HInt for i128 { } fn widen_hi(self) -> Self::D { - self.widen() << ::BITS + i256 { lo: 0, hi: self } } } @@ -252,6 +277,6 @@ impl DInt for i256 { } fn hi(self) -> Self::H { - self.hi as i128 + self.hi } } diff --git a/library/compiler-builtins/libm/src/math/support/big/tests.rs b/library/compiler-builtins/libm/src/math/support/big/tests.rs index d2010f0216e35..d54706c726072 100644 --- a/library/compiler-builtins/libm/src/math/support/big/tests.rs +++ b/library/compiler-builtins/libm/src/math/support/big/tests.rs @@ -36,7 +36,7 @@ fn widen_i128() { (LOHI_SPLIT as i128).widen(), i256 { lo: LOHI_SPLIT, - hi: u128::MAX + hi: -1, } ); assert_eq!((-1i128).zero_widen().unsigned(), (u128::MAX).widen()); @@ -275,3 +275,64 @@ fn shr_u256_overflow() { assert_eq!(u256::MAX >> 257, u256::ZERO); assert_eq!(u256::MAX >> u32::MAX, u256::ZERO); } + +#[test] +fn u256_ord() { + let _1 = u256::ONE; + let _2 = _1 + _1; + for x in u8::MIN..u8::MAX { + let y = x + 1; + let wx = (x as u128).widen_hi(); + let wy = (y as u128).widen_hi(); + assert!([wx, wx + _1, wx + _2, wy, wy + _1, wy + _2].is_sorted()); + } +} +#[test] +fn i256_ord() { + let _1 = i256::ONE; + let _2 = _1 + _1; + for x in i8::MIN..i8::MAX { + let y = x + 1; + let wx = (x as i128).widen_hi(); + let wy = (y as i128).widen_hi(); + assert!([wx, wx + _1, wx + _2, wy - _2, wy - _1, wy].is_sorted()); + } +} + +#[test] +fn u256_shifts() { + let _1 = u256::ONE; + for k in 0..255 { + let x = _1 << k; + let x2 = _1 << (k + 1); + assert!(x < x2); + assert_eq!(x << 1, x2); + assert_eq!(x + x, x2); + assert_eq!(x >> k, _1); + assert_eq!(x2 >> (k + 1), _1); + } +} +#[test] +fn i256_shifts() { + let _1 = i256::ONE; + for k in 0..254 { + let x = _1 << k; + let x2 = _1 << (k + 1); + assert!(x < x2); + assert_eq!(x << 1, x2); + assert_eq!(x + x, x2); + assert_eq!(x >> k, _1); + assert_eq!(x2 >> (k + 1), _1); + } + + let min = _1 << 255; + assert_eq!(min, i256::MIN); + let mut x = min; + for k in 0..255 { + assert_eq!(x, min >> k); + let y = x >> 1; + assert_eq!(y + y, x); + assert!(x < y); + x = y; + } +} diff --git a/library/compiler-builtins/libm/src/math/support/int_traits.rs b/library/compiler-builtins/libm/src/math/support/int_traits.rs index 9b29e2f4561d5..9d8826dfed3fe 100644 --- a/library/compiler-builtins/libm/src/math/support/int_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs @@ -37,8 +37,6 @@ pub trait Int: + fmt::Display + fmt::Binary + fmt::LowerHex - + PartialEq - + PartialOrd + ops::AddAssign + ops::SubAssign + ops::MulAssign @@ -102,7 +100,10 @@ pub trait Int: fn rotate_left(self, other: u32) -> Self; fn overflowing_add(self, other: Self) -> (Self, bool); fn overflowing_sub(self, other: Self) -> (Self, bool); + fn carrying_add(self, other: Self, carry: bool) -> (Self, bool); + fn borrowing_sub(self, other: Self, borrow: bool) -> (Self, bool); fn leading_zeros(self) -> u32; + fn trailing_zeros(self) -> u32; fn ilog2(self) -> u32; } @@ -168,12 +169,30 @@ macro_rules! int_impl_common { ::leading_zeros(self) } + fn trailing_zeros(self) -> u32 { + ::trailing_zeros(self) + } + fn ilog2(self) -> u32 { // On our older MSRV, this resolves to the trait method. Which won't actually work, // but this is only called behind other gates. #[allow(clippy::incompatible_msrv)] ::ilog2(self) } + + fn carrying_add(self, other: Self, carry: bool) -> (Self, bool) { + let (ab, of1) = self.overflowing_add(other); + let (abc, of2) = ab.overflowing_add(Self::from_bool(carry)); + // `of1 && of2` is possible with signed integers if a negative sum + // overflows to `MAX` and adding the carry overflows again back to `MIN` + (abc, of1 ^ of2) + } + + fn borrowing_sub(self, other: Self, borrow: bool) -> (Self, bool) { + let (ab, of1) = self.overflowing_sub(other); + let (abc, of2) = ab.overflowing_sub(Self::from_bool(borrow)); + (abc, of1 ^ of2) + } }; } diff --git a/library/compiler-builtins/thumbv6m-linux-eabi.json b/library/compiler-builtins/thumbv6m-linux-eabi.json deleted file mode 100644 index ac736eae686b4..0000000000000 --- a/library/compiler-builtins/thumbv6m-linux-eabi.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "abi-blacklist": [ - "stdcall", - "fastcall", - "vectorcall", - "win64", - "sysv64" - ], - "arch": "arm", - "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", - "env": "", - "executables": true, - "features": "+strict-align", - "linker": "arm-none-eabi-gcc", - "linker-flavor": "gcc", - "llvm-target": "thumbv6m-none-eabi", - "max-atomic-width": 0, - "os": "linux", - "panic-strategy": "abort", - "pre-link-args": { - "gcc": ["-nostartfiles"] - }, - "relocation-model": "static", - "target-endian": "little", - "target-pointer-width": "32", - "target-c-int-width": "32", - "vendor": "" -} diff --git a/library/compiler-builtins/thumbv7em-linux-eabi.json b/library/compiler-builtins/thumbv7em-linux-eabi.json deleted file mode 100644 index b6d4a6bda7bac..0000000000000 --- a/library/compiler-builtins/thumbv7em-linux-eabi.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "abi-blacklist": [ - "stdcall", - "fastcall", - "vectorcall", - "win64", - "sysv64" - ], - "arch": "arm", - "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", - "env": "", - "executables": true, - "linker": "arm-none-eabi-gcc", - "linker-flavor": "gcc", - "llvm-target": "thumbv7em-none-eabi", - "max-atomic-width": 32, - "os": "linux", - "panic-strategy": "abort", - "pre-link-args": { - "gcc": ["-nostartfiles"] - }, - "relocation-model": "static", - "target-endian": "little", - "target-pointer-width": "32", - "target-c-int-width": "32", - "vendor": "" -} diff --git a/library/compiler-builtins/thumbv7em-linux-eabihf.json b/library/compiler-builtins/thumbv7em-linux-eabihf.json deleted file mode 100644 index 81cfcd48d56ce..0000000000000 --- a/library/compiler-builtins/thumbv7em-linux-eabihf.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "abi-blacklist": [ - "stdcall", - "fastcall", - "vectorcall", - "win64", - "sysv64" - ], - "arch": "arm", - "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", - "env": "", - "executables": true, - "features": "+vfp4,+d16,+fp-only-sp", - "linker": "arm-none-eabi-gcc", - "linker-flavor": "gcc", - "llvm-target": "thumbv7em-none-eabihf", - "max-atomic-width": 32, - "os": "linux", - "panic-strategy": "abort", - "pre-link-args": { - "gcc": ["-nostartfiles"] - }, - "relocation-model": "static", - "target-endian": "little", - "target-pointer-width": "32", - "target-c-int-width": "32", - "vendor": "" -} diff --git a/library/compiler-builtins/thumbv7m-linux-eabi.json b/library/compiler-builtins/thumbv7m-linux-eabi.json deleted file mode 100644 index abe037c5bef88..0000000000000 --- a/library/compiler-builtins/thumbv7m-linux-eabi.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "abi-blacklist": [ - "stdcall", - "fastcall", - "vectorcall", - "win64", - "sysv64" - ], - "arch": "arm", - "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64", - "env": "", - "executables": true, - "linker": "arm-none-eabi-gcc", - "linker-flavor": "gcc", - "llvm-target": "thumbv7m-none-eabi", - "max-atomic-width": 32, - "os": "linux", - "panic-strategy": "abort", - "pre-link-args": { - "gcc": ["-nostartfiles"] - }, - "relocation-model": "static", - "target-endian": "little", - "target-pointer-width": "32", - "target-c-int-width": "32", - "vendor": "" -} diff --git a/library/compiler-builtins/triagebot.toml b/library/compiler-builtins/triagebot.toml new file mode 100644 index 0000000000000..ecc05da019517 --- /dev/null +++ b/library/compiler-builtins/triagebot.toml @@ -0,0 +1,21 @@ +## See for documentation +## of these features. + +# Warns when a PR contains merge commits +# Documentation at: https://forge.rust-lang.org/triagebot/no-merge.html +[no-merges] +exclude_titles = ["Update from"] + +# Canonicalize issue numbers to avoid closing the wrong issue +# when commits are included in subtrees, as well as warning links in commits. +# Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html +[issue-links] +check-commits = false + +# Prevents mentions in commits to avoid users being spammed +# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html +[no-mentions] + +# Enable issue transfers within the org +# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html +[transfer] diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index 44afa4f1fbcf4..e676e88f4d4d8 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -26,8 +26,6 @@ optimize_for_size = [] # Make `RefCell` store additional debugging information, which is printed out when # a borrow error occurs debug_refcell = [] -# Make `TypeId` store a reference to the name of the type, so that it can print that name. -debug_typeid = [] [lints.rust.unexpected_cfgs] level = "warn" diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 01dce114592a1..39cdf6efda07a 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -707,19 +707,52 @@ impl dyn Any + Send + Sync { /// ``` #[derive(Clone, Copy, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] +#[lang = "type_id"] pub struct TypeId { - // We avoid using `u128` because that imposes higher alignment requirements on many platforms. - // See issue #115620 for more information. - t: (u64, u64), - #[cfg(feature = "debug_typeid")] - name: &'static str, + /// This needs to be an array of pointers, since there is provenance + /// in the first array field. This provenance knows exactly which type + /// the TypeId actually is, allowing CTFE and miri to operate based off it. + /// At runtime all the pointers in the array contain bits of the hash, making + /// the entire `TypeId` actually just be a `u128` hash of the type. + pub(crate) data: [*const (); 16 / size_of::<*const ()>()], } +// SAFETY: the raw pointer is always an integer #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for TypeId { +unsafe impl Send for TypeId {} +// SAFETY: the raw pointer is always an integer +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl Sync for TypeId {} + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_type_id", issue = "77125")] +impl const PartialEq for TypeId { #[inline] fn eq(&self, other: &Self) -> bool { - self.t == other.t + #[cfg(miri)] + return crate::intrinsics::type_id_eq(*self, *other); + #[cfg(not(miri))] + { + let this = self; + crate::intrinsics::const_eval_select!( + @capture { this: &TypeId, other: &TypeId } -> bool: + if const { + crate::intrinsics::type_id_eq(*this, *other) + } else { + // Ideally we would just invoke `type_id_eq` unconditionally here, + // but since we do not MIR inline intrinsics, because backends + // may want to override them (and miri does!), MIR opts do not + // clean up this call sufficiently for LLVM to turn repeated calls + // of `TypeId` comparisons against one specific `TypeId` into + // a lookup table. + // SAFETY: We know that at runtime none of the bits have provenance and all bits + // are initialized. So we can just convert the whole thing to a `u128` and compare that. + unsafe { + crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other) + } + } + ) + } } } @@ -742,19 +775,19 @@ impl TypeId { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] pub const fn of() -> TypeId { - let t: u128 = const { intrinsics::type_id::() }; - let t1 = (t >> 64) as u64; - let t2 = t as u64; - - TypeId { - t: (t1, t2), - #[cfg(feature = "debug_typeid")] - name: type_name::(), - } + const { intrinsics::type_id::() } } fn as_u128(self) -> u128 { - u128::from(self.t.0) << 64 | u128::from(self.t.1) + let mut bytes = [0; 16]; + + // This is a provenance-stripping memcpy. + for (i, chunk) in self.data.iter().copied().enumerate() { + let chunk = chunk.expose_provenance().to_ne_bytes(); + let start = i * chunk.len(); + bytes[start..(start + chunk.len())].copy_from_slice(&chunk); + } + u128::from_ne_bytes(bytes) } } @@ -774,22 +807,19 @@ impl hash::Hash for TypeId { // - It is correct to do so -- only hashing a subset of `self` is still // compatible with an `Eq` implementation that considers the entire // value, as ours does. - self.t.1.hash(state); + let data = + // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`. + // Only the first ptr-sized chunk ever has provenance, so that second half is always + // fine to read at integer type. + unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::().offset(1)) }; + data.hash(state); } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for TypeId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - #[cfg(feature = "debug_typeid")] - { - write!(f, "TypeId({:#034x} = {})", self.as_u128(), self.name)?; - } - #[cfg(not(feature = "debug_typeid"))] - { - write!(f, "TypeId({:#034x})", self.as_u128())?; - } - Ok(()) + write!(f, "TypeId({:#034x})", self.as_u128()) } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index b1ca3701fa5ae..03b120fbf0c34 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -248,7 +248,7 @@ use crate::ops::ControlFlow; )] #[rustc_diagnostic_item = "PartialEq"] #[const_trait] -#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] pub trait PartialEq: PointeeSized { /// Tests for `self` and `other` values to be equal, and is used by `==`. #[must_use] @@ -1809,7 +1809,7 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq for $t { #[inline] fn eq(&self, other: &Self) -> bool { *self == *other } @@ -2017,7 +2017,7 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq<&B> for &A where A: ~const PartialEq, @@ -2089,7 +2089,7 @@ mod impls { // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq<&mut B> for &mut A where A: ~const PartialEq, @@ -2159,7 +2159,7 @@ mod impls { impl Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq<&mut B> for &A where A: ~const PartialEq, @@ -2175,7 +2175,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] + #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const PartialEq<&B> for &mut A where A: ~const PartialEq, diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 7132e712ec52f..38381dbdf2303 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -445,6 +445,8 @@ pub trait AsMut: PointeeSized { #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait Into: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -580,6 +582,8 @@ pub trait Into: Sized { note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait From: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] @@ -607,6 +611,8 @@ pub trait From: Sized { /// [`Into`], see there for details. #[rustc_diagnostic_item = "TryInto"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryInto: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -685,6 +691,8 @@ pub trait TryInto: Sized { /// [`try_from`]: TryFrom::try_from #[rustc_diagnostic_item = "TryFrom"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -754,9 +762,10 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -impl Into for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl const Into for T where - U: From, + U: ~const From, { /// Calls `U::from(self)`. /// @@ -771,7 +780,8 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -impl From for T { +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl const From for T { /// Returns the argument unchanged. #[inline(always)] fn from(t: T) -> T { @@ -787,7 +797,8 @@ impl From for T { #[stable(feature = "convert_infallible", since = "1.34.0")] #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl From for T` later; see rust-lang/rust#64715 for details"] -impl From for T { +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl const From for T { fn from(t: !) -> T { t } @@ -795,9 +806,10 @@ impl From for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -impl TryInto for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl const TryInto for T where - U: TryFrom, + U: ~const TryFrom, { type Error = U::Error; @@ -810,9 +822,10 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -impl TryFrom for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl const TryFrom for T where - U: Into, + U: ~const Into, { type Error = Infallible; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index d9da32707298c..15295a3cdf738 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2285,7 +2285,7 @@ pub const fn const_eval_select( ) -> RET where G: FnOnce, - F: FnOnce; + F: const FnOnce; /// A macro to make it easier to invoke const_eval_select. Use as follows: /// ```rust,ignore (just a macro example) @@ -2749,7 +2749,20 @@ pub const fn type_name() -> &'static str; #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] -pub const fn type_id() -> u128; +pub const fn type_id() -> crate::any::TypeId; + +/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the +/// same type. This is necessary because at const-eval time the actual discriminating +/// data is opaque and cannot be inspected directly. +/// +/// The stabilized version of this intrinsic is the [PartialEq] impl for [`core::any::TypeId`]. +#[rustc_nounwind] +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_intrinsic] +#[rustc_do_not_const_check] +pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool { + a.data == b.data +} /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`. /// diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 8035dccc632d4..6b9cbb0643586 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -230,32 +230,16 @@ pub macro assert_matches { /// ``` /// #![feature(cfg_select)] /// -/// let _some_string = cfg_select! {{ +/// let _some_string = cfg_select! { /// unix => { "With great power comes great electricity bills" } /// _ => { "Behind every successful diet is an unwatched pizza" } -/// }}; +/// }; /// ``` #[unstable(feature = "cfg_select", issue = "115585")] #[rustc_diagnostic_item = "cfg_select"] -#[rustc_macro_transparency = "semitransparent"] -pub macro cfg_select { - ({ $($tt:tt)* }) => {{ - $crate::cfg_select! { $($tt)* } - }}, - (_ => { $($output:tt)* }) => { - $($output)* - }, - ( - $cfg:meta => $output:tt - $($( $rest:tt )+)? - ) => { - #[cfg($cfg)] - $crate::cfg_select! { _ => $output } - $( - #[cfg(not($cfg))] - $crate::cfg_select! { $($rest)+ } - )? - }, +#[rustc_builtin_macro] +pub macro cfg_select($($tt:tt)*) { + /* compiler built-in */ } /// Asserts that a boolean expression is `true` at runtime. diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 1c0629f259db2..6531d3ec766a9 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -210,6 +210,11 @@ pub trait PointeeSized { /// - `Trait` is dyn-compatible[^1]. /// - The type is sized. /// - The type outlives `'a`. +/// - Trait objects `dyn TraitA + AutoA... + 'a` implement `Unsize` +/// if all of these conditions are met: +/// - `TraitB` is a supertrait of `TraitA`. +/// - `AutoB...` is a subset of `AutoA...`. +/// - `'a` outlives `'b`. /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize>` /// where any number of (type and const) parameters may be changed if all of these conditions /// are met: diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 889d394793f64..8fb1010fd2014 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -153,7 +153,7 @@ pub const fn forget(t: T) { /// /// While Rust does not permit unsized locals since its removal in [#111942] it is /// still possible to call functions with unsized values from a function argument -/// or in-place construction. +/// or place expression. /// /// ```rust /// #![feature(unsized_fn_params, forget_unsized)] diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index a5242d60bf14d..f9c4cdd0ebe63 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -45,8 +45,11 @@ impl From for TryFromIntError { /// An error which can be returned when parsing an integer. /// -/// This error is used as the error type for the `from_str_radix()` functions -/// on the primitive integer types, such as [`i8::from_str_radix`]. +/// For example, this error is returned by the `from_str_radix()` functions +/// on the primitive integer types (such as [`i8::from_str_radix`]) +/// and is used as the error type in their [`FromStr`] implementations. +/// +/// [`FromStr`]: crate::str::FromStr /// /// # Potential causes /// diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index e53c128efe069..7d44b1733b9c6 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -65,7 +65,7 @@ /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[rustc_on_unimplemented( on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",), on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",), @@ -96,7 +96,7 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Add for $t { type Output = $t; @@ -179,7 +179,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[rustc_on_unimplemented( message = "cannot subtract `{Rhs}` from `{Self}`", label = "no implementation for `{Self} - {Rhs}`", @@ -208,7 +208,7 @@ pub trait Sub { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Sub for $t { type Output = $t; @@ -313,7 +313,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot multiply `{Self}` by `{Rhs}`", label = "no implementation for `{Self} * {Rhs}`" @@ -341,7 +341,7 @@ pub trait Mul { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Mul for $t { type Output = $t; @@ -450,7 +450,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 /// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot divide `{Self}` by `{Rhs}`", label = "no implementation for `{Self} / {Rhs}`" @@ -484,7 +484,7 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Div for $t { type Output = $t; @@ -505,7 +505,7 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Div for $t { type Output = $t; @@ -556,7 +556,7 @@ div_impl_float! { f16 f32 f64 f128 } /// ``` #[lang = "rem"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] +#[rustc_const_unstable(feature = "const_ops", issue = "143802")] #[diagnostic::on_unimplemented( message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`", label = "no implementation for `{Self} % {Rhs}`" @@ -590,7 +590,7 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Rem for $t { type Output = $t; @@ -626,7 +626,7 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + #[rustc_const_unstable(feature = "const_ops", issue = "143802")] impl const Rem for $t { type Output = $t; diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index df48c104410ca..763b60d88e510 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -72,7 +72,8 @@ use crate::marker::Tuple; )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -// FIXME(const_trait_impl) #[const_trait] +#[const_trait] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] pub trait Fn: FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -159,7 +160,8 @@ pub trait Fn: FnMut { )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -// FIXME(const_trait_impl) #[const_trait] +#[const_trait] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] pub trait FnMut: FnOnce { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] @@ -238,7 +240,8 @@ pub trait FnMut: FnOnce { )] #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] -// FIXME(const_trait_impl) #[const_trait] +#[const_trait] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] pub trait FnOnce { /// The returned type after the call operator is used. #[lang = "fn_once_output"] @@ -254,9 +257,10 @@ mod impls { use crate::marker::Tuple; #[stable(feature = "rust1", since = "1.0.0")] - impl Fn for &F + #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] + impl const Fn for &F where - F: Fn, + F: ~const Fn, { extern "rust-call" fn call(&self, args: A) -> F::Output { (**self).call(args) @@ -264,9 +268,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnMut for &F + #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] + impl const FnMut for &F where - F: Fn, + F: ~const Fn, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (**self).call(args) @@ -274,9 +279,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnOnce for &F + #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] + impl const FnOnce for &F where - F: Fn, + F: ~const Fn, { type Output = F::Output; @@ -286,9 +292,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnMut for &mut F + #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] + impl const FnMut for &mut F where - F: FnMut, + F: ~const FnMut, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (*self).call_mut(args) @@ -296,9 +303,10 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl FnOnce for &mut F + #[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")] + impl const FnOnce for &mut F where - F: FnMut, + F: ~const FnMut, { type Output = F::Output; extern "rust-call" fn call_once(self, args: A) -> F::Output { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 479fe0f1554de..58b7e9a9fdf4a 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1120,6 +1120,9 @@ impl [T] { /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the /// slice. /// + /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1137,6 +1140,7 @@ impl [T] { /// /// [`chunks_exact`]: slice::chunks_exact /// [`rchunks`]: slice::rchunks + /// [`as_chunks`]: slice::as_chunks #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1156,6 +1160,9 @@ impl [T] { /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at /// the end of the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1177,6 +1184,7 @@ impl [T] { /// /// [`chunks_exact_mut`]: slice::chunks_exact_mut /// [`rchunks_mut`]: slice::rchunks_mut + /// [`as_chunks_mut`]: slice::as_chunks_mut #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1199,6 +1207,9 @@ impl [T] { /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1216,6 +1227,7 @@ impl [T] { /// /// [`chunks`]: slice::chunks /// [`rchunks_exact`]: slice::rchunks_exact + /// [`as_chunks`]: slice::chunks #[stable(feature = "chunks_exact", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1239,6 +1251,9 @@ impl [T] { /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of /// the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1260,6 +1275,7 @@ impl [T] { /// /// [`chunks_mut`]: slice::chunks_mut /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut + /// [`as_chunks_mut`]: slice::as_chunks_mut #[stable(feature = "chunks_exact", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1707,6 +1723,9 @@ impl [T] { /// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning /// of the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1724,6 +1743,7 @@ impl [T] { /// /// [`rchunks_exact`]: slice::rchunks_exact /// [`chunks`]: slice::chunks + /// [`as_rchunks`]: slice::as_rchunks #[stable(feature = "rchunks", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1743,6 +1763,9 @@ impl [T] { /// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the /// beginning of the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1764,6 +1787,7 @@ impl [T] { /// /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut /// [`chunks_mut`]: slice::chunks_mut + /// [`as_rchunks_mut`]: slice::as_rchunks_mut #[stable(feature = "rchunks", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1787,6 +1811,9 @@ impl [T] { /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the /// slice. /// + /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1805,6 +1832,7 @@ impl [T] { /// [`chunks`]: slice::chunks /// [`rchunks`]: slice::rchunks /// [`chunks_exact`]: slice::chunks_exact + /// [`as_rchunks`]: slice::as_rchunks #[stable(feature = "rchunks", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -1828,6 +1856,9 @@ impl [T] { /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning /// of the slice. /// + /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will + /// give references to arrays of exactly that length, rather than slices. + /// /// # Panics /// /// Panics if `chunk_size` is zero. @@ -1850,6 +1881,7 @@ impl [T] { /// [`chunks_mut`]: slice::chunks_mut /// [`rchunks_mut`]: slice::rchunks_mut /// [`chunks_exact_mut`]: slice::chunks_exact_mut + /// [`as_rchunks_mut`]: slice::as_rchunks_mut #[stable(feature = "rchunks", since = "1.31.0")] #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")] #[inline] @@ -3668,7 +3700,8 @@ impl [T] { /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']); /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] - pub fn rotate_left(&mut self, mid: usize) { + #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")] + pub const fn rotate_left(&mut self, mid: usize) { assert!(mid <= self.len()); let k = self.len() - mid; let p = self.as_mut_ptr(); @@ -3713,7 +3746,8 @@ impl [T] { /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']); /// ``` #[stable(feature = "slice_rotate", since = "1.26.0")] - pub fn rotate_right(&mut self, k: usize) { + #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")] + pub const fn rotate_right(&mut self, k: usize) { assert!(k <= self.len()); let mid = self.len() - k; let p = self.as_mut_ptr(); diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index 80178f297eaae..b3b64422884d5 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -1,5 +1,5 @@ use crate::mem::{MaybeUninit, SizedTypeProperties}; -use crate::{cmp, ptr}; +use crate::ptr; type BufType = [usize; 32]; @@ -11,7 +11,7 @@ type BufType = [usize; 32]; /// /// The specified range must be valid for reading and writing. #[inline] -pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { +pub(super) const unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { if T::IS_ZST { return; } @@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { } // `T` is not a zero-sized type, so it's okay to divide by its size. if !cfg!(feature = "optimize_for_size") - && cmp::min(left, right) <= size_of::() / size_of::() + // FIXME(const-hack): Use cmp::min when available in const + && const_min(left, right) <= size_of::() / size_of::() { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_memmove(left, mid, right) }; @@ -45,7 +46,7 @@ pub(super) unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { +const unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { // The `[T; 0]` here is to ensure this is appropriately aligned for T let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit(); let buf = rawarray.as_mut_ptr() as *mut T; @@ -117,7 +118,7 @@ unsafe fn ptr_rotate_memmove(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { +const unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { // Algorithm 2 // Microbenchmarks indicate that the average performance for random shifts is better all // the way until about `left + right == 32`, but the worst case performance breaks even @@ -175,7 +176,9 @@ unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { } } // finish the chunk with more rounds - for start in 1..gcd { + // FIXME(const-hack): Use `for start in 1..gcd` when available in const + let mut start = 1; + while start < gcd { // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for // reading and writing as per the function's safety contract, see [long-safety-expl] // above @@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { i += right; } } + + start += 1; } } @@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd(left: usize, mid: *mut T, right: usize) { /// /// The specified range must be valid for reading and writing. #[inline] -unsafe fn ptr_rotate_swap(mut left: usize, mut mid: *mut T, mut right: usize) { +const unsafe fn ptr_rotate_swap(mut left: usize, mut mid: *mut T, mut right: usize) { loop { if left >= right { // Algorithm 3 @@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap(mut left: usize, mut mid: *mut T, mut right: usize) } } } + +// FIXME(const-hack): Use cmp::min when available in const +const fn const_min(left: usize, right: usize) -> usize { + if right < left { right } else { left } +} diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 25b9c6e0e0e94..b57234bbee9a2 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -82,7 +82,7 @@ unsafe fn skip_search( let needle = needle as u32; let last_idx = - match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) { + match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) { Ok(idx) => idx + 1, Err(idx) => idx, }; diff --git a/library/coretests/tests/any.rs b/library/coretests/tests/any.rs index 117ef0042380d..25002617d0bbd 100644 --- a/library/coretests/tests/any.rs +++ b/library/coretests/tests/any.rs @@ -118,14 +118,6 @@ fn any_unsized() { is_any::<[i32]>(); } -#[cfg(feature = "debug_typeid")] -#[test] -fn debug_typeid_includes_name() { - let type_id = TypeId::of::<[usize; 2]>(); - let debug_str = format!("{type_id:?}"); - assert!(debug_str.ends_with("= [usize; 2])"), "{debug_str:?} did not match"); -} - #[test] fn distinct_type_names() { // https://github.com/rust-lang/rust/issues/84666 diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs index cf78e8796a030..38df09a91c103 100644 --- a/library/coretests/tests/floats/f128.rs +++ b/library/coretests/tests/floats/f128.rs @@ -55,20 +55,6 @@ fn test_num_f128() { // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -fn test_nan() { - let nan: f128 = f128::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert!(!nan.is_normal()); - assert_eq!(Fp::Nan, nan.classify()); - // Ensure the quiet bit is set. - assert!(nan.to_bits() & (1 << (f128::MANTISSA_DIGITS - 2)) != 0); -} - #[test] fn test_infinity() { let inf: f128 = f128::INFINITY; diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs index 9e91b654304b6..f6749d796cca9 100644 --- a/library/coretests/tests/floats/f16.rs +++ b/library/coretests/tests/floats/f16.rs @@ -51,20 +51,6 @@ fn test_num_f16() { // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -fn test_nan() { - let nan: f16 = f16::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert!(!nan.is_normal()); - assert_eq!(Fp::Nan, nan.classify()); - // Ensure the quiet bit is set. - assert!(nan.to_bits() & (1 << (f16::MANTISSA_DIGITS - 2)) != 0); -} - #[test] fn test_infinity() { let inf: f16 = f16::INFINITY; diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs index d2724d12e3927..f5d5723fea455 100644 --- a/library/coretests/tests/floats/f32.rs +++ b/library/coretests/tests/floats/f32.rs @@ -35,20 +35,6 @@ fn test_num_f32() { super::test_num(10f32, 2f32); } -#[test] -fn test_nan() { - let nan: f32 = f32::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(!nan.is_normal()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert_eq!(Fp::Nan, nan.classify()); - // Ensure the quiet bit is set. - assert!(nan.to_bits() & (1 << (f32::MANTISSA_DIGITS - 2)) != 0); -} - #[test] fn test_infinity() { let inf: f32 = f32::INFINITY; diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs index b2b2393a5279c..34af87c241e91 100644 --- a/library/coretests/tests/floats/f64.rs +++ b/library/coretests/tests/floats/f64.rs @@ -30,20 +30,6 @@ fn test_num_f64() { super::test_num(10f64, 2f64); } -#[test] -fn test_nan() { - let nan: f64 = f64::NAN; - assert!(nan.is_nan()); - assert!(!nan.is_infinite()); - assert!(!nan.is_finite()); - assert!(!nan.is_normal()); - assert!(nan.is_sign_positive()); - assert!(!nan.is_sign_negative()); - assert_eq!(Fp::Nan, nan.classify()); - // Ensure the quiet bit is set. - assert!(nan.to_bits() & (1 << (f64::MANTISSA_DIGITS - 2)) != 0); -} - #[test] fn test_infinity() { let inf: f64 = f64::INFINITY; diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index 6b4f586fa9b6b..36743a7d6df9e 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::num::FpCategory as Fp; use std::ops::{Add, Div, Mul, Rem, Sub}; /// Set the default tolerance for float comparison based on the type. @@ -187,6 +188,8 @@ macro_rules! float_test { mod const_ { #[allow(unused)] use super::Approx; + #[allow(unused)] + use std::num::FpCategory as Fp; // Shadow the runtime versions of the macro with const-compatible versions. #[allow(unused)] use $crate::floats::{ @@ -250,6 +253,26 @@ mod f16; mod f32; mod f64; +float_test! { + name: nan, + attrs: { + f16: #[cfg(any(miri, target_has_reliable_f16))], + f128: #[cfg(any(miri, target_has_reliable_f128))], + }, + test { + let nan: Float = Float::NAN; + assert!(nan.is_nan()); + assert!(!nan.is_infinite()); + assert!(!nan.is_finite()); + assert!(!nan.is_normal()); + assert!(nan.is_sign_positive()); + assert!(!nan.is_sign_negative()); + assert!(matches!(nan.classify(), Fp::Nan)); + // Ensure the quiet bit is set. + assert!(nan.to_bits() & (1 << (Float::MANTISSA_DIGITS - 2)) != 0); + } +} + float_test! { name: min, attrs: { diff --git a/library/coretests/tests/macros.rs b/library/coretests/tests/macros.rs index d220e628d7339..1c6aa90dfbca2 100644 --- a/library/coretests/tests/macros.rs +++ b/library/coretests/tests/macros.rs @@ -48,11 +48,12 @@ fn matches_leading_pipe() { fn cfg_select_basic() { cfg_select! { target_pointer_width = "64" => { fn f0_() -> bool { true }} + _ => {} } cfg_select! { unix => { fn f1_() -> bool { true } } - any(target_os = "macos", target_os = "linux") => { fn f1_() -> bool { false }} + _ => { fn f1_() -> bool { false }} } cfg_select! { @@ -70,6 +71,8 @@ fn cfg_select_basic() { #[cfg(unix)] assert!(f1_()); + #[cfg(not(unix))] + assert!(!f1_()); #[cfg(target_pointer_width = "32")] assert!(!f2_()); @@ -183,6 +186,12 @@ fn _accepts_expressions() -> i32 { } } +fn _accepts_only_wildcard() -> i32 { + cfg_select! { + _ => { 1 } + } +} + // The current implementation expands to a macro call, which allows the use of expression // statements. fn _allows_stmt_expr_attributes() { @@ -195,12 +204,12 @@ fn _allows_stmt_expr_attributes() { } fn _expression() { - let _ = cfg_select!({ + let _ = cfg_select!( windows => { " XP" } _ => { "" } - }); + ); } diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 003ac4f0cd37f..668e988abff39 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -61,6 +61,7 @@ struct Exception { // and its destructor is executed by the C++ runtime. When we take the Box // out of the exception, we need to leave the exception in a valid state // for its destructor to run without double-dropping the Box. + // We also construct this as None for copies of the exception. data: Option>, } @@ -264,7 +265,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // runtime under a try/catch block and the panic that we generate here will be // used as the result of the exception copy. This is used by the C++ runtime to // support capturing exceptions with std::exception_ptr, which we can't support -// because Box isn't clonable. +// because Box isn't clonable. Thus we throw an exception without data, +// which the C++ runtime will attempt to copy, which will once again fail, and +// a std::bad_exception instance ends up in the std::exception_ptr instance. +// The lack of data doesn't matter because the exception will never be rethrown +// - it is purely used to signal to the C++ runtime that copying failed. macro_rules! define_cleanup { ($abi:tt $abi2:tt) => { unsafe extern $abi fn exception_cleanup(e: *mut Exception) { @@ -278,7 +283,9 @@ macro_rules! define_cleanup { unsafe extern $abi2 fn exception_copy( _dest: *mut Exception, _src: *mut Exception ) -> *mut Exception { - panic!("Rust panics cannot be copied"); + unsafe { + throw_exception(None); + } } } } @@ -291,6 +298,10 @@ cfg_if::cfg_if! { } pub(crate) unsafe fn panic(data: Box) -> u32 { + unsafe { throw_exception(Some(data)) } +} + +unsafe fn throw_exception(data: Option>) -> ! { use core::intrinsics::{AtomicOrdering, atomic_store}; // _CxxThrowException executes entirely on this stack frame, so there's no @@ -300,8 +311,7 @@ pub(crate) unsafe fn panic(data: Box) -> u32 { // The ManuallyDrop is needed here since we don't want Exception to be // dropped when unwinding. Instead it will be dropped by exception_cleanup // which is invoked by the C++ runtime. - let mut exception = - ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) }); + let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data }); let throw_ptr = (&raw mut exception) as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 6a1cecd69fb5f..57ca7db9fcdd7 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -33,7 +33,7 @@ impl Symbol { /// Validates and normalizes before converting it to a symbol. pub(crate) fn new_ident(string: &str, is_raw: bool) -> Self { // Fast-path: check if this is a valid ASCII identifier - if Self::is_valid_ascii_ident(string.as_bytes()) { + if Self::is_valid_ascii_ident(string.as_bytes()) || string == "$crate" { if is_raw && !Self::can_be_raw(string) { panic!("`{}` cannot be a raw identifier", string); } @@ -79,7 +79,7 @@ impl Symbol { // Mimics the behavior of `Symbol::can_be_raw` from `rustc_span` fn can_be_raw(string: &str) -> bool { match string { - "_" | "super" | "self" | "Self" | "crate" => false, + "_" | "super" | "self" | "Self" | "crate" | "$crate" => false, _ => true, } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index e941eb577a47c..7a20d8bc919e7 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -114,8 +114,6 @@ optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"] # Make `RefCell` store additional debugging information, which is printed out when # a borrow error occurs debug_refcell = ["core/debug_refcell"] -# Make `TypeId` store a reference to the name of the type, so that it can print that name. -debug_typeid = ["core/debug_typeid"] # Enable std_detect default features for stdarch/crates/std_detect: diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 466b134d8faee..76e63a69e45da 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -210,6 +210,9 @@ pub trait CommandExt: Sealed { /// intentional difference from the underlying `chroot` system call.) #[unstable(feature = "process_chroot", issue = "141298")] fn chroot>(&mut self, dir: P) -> &mut process::Command; + + #[unstable(feature = "process_setsid", issue = "105376")] + fn setsid(&mut self, setsid: bool) -> &mut process::Command; } #[stable(feature = "rust1", since = "1.0.0")] @@ -260,6 +263,11 @@ impl CommandExt for process::Command { self.as_inner_mut().chroot(dir.as_ref()); self } + + fn setsid(&mut self, setsid: bool) -> &mut process::Command { + self.as_inner_mut().setsid(setsid); + self + } } /// Unix-specific extensions to [`process::ExitStatus`] and diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index dc278274f00f4..b310db2dac485 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1491,7 +1491,6 @@ impl File { target_os = "redox", target_os = "espidf", target_os = "horizon", - target_os = "vxworks", target_os = "nuttx", )))] let to_timespec = |time: Option| match time { diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 6835ba44ee242..884cbd4ac1dc7 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -1,37 +1,54 @@ use crate::fmt; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; +use crate::sync::{Arc, Mutex}; use crate::sys::unsupported; use crate::time::Duration; mod tcp; pub(crate) mod tcp4; -pub struct TcpStream(tcp::Tcp); +pub struct TcpStream { + inner: tcp::Tcp, + read_timeout: Arc>>, + write_timeout: Arc>>, +} impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result { - tcp::Tcp::connect(addr?).map(Self) + let inner = tcp::Tcp::connect(addr?, None)?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { - unsupported() + pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { + let inner = tcp::Tcp::connect(addr, Some(timeout))?; + Ok(Self { + inner, + read_timeout: Arc::new(Mutex::new(None)), + write_timeout: Arc::new(Mutex::new(None)), + }) } - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_read_timeout(&self, t: Option) -> io::Result<()> { + self.read_timeout.set(t).unwrap(); + Ok(()) } - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - unsupported() + pub fn set_write_timeout(&self, t: Option) -> io::Result<()> { + self.write_timeout.set(t).unwrap(); + Ok(()) } pub fn read_timeout(&self) -> io::Result> { - unsupported() + Ok(self.read_timeout.get_cloned().unwrap()) } pub fn write_timeout(&self) -> io::Result> { - unsupported() + Ok(self.write_timeout.get_cloned().unwrap()) } pub fn peek(&self, _: &mut [u8]) -> io::Result { @@ -39,7 +56,7 @@ impl TcpStream { } pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.0.read(buf) + self.inner.read(buf, self.read_timeout()?) } pub fn read_buf(&self, cursor: BorrowedCursor<'_>) -> io::Result<()> { @@ -56,7 +73,7 @@ impl TcpStream { } pub fn write(&self, buf: &[u8]) -> io::Result { - self.0.write(buf) + self.inner.write(buf, self.write_timeout()?) } pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 55b6dbf2490bd..1152f69446e42 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -1,33 +1,34 @@ use super::tcp4; use crate::io; use crate::net::SocketAddr; +use crate::time::Duration; pub(crate) enum Tcp { V4(tcp4::Tcp4), } impl Tcp { - pub(crate) fn connect(addr: &SocketAddr) -> io::Result { + pub(crate) fn connect(addr: &SocketAddr, timeout: Option) -> io::Result { match addr { SocketAddr::V4(x) => { let temp = tcp4::Tcp4::new()?; temp.configure(true, Some(x), None)?; - temp.connect()?; + temp.connect(timeout)?; Ok(Tcp::V4(temp)) } SocketAddr::V6(_) => todo!(), } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.write(buf), + Self::V4(client) => client.write(buf, timeout), } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { match self { - Self::V4(client) => client.read(buf), + Self::V4(client) => client.read(buf, timeout), } } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index af1ba2be47adb..6342718929a7d 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -6,6 +6,7 @@ use crate::net::SocketAddrV4; use crate::ptr::NonNull; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::pal::helpers; +use crate::time::{Duration, Instant}; const TYPE_OF_SERVICE: u8 = 8; const TIME_TO_LIVE: u8 = 255; @@ -66,7 +67,7 @@ impl Tcp4 { if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } - pub(crate) fn connect(&self) -> io::Result<()> { + pub(crate) fn connect(&self, timeout: Option) -> io::Result<()> { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -79,7 +80,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut conn_token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -88,7 +89,7 @@ impl Tcp4 { } } - pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + pub(crate) fn write(&self, buf: &[u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -119,7 +120,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -128,7 +129,7 @@ impl Tcp4 { } } - pub(crate) fn read(&self, buf: &mut [u8]) -> io::Result { + pub(crate) fn read(&self, buf: &mut [u8], timeout: Option) -> io::Result { let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -158,7 +159,7 @@ impl Tcp4 { return Err(io::Error::from_raw_os_error(r.as_usize())); } - self.wait_for_flag(); + unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) @@ -167,6 +168,50 @@ impl Tcp4 { } } + /// Wait for an event to finish. This is checked by an atomic boolean that is supposed to be set + /// to true in the event callback. + /// + /// Optionally, allow specifying a timeout. + /// + /// If a timeout is provided, the operation (specified by its `EFI_TCP4_COMPLETION_TOKEN`) is + /// canceled and Error of kind TimedOut is returned. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` + unsafe fn wait_or_cancel( + &self, + timeout: Option, + token: *mut tcp4::CompletionToken, + ) -> io::Result<()> { + if !self.wait_for_flag(timeout) { + let _ = unsafe { self.cancel(token) }; + return Err(io::Error::new(io::ErrorKind::TimedOut, "Operation Timed out")); + } + + Ok(()) + } + + /// Abort an asynchronous connection, listen, transmission or receive request. + /// + /// If token is NULL, then all pending tokens issued by EFI_TCP4_PROTOCOL.Connect(), + /// EFI_TCP4_PROTOCOL.Accept(), EFI_TCP4_PROTOCOL.Transmit() or EFI_TCP4_PROTOCOL.Receive() are + /// aborted. + /// + /// # SAFETY + /// + /// Pointer to a valid `EFI_TCP4_COMPLETION_TOKEN` or NULL + unsafe fn cancel(&self, token: *mut tcp4::CompletionToken) -> io::Result<()> { + let protocol = self.protocol.as_ptr(); + + let r = unsafe { ((*protocol).cancel)(protocol, token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } else { + Ok(()) + } + } + unsafe fn create_evt(&self) -> io::Result { self.flag.store(false, Ordering::Relaxed); helpers::OwnedEvent::new( @@ -177,10 +222,19 @@ impl Tcp4 { ) } - fn wait_for_flag(&self) { + fn wait_for_flag(&self, timeout: Option) -> bool { + let start = Instant::now(); + while !self.flag.load(Ordering::Relaxed) { let _ = self.poll(); + if let Some(t) = timeout { + if Instant::now().duration_since(start) >= t { + return false; + } + } } + + true } fn poll(&self) -> io::Result<()> { diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 53f0d1eeda5bf..e4f5520d8a33e 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -222,7 +222,7 @@ impl Thread { #[cfg(target_os = "vxworks")] pub fn set_name(name: &CStr) { - let mut name = truncate_cstr::<{ libc::VX_TASK_RENAME_LENGTH - 1 }>(name); + let mut name = truncate_cstr::<{ (libc::VX_TASK_RENAME_LENGTH - 1) as usize }>(name); let res = unsafe { libc::taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) }; debug_assert_eq!(res, libc::OK); } diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index b6777b76668d5..6219be60caf2c 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -98,6 +98,7 @@ pub struct Command { #[cfg(target_os = "linux")] create_pidfd: bool, pgroup: Option, + setsid: bool, } // passed back to std::process with the pipes connected to the child, if any @@ -185,6 +186,7 @@ impl Command { #[cfg(target_os = "linux")] create_pidfd: false, pgroup: None, + setsid: false, } } @@ -220,6 +222,9 @@ impl Command { self.cwd(&OsStr::new("/")); } } + pub fn setsid(&mut self, setsid: bool) { + self.setsid = setsid; + } #[cfg(target_os = "linux")] pub fn create_pidfd(&mut self, val: bool) { @@ -298,6 +303,10 @@ impl Command { pub fn get_chroot(&self) -> Option<&CStr> { self.chroot.as_deref() } + #[allow(dead_code)] + pub fn get_setsid(&self) -> bool { + self.setsid + } pub fn get_closures(&mut self) -> &mut Vec io::Result<()> + Send + Sync>> { &mut self.closures diff --git a/library/std/src/sys/process/unix/common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs index e5c8dd6e341e1..5f71bf051f8a8 100644 --- a/library/std/src/sys/process/unix/common/tests.rs +++ b/library/std/src/sys/process/unix/common/tests.rs @@ -134,6 +134,64 @@ fn test_process_group_no_posix_spawn() { } } +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_posix_spawn() { + // Spawn a cat subprocess that's just going to hang since there is no I/O. + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + unsafe { + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + +#[test] +#[cfg_attr( + any( + // See test_process_mask + target_os = "macos", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv64", + ), + ignore +)] +fn test_setsid_no_posix_spawn() { + let mut cmd = Command::new(OsStr::new("cat")); + cmd.setsid(true); + cmd.stdin(Stdio::MakePipe); + cmd.stdout(Stdio::MakePipe); + + unsafe { + // Same as above, create hang-y cat. This time, force using the non-posix_spawn path. + cmd.pre_exec(Box::new(|| Ok(()))); // pre_exec forces fork + exec rather than posix spawn. + let (mut cat, _pipes) = t!(cmd.spawn(Stdio::Null, true)); + + // Setsid will create a new session and process group, so check that + // we can kill the process group, which means there *is* one. + t!(cvt(libc::kill(-(cat.id() as libc::pid_t), libc::SIGINT))); + + t!(cat.wait()); + } +} + #[test] fn test_program_kind() { let vectors = &[ diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index bbd03e2b0c4e9..5d13d6da18582 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -340,6 +340,10 @@ impl Command { cvt(libc::setpgid(0, pgroup))?; } + if self.get_setsid() { + cvt(libc::setsid())?; + } + // emscripten has no signal support. #[cfg(not(target_os = "emscripten"))] { @@ -741,6 +745,16 @@ impl Command { flags |= libc::POSIX_SPAWN_SETSIGDEF; } + if self.get_setsid() { + cfg_if::cfg_if! { + if #[cfg(all(target_os = "linux", target_env = "gnu"))] { + flags |= libc::POSIX_SPAWN_SETSID; + } else { + return Ok(None); + } + } + } + cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 013e886a99b6b..fc85797dcc269 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -20,6 +20,7 @@ cfg_if::cfg_if! { target_os = "rtems", target_os = "solaris", target_os = "vita", + target_os = "nuttx", ))] { mod arc4random; pub use arc4random::fill_bytes; @@ -44,7 +45,6 @@ cfg_if::cfg_if! { target_os = "hurd", target_os = "l4re", target_os = "nto", - target_os = "nuttx", ))] { mod unix_legacy; pub use unix_legacy::fill_bytes; diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index b7f4656fa3701..cce88d936b71b 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -11,7 +11,7 @@ //! This is because `sys_common` not only contains platform-independent code, //! but also code that is shared between the different platforms in `sys`. //! Ideally all that shared code should be moved to `sys::common`, -//! and the dependencies between `std`, `sys_common` and `sys` all would form a dag. +//! and the dependencies between `std`, `sys_common` and `sys` all would form a DAG. //! Progress on this is tracked in #84187. #![allow(missing_docs)] diff --git a/library/stdarch/Cargo.lock b/library/stdarch/Cargo.lock index 3b76eed770bd0..80f424dfdd8da 100644 --- a/library/stdarch/Cargo.lock +++ b/library/stdarch/Cargo.lock @@ -147,7 +147,6 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" name = "core_arch" version = "0.1.5" dependencies = [ - "std_detect", "stdarch-test", "syscalls", ] diff --git a/library/stdarch/README.md b/library/stdarch/README.md index 70ec256e681e0..9a35f4cd6ff58 100644 --- a/library/stdarch/README.md +++ b/library/stdarch/README.md @@ -16,3 +16,9 @@ This repository contains two main crates: The `std::simd` component now lives in the [`packed_simd_2`](https://github.com/rust-lang/packed_simd) crate. + +## Synchronizing josh subtree with rustc + +This repository is linked to `rust-lang/rust` as a [josh](https://josh-project.github.io/josh/intro.html) subtree. You can use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) tool to perform synchronization. + +You can find a guide on how to perform the synchronization [here](https://rustc-dev-guide.rust-lang.org/external-repos.html#synchronizing-a-josh-subtree). diff --git a/library/stdarch/crates/core_arch/Cargo.toml b/library/stdarch/crates/core_arch/Cargo.toml index f4bd5fc552afe..670447a2d5a8b 100644 --- a/library/stdarch/crates/core_arch/Cargo.toml +++ b/library/stdarch/crates/core_arch/Cargo.toml @@ -22,7 +22,6 @@ maintenance = { status = "experimental" } [dev-dependencies] stdarch-test = { version = "0.*", path = "../stdarch-test" } -std_detect = { version = "0.*", path = "../std_detect" } [target.'cfg(all(target_arch = "x86_64", target_os = "linux"))'.dev-dependencies] syscalls = { version = "0.6.18", default-features = false } diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 96ed82021b4b2..32f144bc7adc4 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -7925,7 +7925,7 @@ pub fn vcvth_f16_u64(a: u64) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] pub fn vcvth_n_f16_s16(a: i16) -> f16 { static_assert!(N >= 1 && N <= 16); - vcvth_n_f16_s32::(a as i32) as f16 + vcvth_n_f16_s32::(a as i32) } #[doc = "Fixed-point convert to floating-point"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_s32)"] @@ -7972,7 +7972,7 @@ pub fn vcvth_n_f16_s64(a: i64) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] pub fn vcvth_n_f16_u16(a: u16) -> f16 { static_assert!(N >= 1 && N <= 16); - vcvth_n_f16_u32::(a as u32) as f16 + vcvth_n_f16_u32::(a as u32) } #[doc = "Fixed-point convert to floating-point"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vcvth_n_f16_u32)"] @@ -17158,7 +17158,7 @@ pub fn vqdmlalh_s16(a: i32, b: i16, c: i16) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqdmlals_s32(a: i64, b: i32, c: i32) -> i64 { let x: i64 = vqaddd_s64(a, vqdmulls_s32(b, c)); - x as i64 + x } #[doc = "Signed saturating doubling multiply-subtract long"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmlsl_high_lane_s16)"] @@ -17324,7 +17324,7 @@ pub fn vqdmlslh_s16(a: i32, b: i16, c: i16) -> i32 { #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqdmlsls_s32(a: i64, b: i32, c: i32) -> i64 { let x: i64 = vqsubd_s64(a, vqdmulls_s32(b, c)); - x as i64 + x } #[doc = "Vector saturating doubling multiply high by scalar"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqdmulh_lane_s16)"] @@ -19495,10 +19495,7 @@ pub fn vqtbl1q_s8(a: int8x16_t, b: uint8x16_t) -> int8x16_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1_u8(a: uint8x16_t, b: uint8x8_t) -> uint8x8_t { - unsafe { - let x = transmute(vqtbl1(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_u8)"] @@ -19507,10 +19504,7 @@ pub fn vqtbl1_u8(a: uint8x16_t, b: uint8x8_t) -> uint8x8_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { - unsafe { - let x = transmute(vqtbl1q(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1q(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1_p8)"] @@ -19519,10 +19513,7 @@ pub fn vqtbl1q_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1_p8(a: poly8x16_t, b: uint8x8_t) -> poly8x8_t { - unsafe { - let x = transmute(vqtbl1(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl1q_p8)"] @@ -19531,10 +19522,7 @@ pub fn vqtbl1_p8(a: poly8x16_t, b: uint8x8_t) -> poly8x8_t { #[cfg_attr(test, assert_instr(tbl))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbl1q_p8(a: poly8x16_t, b: uint8x16_t) -> poly8x16_t { - unsafe { - let x = transmute(vqtbl1q(transmute(a), b)); - x - } + unsafe { transmute(vqtbl1q(transmute(a), b)) } } #[doc = "Table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbl2)"] @@ -20397,10 +20385,7 @@ pub fn vqtbx1q_s8(a: int8x16_t, b: int8x16_t, c: uint8x16_t) -> int8x16_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1_u8(a: uint8x8_t, b: uint8x16_t, c: uint8x8_t) -> uint8x8_t { - unsafe { - let x = transmute(vqtbx1(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_u8)"] @@ -20409,10 +20394,7 @@ pub fn vqtbx1_u8(a: uint8x8_t, b: uint8x16_t, c: uint8x8_t) -> uint8x8_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t { - unsafe { - let x = transmute(vqtbx1q(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1q(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1_p8)"] @@ -20421,10 +20403,7 @@ pub fn vqtbx1q_u8(a: uint8x16_t, b: uint8x16_t, c: uint8x16_t) -> uint8x16_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1_p8(a: poly8x8_t, b: poly8x16_t, c: uint8x8_t) -> poly8x8_t { - unsafe { - let x = transmute(vqtbx1(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx1q_p8)"] @@ -20433,10 +20412,7 @@ pub fn vqtbx1_p8(a: poly8x8_t, b: poly8x16_t, c: uint8x8_t) -> poly8x8_t { #[cfg_attr(test, assert_instr(tbx))] #[stable(feature = "neon_intrinsics", since = "1.59.0")] pub fn vqtbx1q_p8(a: poly8x16_t, b: poly8x16_t, c: uint8x16_t) -> poly8x16_t { - unsafe { - let x = transmute(vqtbx1q(transmute(a), transmute(b), c)); - x - } + unsafe { transmute(vqtbx1q(transmute(a), transmute(b), c)) } } #[doc = "Extended table look-up"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqtbx2)"] @@ -23785,14 +23761,7 @@ pub fn vrndph_f16(a: f16) -> f16 { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f16(a: float16x4_t) -> float16x4_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v4f16" - )] - fn _vrndx_f16(a: float16x4_t) -> float16x4_t; - } - unsafe { _vrndx_f16(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f16)"] @@ -23801,14 +23770,7 @@ pub fn vrndx_f16(a: float16x4_t) -> float16x4_t { #[unstable(feature = "stdarch_neon_f16", issue = "136306")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f16(a: float16x8_t) -> float16x8_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v8f16" - )] - fn _vrndxq_f16(a: float16x8_t) -> float16x8_t; - } - unsafe { _vrndxq_f16(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f32)"] @@ -23817,14 +23779,7 @@ pub fn vrndxq_f16(a: float16x8_t) -> float16x8_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f32(a: float32x2_t) -> float32x2_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v2f32" - )] - fn _vrndx_f32(a: float32x2_t) -> float32x2_t; - } - unsafe { _vrndx_f32(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f32)"] @@ -23833,14 +23788,7 @@ pub fn vrndx_f32(a: float32x2_t) -> float32x2_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f32(a: float32x4_t) -> float32x4_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v4f32" - )] - fn _vrndxq_f32(a: float32x4_t) -> float32x4_t; - } - unsafe { _vrndxq_f32(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f64)"] @@ -23849,14 +23797,7 @@ pub fn vrndxq_f32(a: float32x4_t) -> float32x4_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndx_f64(a: float64x1_t) -> float64x1_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v1f64" - )] - fn _vrndx_f64(a: float64x1_t) -> float64x1_t; - } - unsafe { _vrndx_f64(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxq_f64)"] @@ -23865,14 +23806,7 @@ pub fn vrndx_f64(a: float64x1_t) -> float64x1_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxq_f64(a: float64x2_t) -> float64x2_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.rint.v2f64" - )] - fn _vrndxq_f64(a: float64x2_t) -> float64x2_t; - } - unsafe { _vrndxq_f64(a) } + unsafe { simd_round_ties_even(a) } } #[doc = "Floating-point round to integral, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndxh_f16)"] @@ -24082,7 +24016,6 @@ pub fn vrsqrtes_f32(a: f32) -> f32 { #[doc = "Reciprocal square-root estimate."] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrsqrteh_f16)"] #[inline] -#[target_feature(enable = "neon,fp16")] #[cfg_attr(test, assert_instr(frsqrte))] #[target_feature(enable = "neon,fp16")] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/mod.rs index 527b53de99d95..8074648a28a28 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/mod.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/mod.rs @@ -20,10 +20,10 @@ //! Section 10.1 of ACLE says: //! //! - "In the sequence of Arm architectures { v5, v5TE, v6, v6T2, v7 } each architecture includes -//! its predecessor instruction set." +//! its predecessor's instruction set." //! //! - "In the sequence of Thumb-only architectures { v6-M, v7-M, v7E-M } each architecture includes -//! its predecessor instruction set." +//! its predecessor's instruction set." //! //! From that info and from looking at how LLVM features work (using custom targets) we can identify //! features that are subsets of others: @@ -38,7 +38,7 @@ //! *NOTE*: Section 5.4.7 of ACLE says: //! //! - "__ARM_FEATURE_DSP is defined to 1 if the DSP (v5E) instructions are supported and the -//! intrinsics defined in Saturating intrinsics are available." +//! intrinsics defined in Saturating intrinsics are available." //! //! This does *not* match how LLVM uses the '+dsp' feature; this feature is not set for v5te //! targets so we have to work around this difference. diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs index 286f1868852aa..4df1b741485b9 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/generated.rs @@ -40758,16 +40758,7 @@ pub fn vqshlu_n_s8(a: int8x8_t) -> uint8x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v8i8")] fn _vqshlu_n_s8(a: int8x8_t, n: int8x8_t) -> uint8x8_t; } - unsafe { - _vqshlu_n_s8( - a, - const { - int8x8_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshlu_n_s8(a, const { int8x8_t([N as i8; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"] @@ -40783,17 +40774,7 @@ pub fn vqshluq_n_s8(a: int8x16_t) -> uint8x16_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v16i8")] fn _vqshluq_n_s8(a: int8x16_t, n: int8x16_t) -> uint8x16_t; } - unsafe { - _vqshluq_n_s8( - a, - const { - int8x16_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshluq_n_s8(a, const { int8x16_t([N as i8; 16]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"] @@ -40809,12 +40790,7 @@ pub fn vqshlu_n_s16(a: int16x4_t) -> uint16x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v4i16")] fn _vqshlu_n_s16(a: int16x4_t, n: int16x4_t) -> uint16x4_t; } - unsafe { - _vqshlu_n_s16( - a, - const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }, - ) - } + unsafe { _vqshlu_n_s16(a, const { int16x4_t([N as i16; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"] @@ -40830,16 +40806,7 @@ pub fn vqshluq_n_s16(a: int16x8_t) -> uint16x8_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v8i16")] fn _vqshluq_n_s16(a: int16x8_t, n: int16x8_t) -> uint16x8_t; } - unsafe { - _vqshluq_n_s16( - a, - const { - int16x8_t([ - N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, - ]) - }, - ) - } + unsafe { _vqshluq_n_s16(a, const { int16x8_t([N as i16; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"] @@ -40855,7 +40822,7 @@ pub fn vqshlu_n_s32(a: int32x2_t) -> uint32x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v2i32")] fn _vqshlu_n_s32(a: int32x2_t, n: int32x2_t) -> uint32x2_t; } - unsafe { _vqshlu_n_s32(a, const { int32x2_t([N as i32, N as i32]) }) } + unsafe { _vqshlu_n_s32(a, const { int32x2_t([N; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"] @@ -40871,12 +40838,7 @@ pub fn vqshluq_n_s32(a: int32x4_t) -> uint32x4_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v4i32")] fn _vqshluq_n_s32(a: int32x4_t, n: int32x4_t) -> uint32x4_t; } - unsafe { - _vqshluq_n_s32( - a, - const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }, - ) - } + unsafe { _vqshluq_n_s32(a, const { int32x4_t([N; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"] @@ -40908,7 +40870,7 @@ pub fn vqshluq_n_s64(a: int64x2_t) -> uint64x2_t { #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqshiftsu.v2i64")] fn _vqshluq_n_s64(a: int64x2_t, n: int64x2_t) -> uint64x2_t; } - unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64, N as i64]) }) } + unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s8)"] @@ -40927,16 +40889,7 @@ pub fn vqshlu_n_s8(a: int8x8_t) -> uint8x8_t { )] fn _vqshlu_n_s8(a: int8x8_t, n: int8x8_t) -> uint8x8_t; } - unsafe { - _vqshlu_n_s8( - a, - const { - int8x8_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshlu_n_s8(a, const { int8x8_t([N as i8; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s8)"] @@ -40955,17 +40908,7 @@ pub fn vqshluq_n_s8(a: int8x16_t) -> uint8x16_t { )] fn _vqshluq_n_s8(a: int8x16_t, n: int8x16_t) -> uint8x16_t; } - unsafe { - _vqshluq_n_s8( - a, - const { - int8x16_t([ - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, - ]) - }, - ) - } + unsafe { _vqshluq_n_s8(a, const { int8x16_t([N as i8; 16]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s16)"] @@ -40984,12 +40927,7 @@ pub fn vqshlu_n_s16(a: int16x4_t) -> uint16x4_t { )] fn _vqshlu_n_s16(a: int16x4_t, n: int16x4_t) -> uint16x4_t; } - unsafe { - _vqshlu_n_s16( - a, - const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }, - ) - } + unsafe { _vqshlu_n_s16(a, const { int16x4_t([N as i16; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s16)"] @@ -41008,16 +40946,7 @@ pub fn vqshluq_n_s16(a: int16x8_t) -> uint16x8_t { )] fn _vqshluq_n_s16(a: int16x8_t, n: int16x8_t) -> uint16x8_t; } - unsafe { - _vqshluq_n_s16( - a, - const { - int16x8_t([ - N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, - ]) - }, - ) - } + unsafe { _vqshluq_n_s16(a, const { int16x8_t([N as i16; 8]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s32)"] @@ -41036,7 +40965,7 @@ pub fn vqshlu_n_s32(a: int32x2_t) -> uint32x2_t { )] fn _vqshlu_n_s32(a: int32x2_t, n: int32x2_t) -> uint32x2_t; } - unsafe { _vqshlu_n_s32(a, const { int32x2_t([N as i32, N as i32]) }) } + unsafe { _vqshlu_n_s32(a, const { int32x2_t([N; 2]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshluq_n_s32)"] @@ -41055,12 +40984,7 @@ pub fn vqshluq_n_s32(a: int32x4_t) -> uint32x4_t { )] fn _vqshluq_n_s32(a: int32x4_t, n: int32x4_t) -> uint32x4_t; } - unsafe { - _vqshluq_n_s32( - a, - const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }, - ) - } + unsafe { _vqshluq_n_s32(a, const { int32x4_t([N; 4]) }) } } #[doc = "Signed saturating shift left unsigned"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshlu_n_s64)"] @@ -41098,7 +41022,7 @@ pub fn vqshluq_n_s64(a: int64x2_t) -> uint64x2_t { )] fn _vqshluq_n_s64(a: int64x2_t, n: int64x2_t) -> uint64x2_t; } - unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64, N as i64]) }) } + unsafe { _vqshluq_n_s64(a, const { int64x2_t([N as i64; 2]) }) } } #[doc = "Signed saturating shift right narrow"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vqshrn_n_s16)"] diff --git a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs index 0683d48ed3271..60c9daef68c42 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/neon/mod.rs @@ -777,8 +777,8 @@ pub struct float16x8x2_t(pub float16x8_t, pub float16x8_t); #[repr(C)] #[derive(Copy, Clone, Debug)] #[unstable(feature = "stdarch_neon_f16", issue = "136306")] - pub struct float16x8x3_t(pub float16x8_t, pub float16x8_t, pub float16x8_t); + /// Arm-specific type containing four `float16x8_t` vectors. #[repr(C)] #[derive(Copy, Clone, Debug)] diff --git a/library/stdarch/crates/core_arch/src/lib.rs b/library/stdarch/crates/core_arch/src/lib.rs index 340c4c510d784..c58580f641780 100644 --- a/library/stdarch/crates/core_arch/src/lib.rs +++ b/library/stdarch/crates/core_arch/src/lib.rs @@ -75,9 +75,7 @@ #[cfg(test)] #[macro_use] extern crate std; -#[cfg(test)] -#[macro_use] -extern crate std_detect; + #[path = "mod.rs"] mod core_arch; diff --git a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs index 2deeb53c20995..a7bbf35ed8d0b 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/altivec.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/altivec.rs @@ -360,25 +360,6 @@ unsafe extern "C" { #[link_name = "llvm.ppc.altivec.vsrv"] fn vsrv(a: vector_unsigned_char, b: vector_unsigned_char) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v16i8"] - fn fshlb( - a: vector_unsigned_char, - b: vector_unsigned_char, - c: vector_unsigned_char, - ) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v8i16"] - fn fshlh( - a: vector_unsigned_short, - b: vector_unsigned_short, - c: vector_unsigned_short, - ) -> vector_unsigned_short; - #[link_name = "llvm.fshl.v4i32"] - fn fshlw( - a: vector_unsigned_int, - b: vector_unsigned_int, - c: vector_unsigned_int, - ) -> vector_unsigned_int; - #[link_name = "llvm.nearbyint.v4f32"] fn vrfin(a: vector_float) -> vector_float; } @@ -3193,19 +3174,19 @@ mod sealed { impl_vec_cntlz! { vec_vcntlzw(vector_unsigned_int) } macro_rules! impl_vrl { - ($fun:ident $intr:ident $ty:ident) => { + ($fun:ident $ty:ident) => { #[inline] #[target_feature(enable = "altivec")] #[cfg_attr(test, assert_instr($fun))] unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { - transmute($intr(transmute(a), transmute(a), transmute(b))) + simd_funnel_shl(a, a, b) } }; } - impl_vrl! { vrlb fshlb u8 } - impl_vrl! { vrlh fshlh u16 } - impl_vrl! { vrlw fshlw u32 } + impl_vrl! { vrlb u8 } + impl_vrl! { vrlh u16 } + impl_vrl! { vrlw u32 } #[unstable(feature = "stdarch_powerpc", issue = "111145")] pub trait VectorRl { diff --git a/library/stdarch/crates/core_arch/src/powerpc/macros.rs b/library/stdarch/crates/core_arch/src/powerpc/macros.rs index af47494e8fb40..24d86f1018c8f 100644 --- a/library/stdarch/crates/core_arch/src/powerpc/macros.rs +++ b/library/stdarch/crates/core_arch/src/powerpc/macros.rs @@ -278,6 +278,7 @@ macro_rules! impl_from { ($s: ident) => { #[unstable(feature = "stdarch_powerpc", issue = "111145")] impl From<$s> for s_t_l!($s) { + #[inline] fn from (v: $s) -> Self { unsafe { transmute(v) @@ -297,6 +298,7 @@ macro_rules! impl_neg { #[unstable(feature = "stdarch_powerpc", issue = "111145")] impl crate::ops::Neg for s_t_l!($s) { type Output = s_t_l!($s); + #[inline] fn neg(self) -> Self::Output { unsafe { simd_neg(self) } } diff --git a/library/stdarch/crates/core_arch/src/s390x/macros.rs b/library/stdarch/crates/core_arch/src/s390x/macros.rs index 4f0f84ec912b7..26afbaa45a741 100644 --- a/library/stdarch/crates/core_arch/src/s390x/macros.rs +++ b/library/stdarch/crates/core_arch/src/s390x/macros.rs @@ -435,6 +435,7 @@ macro_rules! impl_from { ($s: ident) => { #[unstable(feature = "stdarch_s390x", issue = "135681")] impl From<$s> for s_t_l!($s) { + #[inline] fn from (v: $s) -> Self { unsafe { transmute(v) @@ -454,6 +455,7 @@ macro_rules! impl_neg { #[unstable(feature = "stdarch_s390x", issue = "135681")] impl crate::ops::Neg for s_t_l!($s) { type Output = s_t_l!($s); + #[inline] fn neg(self) -> Self::Output { unsafe { simd_neg(self) } } diff --git a/library/stdarch/crates/core_arch/src/s390x/vector.rs b/library/stdarch/crates/core_arch/src/s390x/vector.rs index ae5c37ce0178b..1cd33c3554bde 100644 --- a/library/stdarch/crates/core_arch/src/s390x/vector.rs +++ b/library/stdarch/crates/core_arch/src/s390x/vector.rs @@ -51,7 +51,7 @@ types! { pub struct vector_double(2 x f64); } -#[repr(packed)] +#[repr(C, packed)] struct PackedTuple { x: T, y: U, @@ -83,9 +83,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.nearbyint.v4f32"] fn nearbyint_v4f32(a: vector_float) -> vector_float; #[link_name = "llvm.nearbyint.v2f64"] fn nearbyint_v2f64(a: vector_double) -> vector_double; - #[link_name = "llvm.rint.v4f32"] fn rint_v4f32(a: vector_float) -> vector_float; - #[link_name = "llvm.rint.v2f64"] fn rint_v2f64(a: vector_double) -> vector_double; - #[link_name = "llvm.roundeven.v4f32"] fn roundeven_v4f32(a: vector_float) -> vector_float; #[link_name = "llvm.roundeven.v2f64"] fn roundeven_v2f64(a: vector_double) -> vector_double; @@ -101,11 +98,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.s390.vsld"] fn vsld(a: i8x16, b: i8x16, c: u32) -> i8x16; #[link_name = "llvm.s390.vsrd"] fn vsrd(a: i8x16, b: i8x16, c: u32) -> i8x16; - #[link_name = "llvm.fshl.v16i8"] fn fshlb(a: vector_unsigned_char, b: vector_unsigned_char, c: vector_unsigned_char) -> vector_unsigned_char; - #[link_name = "llvm.fshl.v8i16"] fn fshlh(a: vector_unsigned_short, b: vector_unsigned_short, c: vector_unsigned_short) -> vector_unsigned_short; - #[link_name = "llvm.fshl.v4i32"] fn fshlf(a: vector_unsigned_int, b: vector_unsigned_int, c: vector_unsigned_int) -> vector_unsigned_int; - #[link_name = "llvm.fshl.v2i64"] fn fshlg(a: vector_unsigned_long_long, b: vector_unsigned_long_long, c: vector_unsigned_long_long) -> vector_unsigned_long_long; - #[link_name = "llvm.s390.verimb"] fn verimb(a: vector_signed_char, b: vector_signed_char, c: vector_signed_char, d: i32) -> vector_signed_char; #[link_name = "llvm.s390.verimh"] fn verimh(a: vector_signed_short, b: vector_signed_short, c: vector_signed_short, d: i32) -> vector_signed_short; #[link_name = "llvm.s390.verimf"] fn verimf(a: vector_signed_int, b: vector_signed_int, c: vector_signed_int, d: i32) -> vector_signed_int; @@ -1197,8 +1189,8 @@ mod sealed { test_impl! { vec_round_f32 (a: vector_float) -> vector_float [roundeven_v4f32, _] } test_impl! { vec_round_f64 (a: vector_double) -> vector_double [roundeven_v2f64, _] } - test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [rint_v4f32, "vector-enhancements-1" vfisb] } - test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [rint_v2f64, vfidb] } + test_impl! { vec_rint_f32 (a: vector_float) -> vector_float [simd_round_ties_even, "vector-enhancements-1" vfisb] } + test_impl! { vec_rint_f64 (a: vector_double) -> vector_double [simd_round_ties_even, vfidb] } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorRoundc { @@ -1221,8 +1213,8 @@ mod sealed { impl_vec_trait! { [VectorRound vec_round] vec_round_f32 (vector_float) } impl_vec_trait! { [VectorRound vec_round] vec_round_f64 (vector_double) } - impl_vec_trait! { [VectorRint vec_rint] vec_rint_f32 (vector_float) } - impl_vec_trait! { [VectorRint vec_rint] vec_rint_f64 (vector_double) } + impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_float) } + impl_vec_trait! { [VectorRint vec_rint] simd_round_ties_even (vector_double) } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorTrunc { @@ -1411,43 +1403,42 @@ mod sealed { } macro_rules! impl_rot { - ($fun:ident $intr:ident $ty:ident) => { + ($fun:ident $ty:ident) => { #[inline] #[target_feature(enable = "vector")] #[cfg_attr(test, assert_instr($fun))] unsafe fn $fun(a: t_t_l!($ty), b: t_t_l!($ty)) -> t_t_l!($ty) { - transmute($intr(transmute(a), transmute(a), transmute(b))) + simd_funnel_shl(a, a, b) } }; } - impl_rot! { verllvb fshlb u8 } - impl_rot! { verllvh fshlh u16 } - impl_rot! { verllvf fshlf u32 } - impl_rot! { verllvg fshlg u64 } + impl_rot! { verllvb u8 } + impl_rot! { verllvh u16 } + impl_rot! { verllvf u32 } + impl_rot! { verllvg u64 } impl_vec_shift! { [VectorRl vec_rl] (verllvb, verllvh, verllvf, verllvg) } macro_rules! test_rot_imm { - ($fun:ident $instr:ident $intr:ident $ty:ident) => { + ($fun:ident $instr:ident $ty:ident) => { #[inline] #[target_feature(enable = "vector")] #[cfg_attr(test, assert_instr($instr))] unsafe fn $fun(a: t_t_l!($ty), bits: core::ffi::c_ulong) -> t_t_l!($ty) { // mod by the number of bits in a's element type to prevent UB let bits = (bits % $ty::BITS as core::ffi::c_ulong) as $ty; - let a = transmute(a); let b = ::splat(bits); - transmute($intr(a, a, transmute(b))) + simd_funnel_shl(a, a, transmute(b)) } }; } - test_rot_imm! { verllvb_imm verllb fshlb u8 } - test_rot_imm! { verllvh_imm verllh fshlh u16 } - test_rot_imm! { verllvf_imm verllf fshlf u32 } - test_rot_imm! { verllvg_imm verllg fshlg u64 } + test_rot_imm! { verllvb_imm verllb u8 } + test_rot_imm! { verllvh_imm verllh u16 } + test_rot_imm! { verllvf_imm verllf u32 } + test_rot_imm! { verllvg_imm verllg u64 } #[unstable(feature = "stdarch_s390x", issue = "135681")] pub trait VectorRli { @@ -4787,7 +4778,7 @@ pub unsafe fn vec_splat_s8() -> vector_signed_char { #[unstable(feature = "stdarch_s390x", issue = "135681")] #[cfg_attr(test, assert_instr(vrepih, IMM = 42))] pub unsafe fn vec_splat_s16() -> vector_signed_short { - vector_signed_short([IMM as i16; 8]) + vector_signed_short([IMM; 8]) } /// Vector Splat Signed Word diff --git a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs index fc0d7723fa014..108bc3125c5f3 100644 --- a/library/stdarch/crates/core_arch/src/wasm32/simd128.rs +++ b/library/stdarch/crates/core_arch/src/wasm32/simd128.rs @@ -141,7 +141,7 @@ unsafe extern "unadjusted" { fn llvm_f64x2_max(x: simd::f64x2, y: simd::f64x2) -> simd::f64x2; } -#[repr(packed)] +#[repr(C, packed)] #[derive(Copy)] struct Unaligned(T); diff --git a/library/stdarch/crates/core_arch/src/x86/avx.rs b/library/stdarch/crates/core_arch/src/x86/avx.rs index df1cb63be30f0..24e0cf6ba1afb 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx.rs @@ -1258,7 +1258,7 @@ pub fn _mm256_permute2f128_si256(a: __m256i, b: __m256i) -> __m #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm256_broadcast_ss(f: &f32) -> __m256 { +pub fn _mm256_broadcast_ss(f: &f32) -> __m256 { _mm256_set1_ps(*f) } @@ -1271,7 +1271,7 @@ pub unsafe fn _mm256_broadcast_ss(f: &f32) -> __m256 { #[cfg_attr(test, assert_instr(vbroadcastss))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm_broadcast_ss(f: &f32) -> __m128 { +pub fn _mm_broadcast_ss(f: &f32) -> __m128 { _mm_set1_ps(*f) } @@ -1284,7 +1284,7 @@ pub unsafe fn _mm_broadcast_ss(f: &f32) -> __m128 { #[cfg_attr(test, assert_instr(vbroadcastsd))] #[stable(feature = "simd_x86", since = "1.27.0")] #[allow(clippy::trivially_copy_pass_by_ref)] -pub unsafe fn _mm256_broadcast_sd(f: &f64) -> __m256d { +pub fn _mm256_broadcast_sd(f: &f64) -> __m256d { _mm256_set1_pd(*f) } @@ -1296,8 +1296,8 @@ pub unsafe fn _mm256_broadcast_sd(f: &f64) -> __m256d { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_broadcast_ps(a: &__m128) -> __m256 { - simd_shuffle!(*a, _mm_setzero_ps(), [0, 1, 2, 3, 0, 1, 2, 3]) +pub fn _mm256_broadcast_ps(a: &__m128) -> __m256 { + unsafe { simd_shuffle!(*a, _mm_setzero_ps(), [0, 1, 2, 3, 0, 1, 2, 3]) } } /// Broadcasts 128 bits from memory (composed of 2 packed double-precision @@ -1308,8 +1308,8 @@ pub unsafe fn _mm256_broadcast_ps(a: &__m128) -> __m256 { #[target_feature(enable = "avx")] #[cfg_attr(test, assert_instr(vbroadcastf128))] #[stable(feature = "simd_x86", since = "1.27.0")] -pub unsafe fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { - simd_shuffle!(*a, _mm_setzero_pd(), [0, 1, 0, 1]) +pub fn _mm256_broadcast_pd(a: &__m128d) -> __m256d { + unsafe { simd_shuffle!(*a, _mm_setzero_pd(), [0, 1, 0, 1]) } } /// Copies `a` to result, then inserts 128 bits (composed of 4 packed diff --git a/library/stdarch/crates/core_arch/src/x86/avx512f.rs b/library/stdarch/crates/core_arch/src/x86/avx512f.rs index dd224616764d6..d53f83c0a10bc 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512f.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512f.rs @@ -33248,7 +33248,7 @@ pub fn _mm512_reduce_add_ps(a: __m512) -> f32 { ); let a = _mm_add_ps(_mm256_extractf128_ps::<0>(a), _mm256_extractf128_ps::<1>(a)); let a = _mm_add_ps(a, simd_shuffle!(a, a, [2, 3, 0, 1])); - simd_extract::<_, f32>(a, 0) + simd_extract::<_, f32>(a, 1) + simd_extract!(a, 0, f32) + simd_extract!(a, 1, f32) } } @@ -33275,7 +33275,7 @@ pub fn _mm512_reduce_add_pd(a: __m512d) -> f64 { _mm512_extractf64x4_pd::<1>(a), ); let a = _mm_add_pd(_mm256_extractf128_pd::<0>(a), _mm256_extractf128_pd::<1>(a)); - simd_extract::<_, f64>(a, 0) + simd_extract::<_, f64>(a, 1) + simd_extract!(a, 0, f64) + simd_extract!(a, 1, f64) } } @@ -33356,7 +33356,7 @@ pub fn _mm512_reduce_mul_ps(a: __m512) -> f32 { ); let a = _mm_mul_ps(_mm256_extractf128_ps::<0>(a), _mm256_extractf128_ps::<1>(a)); let a = _mm_mul_ps(a, simd_shuffle!(a, a, [2, 3, 0, 1])); - simd_extract::<_, f32>(a, 0) * simd_extract::<_, f32>(a, 1) + simd_extract!(a, 0, f32) * simd_extract!(a, 1, f32) } } @@ -33383,7 +33383,7 @@ pub fn _mm512_reduce_mul_pd(a: __m512d) -> f64 { _mm512_extractf64x4_pd::<1>(a), ); let a = _mm_mul_pd(_mm256_extractf128_pd::<0>(a), _mm256_extractf128_pd::<1>(a)); - simd_extract::<_, f64>(a, 0) * simd_extract::<_, f64>(a, 1) + simd_extract!(a, 0, f64) * simd_extract!(a, 1, f64) } } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs index 0a81a0581f97a..8c914803c665d 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512fp16.rs @@ -11032,7 +11032,7 @@ pub fn _mm_reduce_add_ph(a: __m128h) -> f16 { let a = _mm_add_ph(a, b); let b = simd_shuffle!(a, a, [2, 3, 0, 1, 4, 5, 6, 7]); let a = _mm_add_ph(a, b); - simd_extract::<_, f16>(a, 0) + simd_extract::<_, f16>(a, 1) + simd_extract!(a, 0, f16) + simd_extract!(a, 1, f16) } } @@ -11085,7 +11085,7 @@ pub fn _mm_reduce_mul_ph(a: __m128h) -> f16 { let a = _mm_mul_ph(a, b); let b = simd_shuffle!(a, a, [2, 3, 0, 1, 4, 5, 6, 7]); let a = _mm_mul_ph(a, b); - simd_extract::<_, f16>(a, 0) * simd_extract::<_, f16>(a, 1) + simd_extract!(a, 0, f16) * simd_extract!(a, 1, f16) } } diff --git a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs index c722f7b370ffe..09a90e29bf088 100644 --- a/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs +++ b/library/stdarch/crates/core_arch/src/x86/avx512vbmi2.rs @@ -500,7 +500,7 @@ pub fn _mm_maskz_expand_epi8(k: __mmask16, a: __m128i) -> __m128i { #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm512_shldv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvq(a.as_i64x8(), b.as_i64x8(), c.as_i64x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x8(), b.as_i64x8(), c.as_i64x8())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -539,7 +539,7 @@ pub fn _mm512_maskz_shldv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm256_shldv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvq256(a.as_i64x4(), b.as_i64x4(), c.as_i64x4())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x4(), b.as_i64x4(), c.as_i64x4())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -578,7 +578,7 @@ pub fn _mm256_maskz_shldv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvq))] pub fn _mm_shldv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvq128(a.as_i64x2(), b.as_i64x2(), c.as_i64x2())) } + unsafe { transmute(simd_funnel_shl(a.as_i64x2(), b.as_i64x2(), c.as_i64x2())) } } /// Concatenate packed 64-bit integers in a and b producing an intermediate 128-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -617,7 +617,7 @@ pub fn _mm_maskz_shldv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm512_shldv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvd(a.as_i32x16(), b.as_i32x16(), c.as_i32x16())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x16(), b.as_i32x16(), c.as_i32x16())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -656,7 +656,7 @@ pub fn _mm512_maskz_shldv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm256_shldv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvd256(a.as_i32x8(), b.as_i32x8(), c.as_i32x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x8(), b.as_i32x8(), c.as_i32x8())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -695,7 +695,7 @@ pub fn _mm256_maskz_shldv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvd))] pub fn _mm_shldv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvd128(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } + unsafe { transmute(simd_funnel_shl(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } /// Concatenate packed 32-bit integers in a and b producing an intermediate 64-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -734,7 +734,7 @@ pub fn _mm_maskz_shldv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm512_shldv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshldvw(a.as_i16x32(), b.as_i16x32(), c.as_i16x32())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x32(), b.as_i16x32(), c.as_i16x32())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -773,7 +773,7 @@ pub fn _mm512_maskz_shldv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm256_shldv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshldvw256(a.as_i16x16(), b.as_i16x16(), c.as_i16x16())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x16(), b.as_i16x16(), c.as_i16x16())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -812,7 +812,7 @@ pub fn _mm256_maskz_shldv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshldvw))] pub fn _mm_shldv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshldvw128(a.as_i16x8(), b.as_i16x8(), c.as_i16x8())) } + unsafe { transmute(simd_funnel_shl(a.as_i16x8(), b.as_i16x8(), c.as_i16x8())) } } /// Concatenate packed 16-bit integers in a and b producing an intermediate 32-bit result. Shift the result left by the amount specified in the corresponding element of c, and store the upper 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -851,7 +851,7 @@ pub fn _mm_maskz_shldv_epi16(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm512_shrdv_epi64(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvq(b.as_i64x8(), a.as_i64x8(), c.as_i64x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x8(), a.as_i64x8(), c.as_i64x8())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -890,7 +890,7 @@ pub fn _mm512_maskz_shrdv_epi64(k: __mmask8, a: __m512i, b: __m512i, c: __m512i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm256_shrdv_epi64(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvq256(b.as_i64x4(), a.as_i64x4(), c.as_i64x4())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x4(), a.as_i64x4(), c.as_i64x4())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -929,7 +929,7 @@ pub fn _mm256_maskz_shrdv_epi64(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvq))] pub fn _mm_shrdv_epi64(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvq128(b.as_i64x2(), a.as_i64x2(), c.as_i64x2())) } + unsafe { transmute(simd_funnel_shr(b.as_i64x2(), a.as_i64x2(), c.as_i64x2())) } } /// Concatenate packed 64-bit integers in b and a producing an intermediate 128-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 64-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -968,7 +968,7 @@ pub fn _mm_maskz_shrdv_epi64(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm512_shrdv_epi32(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvd(b.as_i32x16(), a.as_i32x16(), c.as_i32x16())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x16(), a.as_i32x16(), c.as_i32x16())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1007,7 +1007,7 @@ pub fn _mm512_maskz_shrdv_epi32(k: __mmask16, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm256_shrdv_epi32(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvd256(b.as_i32x8(), a.as_i32x8(), c.as_i32x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x8(), a.as_i32x8(), c.as_i32x8())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1046,7 +1046,7 @@ pub fn _mm256_maskz_shrdv_epi32(k: __mmask8, a: __m256i, b: __m256i, c: __m256i) #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvd))] pub fn _mm_shrdv_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvd128(b.as_i32x4(), a.as_i32x4(), c.as_i32x4())) } + unsafe { transmute(simd_funnel_shr(b.as_i32x4(), a.as_i32x4(), c.as_i32x4())) } } /// Concatenate packed 32-bit integers in b and a producing an intermediate 64-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 32-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1085,7 +1085,7 @@ pub fn _mm_maskz_shrdv_epi32(k: __mmask8, a: __m128i, b: __m128i, c: __m128i) -> #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm512_shrdv_epi16(a: __m512i, b: __m512i, c: __m512i) -> __m512i { - unsafe { transmute(vpshrdvw(b.as_i16x32(), a.as_i16x32(), c.as_i16x32())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x32(), a.as_i16x32(), c.as_i16x32())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1124,7 +1124,7 @@ pub fn _mm512_maskz_shrdv_epi16(k: __mmask32, a: __m512i, b: __m512i, c: __m512i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm256_shrdv_epi16(a: __m256i, b: __m256i, c: __m256i) -> __m256i { - unsafe { transmute(vpshrdvw256(b.as_i16x16(), a.as_i16x16(), c.as_i16x16())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x16(), a.as_i16x16(), c.as_i16x16())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -1163,7 +1163,7 @@ pub fn _mm256_maskz_shrdv_epi16(k: __mmask16, a: __m256i, b: __m256i, c: __m256i #[stable(feature = "stdarch_x86_avx512", since = "1.89")] #[cfg_attr(test, assert_instr(vpshrdvw))] pub fn _mm_shrdv_epi16(a: __m128i, b: __m128i, c: __m128i) -> __m128i { - unsafe { transmute(vpshrdvw128(b.as_i16x8(), a.as_i16x8(), c.as_i16x8())) } + unsafe { transmute(simd_funnel_shr(b.as_i16x8(), a.as_i16x8(), c.as_i16x8())) } } /// Concatenate packed 16-bit integers in b and a producing an intermediate 32-bit result. Shift the result right by the amount specified in the corresponding element of c, and store the lower 16-bits in dst using writemask k (elements are copied from a when the corresponding mask bit is not set). @@ -2138,44 +2138,6 @@ unsafe extern "C" { #[link_name = "llvm.x86.avx512.mask.expand.b.128"] fn vpexpandb128(a: i8x16, src: i8x16, mask: u16) -> i8x16; - #[link_name = "llvm.fshl.v8i64"] - fn vpshldvq(a: i64x8, b: i64x8, c: i64x8) -> i64x8; - #[link_name = "llvm.fshl.v4i64"] - fn vpshldvq256(a: i64x4, b: i64x4, c: i64x4) -> i64x4; - #[link_name = "llvm.fshl.v2i64"] - fn vpshldvq128(a: i64x2, b: i64x2, c: i64x2) -> i64x2; - #[link_name = "llvm.fshl.v16i32"] - fn vpshldvd(a: i32x16, b: i32x16, c: i32x16) -> i32x16; - #[link_name = "llvm.fshl.v8i32"] - fn vpshldvd256(a: i32x8, b: i32x8, c: i32x8) -> i32x8; - #[link_name = "llvm.fshl.v4i32"] - fn vpshldvd128(a: i32x4, b: i32x4, c: i32x4) -> i32x4; - #[link_name = "llvm.fshl.v32i16"] - fn vpshldvw(a: i16x32, b: i16x32, c: i16x32) -> i16x32; - #[link_name = "llvm.fshl.v16i16"] - fn vpshldvw256(a: i16x16, b: i16x16, c: i16x16) -> i16x16; - #[link_name = "llvm.fshl.v8i16"] - fn vpshldvw128(a: i16x8, b: i16x8, c: i16x8) -> i16x8; - - #[link_name = "llvm.fshr.v8i64"] - fn vpshrdvq(a: i64x8, b: i64x8, c: i64x8) -> i64x8; - #[link_name = "llvm.fshr.v4i64"] - fn vpshrdvq256(a: i64x4, b: i64x4, c: i64x4) -> i64x4; - #[link_name = "llvm.fshr.v2i64"] - fn vpshrdvq128(a: i64x2, b: i64x2, c: i64x2) -> i64x2; - #[link_name = "llvm.fshr.v16i32"] - fn vpshrdvd(a: i32x16, b: i32x16, c: i32x16) -> i32x16; - #[link_name = "llvm.fshr.v8i32"] - fn vpshrdvd256(a: i32x8, b: i32x8, c: i32x8) -> i32x8; - #[link_name = "llvm.fshr.v4i32"] - fn vpshrdvd128(a: i32x4, b: i32x4, c: i32x4) -> i32x4; - #[link_name = "llvm.fshr.v32i16"] - fn vpshrdvw(a: i16x32, b: i16x32, c: i16x32) -> i16x32; - #[link_name = "llvm.fshr.v16i16"] - fn vpshrdvw256(a: i16x16, b: i16x16, c: i16x16) -> i16x16; - #[link_name = "llvm.fshr.v8i16"] - fn vpshrdvw128(a: i16x8, b: i16x8, c: i16x8) -> i16x8; - #[link_name = "llvm.x86.avx512.mask.expand.load.b.128"] fn expandloadb_128(mem_addr: *const i8, a: i8x16, mask: u16) -> i8x16; #[link_name = "llvm.x86.avx512.mask.expand.load.w.128"] diff --git a/library/stdarch/crates/core_arch/src/x86/kl.rs b/library/stdarch/crates/core_arch/src/x86/kl.rs index eb9eb83f4115c..26e5a46c62934 100644 --- a/library/stdarch/crates/core_arch/src/x86/kl.rs +++ b/library/stdarch/crates/core_arch/src/x86/kl.rs @@ -127,7 +127,7 @@ unsafe extern "unadjusted" { /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadiwkey) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(loadiwkey))] pub unsafe fn _mm_loadiwkey( control: u32, @@ -153,7 +153,7 @@ pub unsafe fn _mm_loadiwkey( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_encodekey128_u32) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(encodekey128))] pub unsafe fn _mm_encodekey128_u32(key_params: u32, key: __m128i, handle: *mut u8) -> u32 { let EncodeKey128Output(control, key0, key1, key2, _, _, _) = encodekey128(key_params, key); @@ -176,7 +176,7 @@ pub unsafe fn _mm_encodekey128_u32(key_params: u32, key: __m128i, handle: *mut u /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_encodekey256_u32) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(encodekey256))] pub unsafe fn _mm_encodekey256_u32( key_params: u32, @@ -198,7 +198,7 @@ pub unsafe fn _mm_encodekey256_u32( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc128kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesenc128kl))] pub unsafe fn _mm_aesenc128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesenc128kl(input, handle); @@ -214,7 +214,7 @@ pub unsafe fn _mm_aesenc128kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec128kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdec128kl))] pub unsafe fn _mm_aesdec128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesdec128kl(input, handle); @@ -230,7 +230,7 @@ pub unsafe fn _mm_aesdec128kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc256kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesenc256kl))] pub unsafe fn _mm_aesenc256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesenc256kl(input, handle); @@ -246,7 +246,7 @@ pub unsafe fn _mm_aesenc256kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec256kl_u8) #[inline] #[target_feature(enable = "kl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdec256kl))] pub unsafe fn _mm_aesdec256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 { let AesOutput(status, result) = aesdec256kl(input, handle); @@ -262,7 +262,7 @@ pub unsafe fn _mm_aesdec256kl_u8(output: *mut __m128i, input: __m128i, handle: * /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesencwide128kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesencwide128kl))] pub unsafe fn _mm_aesencwide128kl_u8( output: *mut __m128i, @@ -285,7 +285,7 @@ pub unsafe fn _mm_aesencwide128kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdecwide128kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdecwide128kl))] pub unsafe fn _mm_aesdecwide128kl_u8( output: *mut __m128i, @@ -308,7 +308,7 @@ pub unsafe fn _mm_aesdecwide128kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesencwide256kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesencwide256kl))] pub unsafe fn _mm_aesencwide256kl_u8( output: *mut __m128i, @@ -331,7 +331,7 @@ pub unsafe fn _mm_aesencwide256kl_u8( /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdecwide256kl_u8) #[inline] #[target_feature(enable = "widekl")] -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] #[cfg_attr(test, assert_instr(aesdecwide256kl))] pub unsafe fn _mm_aesdecwide256kl_u8( output: *mut __m128i, diff --git a/library/stdarch/crates/core_arch/src/x86/mod.rs b/library/stdarch/crates/core_arch/src/x86/mod.rs index 8897258c7dc24..79a593e647f13 100644 --- a/library/stdarch/crates/core_arch/src/x86/mod.rs +++ b/library/stdarch/crates/core_arch/src/x86/mod.rs @@ -772,5 +772,5 @@ mod avx512fp16; pub use self::avx512fp16::*; mod kl; -#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "keylocker_x86", since = "1.89.0")] pub use self::kl::*; diff --git a/library/stdarch/crates/core_arch/src/x86/sha.rs b/library/stdarch/crates/core_arch/src/x86/sha.rs index da568c449a6be..9ad1a9f14c155 100644 --- a/library/stdarch/crates/core_arch/src/x86/sha.rs +++ b/library/stdarch/crates/core_arch/src/x86/sha.rs @@ -146,7 +146,7 @@ pub fn _mm_sha256rnds2_epu32(a: __m128i, b: __m128i, k: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512msg1))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512msg1_epi64(a: __m256i, b: __m128i) -> __m256i { unsafe { transmute(vsha512msg1(a.as_i64x4(), b.as_i64x2())) } } @@ -159,7 +159,7 @@ pub fn _mm256_sha512msg1_epi64(a: __m256i, b: __m128i) -> __m256i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512msg2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512msg2_epi64(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsha512msg2(a.as_i64x4(), b.as_i64x4())) } } @@ -175,7 +175,7 @@ pub fn _mm256_sha512msg2_epi64(a: __m256i, b: __m256i) -> __m256i { #[inline] #[target_feature(enable = "sha512,avx")] #[cfg_attr(test, assert_instr(vsha512rnds2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sha512rnds2_epi64(a: __m256i, b: __m256i, k: __m128i) -> __m256i { unsafe { transmute(vsha512rnds2(a.as_i64x4(), b.as_i64x4(), k.as_i64x2())) } } @@ -188,7 +188,7 @@ pub fn _mm256_sha512rnds2_epi64(a: __m256i, b: __m256i, k: __m128i) -> __m256i { #[inline] #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3msg1))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3msg1_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(vsm3msg1(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } @@ -201,7 +201,7 @@ pub fn _mm_sm3msg1_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3msg2))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3msg2_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { unsafe { transmute(vsm3msg2(a.as_i32x4(), b.as_i32x4(), c.as_i32x4())) } } @@ -219,7 +219,7 @@ pub fn _mm_sm3msg2_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { #[target_feature(enable = "sm3,avx")] #[cfg_attr(test, assert_instr(vsm3rnds2, IMM8 = 0))] #[rustc_legacy_const_generics(3)] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm3rnds2_epi32(a: __m128i, b: __m128i, c: __m128i) -> __m128i { static_assert!( IMM8 == (IMM8 & 0x3e), @@ -235,7 +235,7 @@ pub fn _mm_sm3rnds2_epi32(a: __m128i, b: __m128i, c: __m128i) - #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4key4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm4key4_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(vsm4key4128(a.as_i32x4(), b.as_i32x4())) } } @@ -247,7 +247,7 @@ pub fn _mm_sm4key4_epi32(a: __m128i, b: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4key4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sm4key4_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsm4key4256(a.as_i32x8(), b.as_i32x8())) } } @@ -259,7 +259,7 @@ pub fn _mm256_sm4key4_epi32(a: __m256i, b: __m256i) -> __m256i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4rnds4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm_sm4rnds4_epi32(a: __m128i, b: __m128i) -> __m128i { unsafe { transmute(vsm4rnds4128(a.as_i32x4(), b.as_i32x4())) } } @@ -271,7 +271,7 @@ pub fn _mm_sm4rnds4_epi32(a: __m128i, b: __m128i) -> __m128i { #[inline] #[target_feature(enable = "sm4,avx")] #[cfg_attr(test, assert_instr(vsm4rnds4))] -#[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "sha512_sm_x86", since = "1.89.0")] pub fn _mm256_sm4rnds4_epi32(a: __m256i, b: __m256i) -> __m256i { unsafe { transmute(vsm4rnds4256(a.as_i32x8(), b.as_i32x8())) } } diff --git a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs index 46a008245bf82..d3e7f62903b32 100644 --- a/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs +++ b/library/stdarch/crates/core_arch/src/x86_64/cmpxchg16b.rs @@ -48,7 +48,7 @@ pub unsafe fn cmpxchg16b( success: Ordering, failure: Ordering, ) -> u128 { - debug_assert!(dst as usize % 16 == 0); + debug_assert!(dst.addr().is_multiple_of(16)); let res = crate::sync::atomic::atomic_compare_exchange(dst, old, new, success, failure); res.unwrap_or_else(|x| x) diff --git a/library/stdarch/crates/intrinsic-test/src/common/compare.rs b/library/stdarch/crates/intrinsic-test/src/common/compare.rs index 815ccf89fc695..9e0cbe8cd6abe 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/compare.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/compare.rs @@ -48,7 +48,7 @@ pub fn compare_outputs( return Some(FailureReason::RunRust(intrinsic_name.clone())); } - info!("Comparing intrinsic: {}", intrinsic_name); + info!("Comparing intrinsic: {intrinsic_name}"); let c = std::str::from_utf8(&c.stdout) .unwrap() diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs index 84c28cc4bf439..1cfb66c39b90f 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_c.rs @@ -79,7 +79,7 @@ pub fn compile_c_programs(compiler_commands: &[String]) -> bool { false } } else { - error!("Command failed: {:#?}", output); + error!("Command failed: {output:#?}"); false } }) diff --git a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs index a2878502ac944..52bccaf905c51 100644 --- a/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs +++ b/library/stdarch/crates/intrinsic-test/src/common/gen_rust.rs @@ -120,7 +120,7 @@ path = "{binary}/main.rs""#, false } } else { - error!("Command failed: {:#?}", output); + error!("Command failed: {output:#?}"); false } } diff --git a/library/stdarch/crates/simd-test-macro/src/lib.rs b/library/stdarch/crates/simd-test-macro/src/lib.rs index 18e4747d94d91..855e969e1eb79 100644 --- a/library/stdarch/crates/simd-test-macro/src/lib.rs +++ b/library/stdarch/crates/simd-test-macro/src/lib.rs @@ -89,7 +89,7 @@ pub fn simd_test( for feature in target_features { let q = quote_spanned! { proc_macro2::Span::call_site() => - if !#macro_test!(#feature) { + if !::std::arch::#macro_test!(#feature) { missing_features.push(#feature); } }; diff --git a/library/stdarch/crates/std_detect/src/detect/arch/x86.rs b/library/stdarch/crates/std_detect/src/detect/arch/x86.rs index f23cfc334170f..28b3e3cfb35b7 100644 --- a/library/stdarch/crates/std_detect/src/detect/arch/x86.rs +++ b/library/stdarch/crates/std_detect/src/detect/arch/x86.rs @@ -157,11 +157,11 @@ features! { /// AVX (Advanced Vector Extensions) @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx2: "avx2"; /// AVX2 (Advanced Vector Extensions 2) - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sha512: "sha512"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sha512: "sha512"; /// SHA512 - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sm3: "sm3"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sm3: "sm3"; /// SM3 - @FEATURE: #[stable(feature = "sha512_sm_x86", since = "CURRENT_RUSTC_VERSION")] sm4: "sm4"; + @FEATURE: #[stable(feature = "sha512_sm_x86", since = "1.89.0")] sm4: "sm4"; /// SM4 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512f: "avx512f" ; /// AVX-512 F (Foundation) @@ -259,9 +259,9 @@ features! { /// XSAVEC (Save Processor Extended States Compacted) @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] cmpxchg16b: "cmpxchg16b"; /// CMPXCH16B (16-byte compare-and-swap instruction) - @FEATURE: #[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] kl: "kl"; + @FEATURE: #[stable(feature = "keylocker_x86", since = "1.89.0")] kl: "kl"; /// Intel Key Locker - @FEATURE: #[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")] widekl: "widekl"; + @FEATURE: #[stable(feature = "keylocker_x86", since = "1.89.0")] widekl: "widekl"; /// Intel Key Locker Wide @FEATURE: #[stable(feature = "simd_x86_adx", since = "1.33.0")] adx: "adx"; /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions) diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs index 5506ff31fc792..db20538af9512 100644 --- a/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs +++ b/library/stdarch/crates/std_detect/src/detect/os/linux/riscv.rs @@ -25,6 +25,13 @@ struct riscv_hwprobe { value: u64, } +impl riscv_hwprobe { + // key is overwritten to -1 if not supported by riscv_hwprobe syscall. + pub fn get(&self) -> Option { + (self.key != -1).then_some(self.value) + } +} + #[allow(non_upper_case_globals)] const __NR_riscv_hwprobe: libc::c_long = 258; @@ -124,8 +131,7 @@ fn _riscv_hwprobe(out: &mut [riscv_hwprobe]) -> bool { } } - let len = out.len(); - unsafe { __riscv_hwprobe(out.as_mut_ptr(), len, 0, ptr::null_mut(), 0) == 0 } + unsafe { __riscv_hwprobe(out.as_mut_ptr(), out.len(), 0, ptr::null_mut(), 0) == 0 } } /// Read list of supported features from (1) the auxiliary vector @@ -156,49 +162,45 @@ pub(crate) fn detect_features() -> cache::Initializer { // Use riscv_hwprobe syscall to query more extensions and // performance-related capabilities. 'hwprobe: { - let mut out = [ - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_BASE_BEHAVIOR, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_IMA_EXT_0, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, - value: 0, - }, - riscv_hwprobe { - key: RISCV_HWPROBE_KEY_CPUPERF_0, - value: 0, - }, - ]; - if !_riscv_hwprobe(&mut out) { + macro_rules! init { + { $($name: ident : $key: expr),* $(,)? } => { + #[repr(usize)] + enum Indices { $($name),* } + let mut t = [$(riscv_hwprobe { key: $key, value: 0 }),*]; + macro_rules! data_mut { () => { &mut t } } + macro_rules! query { [$idx: ident] => { t[Indices::$idx as usize].get() } } + } + } + init! { + BaseBehavior: RISCV_HWPROBE_KEY_BASE_BEHAVIOR, + Extensions: RISCV_HWPROBE_KEY_IMA_EXT_0, + MisalignedScalarPerf: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF, + MisalignedVectorPerf: RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, + MisalignedScalarPerfFallback: RISCV_HWPROBE_KEY_CPUPERF_0, + }; + if !_riscv_hwprobe(data_mut!()) { break 'hwprobe; } - // Query scalar/vector misaligned behavior. - if out[2].key != -1 { + // Query scalar misaligned behavior. + if let Some(value) = query![MisalignedScalarPerf] { enable_feature( Feature::unaligned_scalar_mem, - out[2].value == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST, + value == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST, ); - } else if out[4].key != -1 { + } else if let Some(value) = query![MisalignedScalarPerfFallback] { // Deprecated method for fallback enable_feature( Feature::unaligned_scalar_mem, - out[4].value & RISCV_HWPROBE_MISALIGNED_MASK == RISCV_HWPROBE_MISALIGNED_FAST, + value & RISCV_HWPROBE_MISALIGNED_MASK == RISCV_HWPROBE_MISALIGNED_FAST, ); } - if out[3].key != -1 { + + // Query vector misaligned behavior. + if let Some(value) = query![MisalignedVectorPerf] { enable_feature( Feature::unaligned_vector_mem, - out[3].value == RISCV_HWPROBE_MISALIGNED_VECTOR_FAST, + value == RISCV_HWPROBE_MISALIGNED_VECTOR_FAST, ); } @@ -208,22 +210,20 @@ pub(crate) fn detect_features() -> cache::Initializer { // 20240411). // This is a current requirement of // `RISCV_HWPROBE_KEY_IMA_EXT_0`-based tests. - let has_ima = (out[0].key != -1) && (out[0].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA != 0); - if !has_ima { + if query![BaseBehavior].is_none_or(|value| value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA == 0) { break 'hwprobe; } - has_i |= has_ima; - enable_feature(Feature::zicsr, has_ima); - enable_feature(Feature::zicntr, has_ima); - enable_feature(Feature::zifencei, has_ima); - enable_feature(Feature::m, has_ima); - enable_feature(Feature::a, has_ima); + has_i = true; + enable_feature(Feature::zicsr, true); + enable_feature(Feature::zicntr, true); + enable_feature(Feature::zifencei, true); + enable_feature(Feature::m, true); + enable_feature(Feature::a, true); // Enable features based on `RISCV_HWPROBE_KEY_IMA_EXT_0`. - if out[1].key == -1 { + let Some(ima_ext_0) = query![Extensions] else { break 'hwprobe; - } - let ima_ext_0 = out[1].value; + }; let test = |mask| (ima_ext_0 & mask) != 0; enable_feature(Feature::d, test(RISCV_HWPROBE_IMA_FD)); // F is implied. diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index f658267b9a19b..f0dce681d9c30 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -1252,7 +1252,7 @@ intrinsics: - [i16, f16, 'h', 'i32', 'as i32'] compose: - FnCall: [static_assert!, ['N >= 1 && N <= 16']] - - "vcvt{type[2]}_n_{type[1]}_{type[3]}::(a {type[4]}) as {type[1]}" + - "vcvt{type[2]}_n_{type[1]}_{type[3]}::(a {type[4]})" - name: "vcvt{type[2]}_n_{type[1]}_{type[0]}" @@ -1270,7 +1270,7 @@ intrinsics: - [u16, f16, 'h', u32] compose: - FnCall: [static_assert!, ['N >= 1 && N <= 16']] - - "vcvt{type[2]}_n_{type[1]}_{type[3]}::(a as {type[3]}) as {type[1]}" + - "vcvt{type[2]}_n_{type[1]}_{type[3]}::(a as {type[3]})" - name: "vcvt{type[2]}" @@ -2976,11 +2976,7 @@ intrinsics: - float64x1_t - float64x2_t compose: - - LLVMLink: - name: "llvm.rint.{neon_type}" - links: - - link: "llvm.rint.{neon_type}" - arch: aarch64,arm64ec + - FnCall: [simd_round_ties_even, [a]] - name: "vrndx{neon_type.no}" @@ -2996,11 +2992,7 @@ intrinsics: - float16x4_t - float16x8_t compose: - - LLVMLink: - name: "llvm.rint.{neon_type}" - links: - - link: "llvm.rint.{neon_type}" - arch: aarch64,arm64ec + - FnCall: [simd_round_ties_even, [a]] - name: "vrndx{type[1]}{type[0]}" @@ -5391,7 +5383,7 @@ intrinsics: attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 static_defs: ["const LANE: i32"] safety: safe @@ -5444,7 +5436,7 @@ intrinsics: attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx, 'LANE = 0']]}]] - FnCall: [rustc_legacy_const_generics, ['2']] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 static_defs: ["const LANE: i32"] safety: safe @@ -5468,7 +5460,7 @@ intrinsics: return_type: "{neon_type[0]}" attr: - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [fmulx]]}]] - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 safety: safe types: @@ -5552,7 +5544,7 @@ intrinsics: arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {type[1]}"] return_type: "{neon_type[0]}" attr: - - *neon-fp16 + - *neon-fp16 - *neon-unstable-f16 assert_instr: [fmla] safety: safe @@ -7320,7 +7312,7 @@ intrinsics: - ["i64", "i32", "i32", "i64"] compose: - Let: [x, i64, {FnCall: [vqaddd_s64, [a, {FnCall: [vqdmulls_s32, [b, c]]}]]}] - - Identifier: ['x as i64', Symbol] + - Identifier: ['x', Symbol] - name: "vqdmlal{type[4]}" doc: "Signed saturating doubling multiply-add long" @@ -7434,7 +7426,7 @@ intrinsics: - ["i64", "i32", "i32", "i64"] compose: - Let: [x, i64, {FnCall: [vqsubd_s64, [a, {FnCall: [vqdmulls_s32, [b, c]]}]]}] - - Identifier: ['x as i64', Symbol] + - Identifier: ['x', Symbol] - name: "vqdmlsl{type[4]}" doc: "Signed saturating doubling multiply-subtract long" @@ -11697,7 +11689,6 @@ intrinsics: arguments: ["a: {type[1]}"] return_type: "{type[1]}" attr: - - *neon-fp16 - FnCall: [cfg_attr, [test, {FnCall: [assert_instr, [frsqrte]]}]] - *neon-fp16 - *neon-unstable-f16 @@ -12104,7 +12095,7 @@ intrinsics: - [uint8x8_t, 'uint8x8_t', 'b'] - [poly8x8_t, 'uint8x8_t', 'b'] compose: - - FnCall: + - FnCall: - 'vqtbl1{neon_type[0].no}' - - FnCall: - 'vcombine{neon_type[0].no}' @@ -12174,7 +12165,7 @@ intrinsics: - '{type[2]}_t' - - FnCall: ['vcombine{neon_type[1].no}', ['a.0', 'a.1']] - FnCall: ['vcombine{neon_type[1].no}', ['a.2', 'unsafe {{ crate::mem::zeroed() }}']] - - FnCall: + - FnCall: - transmute - - FnCall: - vqtbl2 @@ -12193,7 +12184,7 @@ intrinsics: types: - [uint8x8x3_t, 'uint8x8_t', 'uint8x16x2', 'uint8x8_t'] - [poly8x8x3_t, 'uint8x8_t', 'poly8x16x2', 'poly8x8_t'] - big_endian_inverse: true + big_endian_inverse: true compose: - Let: - x @@ -12201,7 +12192,7 @@ intrinsics: - '{type[2]}_t' - - FnCall: ['vcombine{neon_type[3].no}', ['a.0', 'a.1']] - FnCall: ['vcombine{neon_type[3].no}', ['a.2', 'unsafe {{ crate::mem::zeroed() }}']] - - FnCall: + - FnCall: - transmute - - FnCall: - vqtbl2 @@ -12288,18 +12279,16 @@ intrinsics: - [poly8x8_t, "poly8x16_t", uint8x8_t, "vqtbx1", "_p8"] - [uint8x16_t, "uint8x16_t", uint8x16_t, "vqtbx1q", "q_u8"] - [poly8x16_t, "poly8x16_t", uint8x16_t, "vqtbx1q", "q_p8"] + big_endian_inverse: false compose: - - Let: - - x - - FnCall: - - transmute - - - FnCall: - - "{type[3]}" - - - FnCall: [transmute, [a]] - - FnCall: [transmute, [b]] - - c - - Identifier: [x, Symbol] - + - FnCall: + - transmute + - - FnCall: + - "{type[3]}" + - - FnCall: [transmute, [a]] + - FnCall: [transmute, [b]] + - c + - name: "vtbx1{neon_type[0].no}" doc: "Extended table look-up" arguments: ["a: {neon_type[0]}", "b: {neon_type[0]}", "c: {neon_type[1]}"] @@ -12315,13 +12304,13 @@ intrinsics: compose: - FnCall: - simd_select - - - FnCall: + - - FnCall: - "simd_lt::<{type[4]}_t, int8x8_t>" - - c - FnCall: [transmute, ["{type[3]}"]] - FnCall: - transmute - - - FnCall: + - - FnCall: - "vqtbx1" - - "transmute(a)" - FnCall: @@ -12470,16 +12459,14 @@ intrinsics: - ['poly8x16_t', uint8x8_t, 'vqtbl1', 'poly8x8_t'] - ['uint8x16_t', uint8x16_t, 'vqtbl1q', 'uint8x16_t'] - ['poly8x16_t', uint8x16_t, 'vqtbl1q', 'poly8x16_t'] + big_endian_inverse: false compose: - - Let: - - x - - FnCall: - - transmute - - - FnCall: - - '{type[2]}' - - - FnCall: [transmute, ['a']] - - b - - Identifier: [x, Symbol] + - FnCall: + - transmute + - - FnCall: + - '{type[2]}' + - - FnCall: [transmute, ['a']] + - b - name: "vqtbl2{neon_type[3].no}" doc: "Table look-up" @@ -12511,7 +12498,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[2]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12547,7 +12534,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -12584,7 +12571,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12621,7 +12608,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -12659,7 +12646,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[2]}' - - FnCall: [transmute, ['a.0']] - FnCall: [transmute, ['a.1']] @@ -12697,7 +12684,7 @@ intrinsics: compose: - FnCall: - transmute - - - FnCall: + - - FnCall: - '{type[3]}' - - FnCall: [transmute, [a]] - FnCall: [transmute, ['b.0']] @@ -13204,7 +13191,7 @@ intrinsics: assert_instr: [addp] safety: safe types: - - [int32x2_t, i32] + - [int32x2_t, i32] compose: - LLVMLink: name: "vaddv{neon_type[0].no}" @@ -13259,7 +13246,7 @@ intrinsics: assert_instr: [addp] safety: safe types: - - [uint32x2_t, u32, i32] + - [uint32x2_t, u32, i32] compose: - LLVMLink: name: "vaddv{neon_type[0].no}" @@ -13335,7 +13322,7 @@ intrinsics: types: - [int8x8_t, i8, 'smaxv'] - [int16x4_t, i16, 'smaxv'] - - [int32x2_t, i32, 'smaxp'] + - [int32x2_t, i32, 'smaxp'] - [int8x16_t, i8, 'smaxv'] - [int16x8_t, i16, 'smaxv'] - [int32x4_t, i32, 'smaxv'] @@ -13357,7 +13344,7 @@ intrinsics: types: - [uint8x8_t, u8, 'umaxv'] - [uint16x4_t, u16, 'umaxv'] - - [uint32x2_t, u32, 'umaxp'] + - [uint32x2_t, u32, 'umaxp'] - [uint8x16_t, u8, 'umaxv'] - [uint16x8_t, u16, 'umaxv'] - [uint32x4_t, u32, 'umaxv'] @@ -13379,7 +13366,7 @@ intrinsics: types: - [float32x2_t, f32, 'fmaxp'] - [float32x4_t, f32, 'fmaxv'] - - [float64x2_t, f64, 'fmaxp'] + - [float64x2_t, f64, 'fmaxp'] compose: - LLVMLink: name: "vmaxv{neon_type[0].no}" @@ -13398,7 +13385,7 @@ intrinsics: types: - [int8x8_t, i8, 'sminv'] - [int16x4_t, i16, 'sminv'] - - [int32x2_t, i32, 'sminp'] + - [int32x2_t, i32, 'sminp'] - [int8x16_t, i8, 'sminv'] - [int16x8_t, i16, 'sminv'] - [int32x4_t, i32, 'sminv'] @@ -13420,7 +13407,7 @@ intrinsics: types: - [uint8x8_t, u8, 'uminv'] - [uint16x4_t, u16, 'uminv'] - - [uint32x2_t, u32, 'uminp'] + - [uint32x2_t, u32, 'uminp'] - [uint8x16_t, u8, 'uminv'] - [uint16x8_t, u16, 'uminv'] - [uint32x4_t, u32, 'uminv'] @@ -13442,7 +13429,7 @@ intrinsics: types: - [float32x2_t, f32, 'fminp'] - [float32x4_t, f32, 'fminv'] - - [float64x2_t, f64, 'fminp'] + - [float64x2_t, f64, 'fminp'] compose: - LLVMLink: name: "vminv{neon_type[0].no}" @@ -13498,7 +13485,7 @@ intrinsics: safety: safe types: - float32x4_t - - float64x2_t + - float64x2_t compose: - LLVMLink: name: "vpmin{neon_type.no}" @@ -13554,7 +13541,7 @@ intrinsics: safety: safe types: - float32x4_t - - float64x2_t + - float64x2_t compose: - LLVMLink: name: "vpmax{neon_type.no}" diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml index 118f5808f758f..07959cf380e8a 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/arm_shared.spec.yml @@ -11447,14 +11447,14 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N as i32, N as i32]) }'] + - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }'] + - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }'] + - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }'] - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }'] - - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }'] - - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64, N as i64]) }'] + - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }'] + - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }'] + - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }'] + - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]] - LLVMLink: @@ -11479,14 +11479,14 @@ intrinsics: static_defs: ['const N: i32'] safety: safe types: - - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N as i32, N as i32]) }'] + - [int8x8_t, uint8x8_t, '3', 'const { int8x8_t([N as i8; 8]) }'] + - [int16x4_t, uint16x4_t, '4', 'const { int16x4_t([N as i16; 4]) }'] + - [int32x2_t, uint32x2_t, '5', 'const { int32x2_t([N; 2]) }'] - [int64x1_t, uint64x1_t, '6', 'const { int64x1_t([N as i64]) }'] - - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8, N as i8]) }'] - - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16, N as i16]) }'] - - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N as i32, N as i32, N as i32, N as i32]) }'] - - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64, N as i64]) }'] + - [int8x16_t, uint8x16_t, '3', 'const { int8x16_t([N as i8; 16]) }'] + - [int16x8_t, uint16x8_t, '4', 'const { int16x8_t([N as i16; 8]) }'] + - [int32x4_t, uint32x4_t, '5', 'const { int32x4_t([N; 4]) }'] + - [int64x2_t, uint64x2_t, '6', 'const { int64x2_t([N as i64; 2]) }'] compose: - FnCall: [static_assert_uimm_bits!, [N, "{type[2]}"]] - LLVMLink: diff --git a/library/stdarch/josh-sync.toml b/library/stdarch/josh-sync.toml new file mode 100644 index 0000000000000..ebdb4576287c8 --- /dev/null +++ b/library/stdarch/josh-sync.toml @@ -0,0 +1,3 @@ +org = "rust-lang" +repo = "stdarch" +path = "library/stdarch" diff --git a/library/stdarch/rust-version b/library/stdarch/rust-version new file mode 100644 index 0000000000000..5102178848e7f --- /dev/null +++ b/library/stdarch/rust-version @@ -0,0 +1 @@ +040e2f8b9ff2d76fbe2146d6003e297ed4532088 diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 3adc022497167..290c2eeed44c6 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -5,6 +5,10 @@ name = "sysroot" version = "0.0.0" edition = "2024" +[lib] +# make sure this crate isn't included in public standard library docs +doc = false + # this is a dummy crate to ensure that all required crates appear in the sysroot [dependencies] proc_macro = { path = "../proc_macro", public = true } @@ -22,7 +26,6 @@ compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] compiler-builtins-no-f16-f128 = ["std/compiler-builtins-no-f16-f128"] compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] debug_refcell = ["std/debug_refcell"] -debug_typeid = ["std/debug_typeid"] llvm-libunwind = ["std/llvm-libunwind"] system-llvm-libunwind = ["std/system-llvm-libunwind"] optimize_for_size = ["std/optimize_for_size"] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index bd9f86aee7475..fed6a6a6c8410 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -2,5 +2,5 @@ # standard library we currently track. [toolchain] -channel = "nightly-2025-07-10" +channel = "nightly-2025-07-14" components = ["llvm-tools-preview", "rustc-dev", "rust-src", "rustfmt"] diff --git a/tool_config/kani-version.toml b/tool_config/kani-version.toml index 004d4645e4e5f..a3cb1b760376d 100644 --- a/tool_config/kani-version.toml +++ b/tool_config/kani-version.toml @@ -2,4 +2,4 @@ # incompatible with the verify-std repo. [kani] -commit = "533403efc3a2eef94e13d67f214ee25a6fb21b41" +commit = "5af25b54e695e0480887ab2e978cd4dd05b7154c"