From 4b7f56ac9dd3db6163f26ab7b5e28b55756fef79 Mon Sep 17 00:00:00 2001 From: Kornel Date: Sat, 2 Nov 2024 11:05:01 +0000 Subject: [PATCH 01/10] Fix and undeprecate home_dir() --- library/std/src/env.rs | 16 ++++++---------- library/std/src/sys/pal/windows/os.rs | 4 ++-- library/std/tests/env.rs | 12 ++++++------ 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index d732a15117e9..eefae253e9b6 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -608,20 +608,16 @@ impl Error for JoinPathsError { /// /// # Windows /// -/// - Returns the value of the 'HOME' environment variable if it is set -/// (including to an empty string). -/// - Otherwise, returns the value of the 'USERPROFILE' environment variable if it is set -/// (including to an empty string). -/// - If both do not exist, [`GetUserProfileDirectory`][msdn] is used to return the path. +/// - Returns the value of the 'USERPROFILE' environment variable if it is set, and is not an empty string. +/// - Otherwise, [`GetUserProfileDirectory`][msdn] is used to return the path. This may change in the future. /// /// [msdn]: https://docs.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectorya /// -/// # Deprecation +/// In UWP (Universal Windows Platform) targets this function is unimplemented and always returns `None`. /// -/// This function is deprecated because the behavior on Windows is not correct. -/// The 'HOME' environment variable is not standard on Windows, and may not produce -/// desired results; for instance, under Cygwin or Mingw it will return `/home/you` -/// when it should return `C:\Users\you`. +/// Before Rust CURRENT_RUSTC_VERSION, this function used to return the value of the 'HOME' environment variable +/// on Windows, which in Cygwin or Mingw environments could return non-standard paths like `/home/you` +/// instead of `C:\Users\you`. /// /// # Examples /// diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 5242bc9da31f..5231a34469ab 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -377,8 +377,8 @@ fn home_dir_crt() -> Option { } pub fn home_dir() -> Option { - crate::env::var_os("HOME") - .or_else(|| crate::env::var_os("USERPROFILE")) + crate::env::var_os("USERPROFILE") + .filter(|s| !s.is_empty()) .map(PathBuf::from) .or_else(home_dir_crt) } diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs index 4e472b4ce995..44fe84c989fb 100644 --- a/library/std/tests/env.rs +++ b/library/std/tests/env.rs @@ -122,19 +122,19 @@ fn env_home_dir() { assert!(home_dir().is_some()); - set_var("HOME", "/home/MountainView"); + set_var("HOME", "/home/PaloAlto"); + assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used"); + + set_var("USERPROFILE", "/home/MountainView"); assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); remove_var("HOME"); - set_var("USERPROFILE", "/home/MountainView"); assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); - set_var("HOME", "/home/MountainView"); - set_var("USERPROFILE", "/home/PaloAlto"); - assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + set_var("USERPROFILE", ""); + assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored"); - remove_var("HOME"); remove_var("USERPROFILE"); if let Some(oldhome) = oldhome { set_var("HOME", oldhome); } From 5eb65530033817f3007d016e34cea5077f4d723d Mon Sep 17 00:00:00 2001 From: "aaishwarymishra@gmail.com" Date: Sat, 16 Nov 2024 19:40:39 +0530 Subject: [PATCH 02/10] changes old intrinsic declaration to new declaration blesses tests/ui/intrinsics blesses tests/ui/intrinsics --- library/core/src/intrinsics/mod.rs | 1544 ++++++++++++-------- tests/ui/intrinsics/reify-intrinsic.stderr | 2 +- 2 files changed, 950 insertions(+), 596 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index e9859a58696d..ee4bf12d0df0 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2039,628 +2039,982 @@ pub fn ptr_mask(_ptr: *const T, _mask: usize) -> *const T { unreachable!() } -extern "rust-intrinsic" { - /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with - /// a size of `count` * `size_of::()` and an alignment of - /// `min_align_of::()` - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); - /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with - /// a size of `count * size_of::()` and an alignment of - /// `min_align_of::()` - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_copy_memory(dst: *mut T, src: *const T, count: usize); - /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a - /// size of `count * size_of::()` and an alignment of - /// `min_align_of::()`. - /// - /// The volatile parameter is set to `true`, so it will not be optimized out - /// unless size is equal to zero. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn volatile_set_memory(dst: *mut T, val: u8, count: usize); +/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with +/// a size of `count` * `size_of::()` and an alignment of +/// `min_align_of::()` +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_copy_nonoverlapping_memory(_dst: *mut T, _src: *const T, _count: usize) { + unreachable!() +} +/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with +/// a size of `count * size_of::()` and an alignment of +/// `min_align_of::()` +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_copy_memory(_dst: *mut T, _src: *const T, _count: usize) { + unreachable!() +} +/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a +/// size of `count * size_of::()` and an alignment of +/// `min_align_of::()`. +/// +/// The volatile parameter is set to `true`, so it will not be optimized out +/// unless size is equal to zero. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_set_memory(_dst: *mut T, _val: u8, _count: usize) { + unreachable!() +} - /// Performs a volatile load from the `src` pointer. - /// - /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. - #[rustc_nounwind] - pub fn volatile_load(src: *const T) -> T; - /// Performs a volatile store to the `dst` pointer. - /// - /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. - #[rustc_nounwind] - pub fn volatile_store(dst: *mut T, val: T); +/// Performs a volatile load from the `src` pointer. +/// +/// The stabilized version of this intrinsic is [`core::ptr::read_volatile`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_load(_src: *const T) -> T { + unreachable!() +} +/// Performs a volatile store to the `dst` pointer. +/// +/// The stabilized version of this intrinsic is [`core::ptr::write_volatile`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn volatile_store(_dst: *mut T, _val: T) { + unreachable!() +} - /// Performs a volatile load from the `src` pointer - /// The pointer is not required to be aligned. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] - pub fn unaligned_volatile_load(src: *const T) -> T; - /// Performs a volatile store to the `dst` pointer. - /// The pointer is not required to be aligned. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] - pub fn unaligned_volatile_store(dst: *mut T, val: T); +/// Performs a volatile load from the `src` pointer +/// The pointer is not required to be aligned. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"] +pub unsafe fn unaligned_volatile_load(_src: *const T) -> T { + unreachable!() +} +/// Performs a volatile store to the `dst` pointer. +/// The pointer is not required to be aligned. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] +pub unsafe fn unaligned_volatile_store(_dst: *mut T, _val: T) { + unreachable!() +} - /// Returns the square root of an `f16` - /// - /// The stabilized version of this intrinsic is - /// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf16(x: f16) -> f16; - /// Returns the square root of an `f32` - /// - /// The stabilized version of this intrinsic is - /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf32(x: f32) -> f32; - /// Returns the square root of an `f64` - /// - /// The stabilized version of this intrinsic is - /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf64(x: f64) -> f64; - /// Returns the square root of an `f128` - /// - /// The stabilized version of this intrinsic is - /// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) - #[rustc_nounwind] - pub fn sqrtf128(x: f128) -> f128; +/// Returns the square root of an `f16` +/// +/// The stabilized version of this intrinsic is +/// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the square root of an `f32` +/// +/// The stabilized version of this intrinsic is +/// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the square root of an `f64` +/// +/// The stabilized version of this intrinsic is +/// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the square root of an `f128` +/// +/// The stabilized version of this intrinsic is +/// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sqrtf128(_x: f128) -> f128 { + unreachable!() +} - /// Raises an `f16` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f16::powi`](../../std/primitive.f16.html#method.powi) - #[rustc_nounwind] - pub fn powif16(a: f16, x: i32) -> f16; - /// Raises an `f32` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f32::powi`](../../std/primitive.f32.html#method.powi) - #[rustc_nounwind] - pub fn powif32(a: f32, x: i32) -> f32; - /// Raises an `f64` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f64::powi`](../../std/primitive.f64.html#method.powi) - #[rustc_nounwind] - pub fn powif64(a: f64, x: i32) -> f64; - /// Raises an `f128` to an integer power. - /// - /// The stabilized version of this intrinsic is - /// [`f128::powi`](../../std/primitive.f128.html#method.powi) - #[rustc_nounwind] - pub fn powif128(a: f128, x: i32) -> f128; +/// Raises an `f16` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f16::powi`](../../std/primitive.f16.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif16(_a: f16, _x: i32) -> f16 { + unreachable!() +} +/// Raises an `f32` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f32::powi`](../../std/primitive.f32.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif32(_a: f32, _x: i32) -> f32 { + unreachable!() +} +/// Raises an `f64` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f64::powi`](../../std/primitive.f64.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif64(_a: f64, _x: i32) -> f64 { + unreachable!() +} +/// Raises an `f128` to an integer power. +/// +/// The stabilized version of this intrinsic is +/// [`f128::powi`](../../std/primitive.f128.html#method.powi) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powif128(_a: f128, _x: i32) -> f128 { + unreachable!() +} - /// Returns the sine of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::sin`](../../std/primitive.f16.html#method.sin) - #[rustc_nounwind] - pub fn sinf16(x: f16) -> f16; - /// Returns the sine of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::sin`](../../std/primitive.f32.html#method.sin) - #[rustc_nounwind] - pub fn sinf32(x: f32) -> f32; - /// Returns the sine of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::sin`](../../std/primitive.f64.html#method.sin) - #[rustc_nounwind] - pub fn sinf64(x: f64) -> f64; - /// Returns the sine of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::sin`](../../std/primitive.f128.html#method.sin) - #[rustc_nounwind] - pub fn sinf128(x: f128) -> f128; +/// Returns the sine of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::sin`](../../std/primitive.f16.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the sine of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::sin`](../../std/primitive.f32.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the sine of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::sin`](../../std/primitive.f64.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the sine of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::sin`](../../std/primitive.f128.html#method.sin) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn sinf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the cosine of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::cos`](../../std/primitive.f16.html#method.cos) - #[rustc_nounwind] - pub fn cosf16(x: f16) -> f16; - /// Returns the cosine of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::cos`](../../std/primitive.f32.html#method.cos) - #[rustc_nounwind] - pub fn cosf32(x: f32) -> f32; - /// Returns the cosine of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::cos`](../../std/primitive.f64.html#method.cos) - #[rustc_nounwind] - pub fn cosf64(x: f64) -> f64; - /// Returns the cosine of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::cos`](../../std/primitive.f128.html#method.cos) - #[rustc_nounwind] - pub fn cosf128(x: f128) -> f128; +/// Returns the cosine of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::cos`](../../std/primitive.f16.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the cosine of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::cos`](../../std/primitive.f32.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the cosine of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::cos`](../../std/primitive.f64.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the cosine of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::cos`](../../std/primitive.f128.html#method.cos) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn cosf128(_x: f128) -> f128 { + unreachable!() +} - /// Raises an `f16` to an `f16` power. - /// - /// The stabilized version of this intrinsic is - /// [`f16::powf`](../../std/primitive.f16.html#method.powf) - #[rustc_nounwind] - pub fn powf16(a: f16, x: f16) -> f16; - /// Raises an `f32` to an `f32` power. - /// - /// The stabilized version of this intrinsic is - /// [`f32::powf`](../../std/primitive.f32.html#method.powf) - #[rustc_nounwind] - pub fn powf32(a: f32, x: f32) -> f32; - /// Raises an `f64` to an `f64` power. - /// - /// The stabilized version of this intrinsic is - /// [`f64::powf`](../../std/primitive.f64.html#method.powf) - #[rustc_nounwind] - pub fn powf64(a: f64, x: f64) -> f64; - /// Raises an `f128` to an `f128` power. - /// - /// The stabilized version of this intrinsic is - /// [`f128::powf`](../../std/primitive.f128.html#method.powf) - #[rustc_nounwind] - pub fn powf128(a: f128, x: f128) -> f128; +/// Raises an `f16` to an `f16` power. +/// +/// The stabilized version of this intrinsic is +/// [`f16::powf`](../../std/primitive.f16.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf16(_a: f16, _x: f16) -> f16 { + unreachable!() +} +/// Raises an `f32` to an `f32` power. +/// +/// The stabilized version of this intrinsic is +/// [`f32::powf`](../../std/primitive.f32.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf32(_a: f32, _x: f32) -> f32 { + unreachable!() +} +/// Raises an `f64` to an `f64` power. +/// +/// The stabilized version of this intrinsic is +/// [`f64::powf`](../../std/primitive.f64.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf64(_a: f64, _x: f64) -> f64 { + unreachable!() +} +/// Raises an `f128` to an `f128` power. +/// +/// The stabilized version of this intrinsic is +/// [`f128::powf`](../../std/primitive.f128.html#method.powf) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn powf128(_a: f128, _x: f128) -> f128 { + unreachable!() +} - /// Returns the exponential of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::exp`](../../std/primitive.f16.html#method.exp) - #[rustc_nounwind] - pub fn expf16(x: f16) -> f16; - /// Returns the exponential of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::exp`](../../std/primitive.f32.html#method.exp) - #[rustc_nounwind] - pub fn expf32(x: f32) -> f32; - /// Returns the exponential of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::exp`](../../std/primitive.f64.html#method.exp) - #[rustc_nounwind] - pub fn expf64(x: f64) -> f64; - /// Returns the exponential of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::exp`](../../std/primitive.f128.html#method.exp) - #[rustc_nounwind] - pub fn expf128(x: f128) -> f128; +/// Returns the exponential of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::exp`](../../std/primitive.f16.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the exponential of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::exp`](../../std/primitive.f32.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the exponential of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::exp`](../../std/primitive.f64.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the exponential of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::exp`](../../std/primitive.f128.html#method.exp) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn expf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns 2 raised to the power of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f16(x: f16) -> f16; - /// Returns 2 raised to the power of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f32(x: f32) -> f32; - /// Returns 2 raised to the power of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f64(x: f64) -> f64; - /// Returns 2 raised to the power of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) - #[rustc_nounwind] - pub fn exp2f128(x: f128) -> f128; +/// Returns 2 raised to the power of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns 2 raised to the power of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns 2 raised to the power of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns 2 raised to the power of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn exp2f128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the natural logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::ln`](../../std/primitive.f16.html#method.ln) - #[rustc_nounwind] - pub fn logf16(x: f16) -> f16; - /// Returns the natural logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::ln`](../../std/primitive.f32.html#method.ln) - #[rustc_nounwind] - pub fn logf32(x: f32) -> f32; - /// Returns the natural logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::ln`](../../std/primitive.f64.html#method.ln) - #[rustc_nounwind] - pub fn logf64(x: f64) -> f64; - /// Returns the natural logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::ln`](../../std/primitive.f128.html#method.ln) - #[rustc_nounwind] - pub fn logf128(x: f128) -> f128; +/// Returns the natural logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::ln`](../../std/primitive.f16.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the natural logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::ln`](../../std/primitive.f32.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the natural logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::ln`](../../std/primitive.f64.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the natural logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::ln`](../../std/primitive.f128.html#method.ln) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn logf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the base 10 logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::log10`](../../std/primitive.f16.html#method.log10) - #[rustc_nounwind] - pub fn log10f16(x: f16) -> f16; - /// Returns the base 10 logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::log10`](../../std/primitive.f32.html#method.log10) - #[rustc_nounwind] - pub fn log10f32(x: f32) -> f32; - /// Returns the base 10 logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::log10`](../../std/primitive.f64.html#method.log10) - #[rustc_nounwind] - pub fn log10f64(x: f64) -> f64; - /// Returns the base 10 logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::log10`](../../std/primitive.f128.html#method.log10) - #[rustc_nounwind] - pub fn log10f128(x: f128) -> f128; +/// Returns the base 10 logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::log10`](../../std/primitive.f16.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::log10`](../../std/primitive.f32.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::log10`](../../std/primitive.f64.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the base 10 logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::log10`](../../std/primitive.f128.html#method.log10) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log10f128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the base 2 logarithm of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::log2`](../../std/primitive.f16.html#method.log2) - #[rustc_nounwind] - pub fn log2f16(x: f16) -> f16; - /// Returns the base 2 logarithm of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::log2`](../../std/primitive.f32.html#method.log2) - #[rustc_nounwind] - pub fn log2f32(x: f32) -> f32; - /// Returns the base 2 logarithm of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::log2`](../../std/primitive.f64.html#method.log2) - #[rustc_nounwind] - pub fn log2f64(x: f64) -> f64; - /// Returns the base 2 logarithm of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::log2`](../../std/primitive.f128.html#method.log2) - #[rustc_nounwind] - pub fn log2f128(x: f128) -> f128; +/// Returns the base 2 logarithm of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::log2`](../../std/primitive.f16.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::log2`](../../std/primitive.f32.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::log2`](../../std/primitive.f64.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the base 2 logarithm of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::log2`](../../std/primitive.f128.html#method.log2) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn log2f128(_x: f128) -> f128 { + unreachable!() +} - /// Returns `a * b + c` for `f16` values. - /// - /// The stabilized version of this intrinsic is - /// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf16(a: f16, b: f16, c: f16) -> f16; - /// Returns `a * b + c` for `f32` values. - /// - /// The stabilized version of this intrinsic is - /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf32(a: f32, b: f32, c: f32) -> f32; - /// Returns `a * b + c` for `f64` values. - /// - /// The stabilized version of this intrinsic is - /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf64(a: f64, b: f64, c: f64) -> f64; - /// Returns `a * b + c` for `f128` values. - /// - /// The stabilized version of this intrinsic is - /// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) - #[rustc_nounwind] - pub fn fmaf128(a: f128, b: f128, c: f128) -> f128; +/// Returns `a * b + c` for `f16` values. +/// +/// The stabilized version of this intrinsic is +/// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf16(_a: f16, _b: f16, _c: f16) -> f16 { + unreachable!() +} +/// Returns `a * b + c` for `f32` values. +/// +/// The stabilized version of this intrinsic is +/// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf32(_a: f32, _b: f32, _c: f32) -> f32 { + unreachable!() +} +/// Returns `a * b + c` for `f64` values. +/// +/// The stabilized version of this intrinsic is +/// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf64(_a: f64, _b: f64, _c: f64) -> f64 { + unreachable!() +} +/// Returns `a * b + c` for `f128` values. +/// +/// The stabilized version of this intrinsic is +/// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmaf128(_a: f128, _b: f128, _c: f128) -> f128 { + unreachable!() +} - /// Returns `a * b + c` for `f16` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; - /// Returns `a * b + c` for `f32` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; - /// Returns `a * b + c` for `f64` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; - /// Returns `a * b + c` for `f128` values, non-deterministically executing - /// either a fused multiply-add or two operations with rounding of the - /// intermediate result. - /// - /// The operation is fused if the code generator determines that target - /// instruction set has support for a fused operation, and that the fused - /// operation is more efficient than the equivalent, separate pair of mul - /// and add instructions. It is unspecified whether or not a fused operation - /// is selected, and that may depend on optimization level and context, for - /// example. - #[rustc_nounwind] - pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; +/// Returns `a * b + c` for `f16` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf16(_a: f16, _b: f16, _c: f16) -> f16 { + unreachable!() +} +/// Returns `a * b + c` for `f32` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf32(_a: f32, _b: f32, _c: f32) -> f32 { + unreachable!() +} +/// Returns `a * b + c` for `f64` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf64(_a: f64, _b: f64, _c: f64) -> f64 { + unreachable!() +} +/// Returns `a * b + c` for `f128` values, non-deterministically executing +/// either a fused multiply-add or two operations with rounding of the +/// intermediate result. +/// +/// The operation is fused if the code generator determines that target +/// instruction set has support for a fused operation, and that the fused +/// operation is more efficient than the equivalent, separate pair of mul +/// and add instructions. It is unspecified whether or not a fused operation +/// is selected, and that may depend on optimization level and context, for +/// example. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmuladdf128(_a: f128, _b: f128, _c: f128) -> f128 { + unreachable!() +} - /// Returns the largest integer less than or equal to an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::floor`](../../std/primitive.f16.html#method.floor) - #[rustc_nounwind] - pub fn floorf16(x: f16) -> f16; - /// Returns the largest integer less than or equal to an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::floor`](../../std/primitive.f32.html#method.floor) - #[rustc_nounwind] - pub fn floorf32(x: f32) -> f32; - /// Returns the largest integer less than or equal to an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::floor`](../../std/primitive.f64.html#method.floor) - #[rustc_nounwind] - pub fn floorf64(x: f64) -> f64; - /// Returns the largest integer less than or equal to an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::floor`](../../std/primitive.f128.html#method.floor) - #[rustc_nounwind] - pub fn floorf128(x: f128) -> f128; +/// Returns the largest integer less than or equal to an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::floor`](../../std/primitive.f16.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::floor`](../../std/primitive.f32.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::floor`](../../std/primitive.f64.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the largest integer less than or equal to an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::floor`](../../std/primitive.f128.html#method.floor) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn floorf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the smallest integer greater than or equal to an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf16(x: f16) -> f16; - /// Returns the smallest integer greater than or equal to an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf32(x: f32) -> f32; - /// Returns the smallest integer greater than or equal to an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf64(x: f64) -> f64; - /// Returns the smallest integer greater than or equal to an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) - #[rustc_nounwind] - pub fn ceilf128(x: f128) -> f128; +/// Returns the smallest integer greater than or equal to an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the smallest integer greater than or equal to an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn ceilf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the integer part of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) - #[rustc_nounwind] - pub fn truncf16(x: f16) -> f16; - /// Returns the integer part of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) - #[rustc_nounwind] - pub fn truncf32(x: f32) -> f32; - /// Returns the integer part of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) - #[rustc_nounwind] - pub fn truncf64(x: f64) -> f64; - /// Returns the integer part of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) - #[rustc_nounwind] - pub fn truncf128(x: f128) -> f128; +/// Returns the integer part of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the integer part of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the integer part of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the integer part of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn truncf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// May raise an inexact floating-point exception if the argument is not an integer. - /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions - /// cannot actually be utilized from Rust code. - /// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) - #[rustc_nounwind] - pub fn rintf128(x: f128) -> f128; +/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// May raise an inexact floating-point exception if the argument is not an integer. +/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions +/// cannot actually be utilized from Rust code. +/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn rintf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, - /// so this rounds half-way cases to the number with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn nearbyintf128(x: f128) -> f128; +/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, +/// so this rounds half-way cases to the number with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn nearbyintf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f16::round`](../../std/primitive.f16.html#method.round) - #[rustc_nounwind] - pub fn roundf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f32::round`](../../std/primitive.f32.html#method.round) - #[rustc_nounwind] - pub fn roundf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f64::round`](../../std/primitive.f64.html#method.round) - #[rustc_nounwind] - pub fn roundf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. - /// - /// The stabilized version of this intrinsic is - /// [`f128::round`](../../std/primitive.f128.html#method.round) - #[rustc_nounwind] - pub fn roundf128(x: f128) -> f128; +/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f16::round`](../../std/primitive.f16.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f32::round`](../../std/primitive.f32.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f64::round`](../../std/primitive.f64.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. +/// +/// The stabilized version of this intrinsic is +/// [`f128::round`](../../std/primitive.f128.html#method.round) +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundf128(_x: f128) -> f128 { + unreachable!() +} - /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf16(x: f16) -> f16; - /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf32(x: f32) -> f32; - /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf64(x: f64) -> f64; - /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number - /// with an even least significant digit. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn roundevenf128(x: f128) -> f128; +/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf16(_x: f16) -> f16 { + unreachable!() +} +/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf32(_x: f32) -> f32 { + unreachable!() +} +/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf64(_x: f64) -> f64 { + unreachable!() +} +/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number +/// with an even least significant digit. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn roundevenf128(_x: f128) -> f128 { + unreachable!() +} - /// Float addition that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fadd_fast(a: T, b: T) -> T; +/// Float addition that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fadd_fast(_a: T, _b: T) -> T { + unreachable!() +} - /// Float subtraction that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fsub_fast(a: T, b: T) -> T; +/// Float subtraction that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fsub_fast(_a: T, _b: T) -> T { + unreachable!() +} - /// Float multiplication that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fmul_fast(a: T, b: T) -> T; +/// Float multiplication that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fmul_fast(_a: T, _b: T) -> T { + unreachable!() +} - /// Float division that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn fdiv_fast(a: T, b: T) -> T; +/// Float division that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn fdiv_fast(_a: T, _b: T) -> T { + unreachable!() +} - /// Float remainder that allows optimizations based on algebraic rules. - /// May assume inputs are finite. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn frem_fast(a: T, b: T) -> T; +/// Float remainder that allows optimizations based on algebraic rules. +/// May assume inputs are finite. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn frem_fast(_a: T, _b: T) -> T { + unreachable!() +} - /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range - /// () - /// - /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. - #[rustc_nounwind] - pub fn float_to_int_unchecked(value: Float) -> Int; +/// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range +/// () +/// +/// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn float_to_int_unchecked(_value: Float) -> Int { + unreachable!() } /// Float addition that allows optimizations based on algebraic rules. diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr index a456e81e762f..aea6d263a727 100644 --- a/tests/ui/intrinsics/reify-intrinsic.stderr +++ b/tests/ui/intrinsics/reify-intrinsic.stderr @@ -22,7 +22,7 @@ LL | std::intrinsics::floorf32, | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers | = note: expected fn pointer `unsafe extern "rust-intrinsic" fn(_) -> _` - found fn item `unsafe extern "rust-intrinsic" fn(_) -> _ {floorf32}` + found fn item `unsafe fn(_) -> _ {floorf32}` error: aborting due to 3 previous errors From f0b7008648dbe2fea5d23bb2ad8ce622ddf4e133 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Tue, 26 Nov 2024 14:01:49 +0100 Subject: [PATCH 03/10] thread::available_parallelism for wasm32-wasip1-threads The target has limited POSIX support and provides the sysconf function which allows querying the number of available CPUs. --- library/std/src/sys/pal/wasi/thread.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 4b83870fdea6..3b44f77631f5 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -2,7 +2,6 @@ use crate::ffi::CStr; use crate::num::NonZero; -use crate::sys::unsupported; use crate::time::Duration; use crate::{io, mem}; @@ -34,6 +33,8 @@ cfg_if::cfg_if! { #[allow(non_camel_case_types)] pub type pthread_t = *mut ffi::c_void; + pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84; + extern "C" { pub fn pthread_create( native: *mut pthread_t, @@ -121,7 +122,7 @@ impl Thread { } } else { pub unsafe fn new(_stack: usize, _p: Box) -> io::Result { - unsupported() + crate::sys::unsupported() } } } @@ -187,5 +188,15 @@ impl Thread { } pub fn available_parallelism() -> io::Result> { - unsupported() + cfg_if::cfg_if! { + if #[cfg(target_feature = "atomics")] { + match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { + -1 => Err(io::Error::last_os_error()), + 0 => Err(io::Error::UNKNOWN_THREAD_COUNT), + cpus => Ok(unsafe { NonZero::new_unchecked(cpus as usize) }), + } + } else { + crate::sys::unsupported() + } + } } From 4342ec0cf29d5d2e8bc7f66546723882b7728789 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Wed, 27 Nov 2024 13:30:18 +0100 Subject: [PATCH 04/10] Implement code review --- library/std/src/sys/pal/wasi/thread.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 3b44f77631f5..f5e19f26bfe1 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -192,8 +192,7 @@ pub fn available_parallelism() -> io::Result> { if #[cfg(target_feature = "atomics")] { match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { -1 => Err(io::Error::last_os_error()), - 0 => Err(io::Error::UNKNOWN_THREAD_COUNT), - cpus => Ok(unsafe { NonZero::new_unchecked(cpus as usize) }), + cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT), } } else { crate::sys::unsupported() From b0f8bd7438362e3160de47381dfd1da5b8cf4449 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 14 Nov 2024 14:45:38 -0800 Subject: [PATCH 05/10] Add `BTreeSet` entry APIs to match `HashSet` * `fn get_or_insert(&mut self, value: T) -> &T` * `fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T` * `fn entry(&mut self, value: T) -> Entry<'_, T, A>` (+ `Entry` APIs) --- library/alloc/src/collections/btree/map.rs | 29 +- .../alloc/src/collections/btree/map/entry.rs | 5 + library/alloc/src/collections/btree/set.rs | 80 +++- .../alloc/src/collections/btree/set/entry.rs | 388 ++++++++++++++++++ 4 files changed, 500 insertions(+), 2 deletions(-) create mode 100644 library/alloc/src/collections/btree/set/entry.rs diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 213924d1d020..d1ce4e215ed9 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -308,11 +308,38 @@ impl BTreeMap { alloc: (*map.alloc).clone(), _marker: PhantomData, } - .insert(SetValZST::default()); + .insert(SetValZST); None } } } + + pub(super) fn get_or_insert_with(&mut self, q: &Q, f: F) -> &K + where + K: Borrow + Ord, + Q: Ord, + F: FnOnce(&Q) -> K, + { + let (map, dormant_map) = DormantMutRef::new(self); + let root_node = + map.root.get_or_insert_with(|| Root::new((*map.alloc).clone())).borrow_mut(); + match root_node.search_tree(q) { + Found(handle) => handle.into_kv_mut().0, + GoDown(handle) => { + let key = f(q); + assert!(*key.borrow() == *q, "new value is not equal"); + VacantEntry { + key, + handle: Some(handle), + dormant_map, + alloc: (*map.alloc).clone(), + _marker: PhantomData, + } + .insert_entry(SetValZST) + .into_key() + } + } + } } /// An iterator over the entries of a `BTreeMap`. diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 0da6af54bc22..ea8fa363c380 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -449,6 +449,11 @@ impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> { self.handle.reborrow().into_kv().0 } + /// Converts the entry into a reference to its key. + pub(crate) fn into_key(self) -> &'a K { + self.handle.into_kv_mut().0 + } + /// Take ownership of the key and value from the map. /// /// # Examples diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 8daee6030c27..9b7c345e0c31 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -7,12 +7,17 @@ use core::iter::{FusedIterator, Peekable}; use core::mem::ManuallyDrop; use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub}; -use super::map::{BTreeMap, Keys}; +use super::map::{self, BTreeMap, Keys}; use super::merge_iter::MergeIterInner; use super::set_val::SetValZST; use crate::alloc::{Allocator, Global}; use crate::vec::Vec; +mod entry; + +#[unstable(feature = "btree_set_entry", issue = "none")] +pub use self::entry::{Entry, OccupiedEntry, VacantEntry}; + /// An ordered set based on a B-Tree. /// /// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance @@ -928,6 +933,79 @@ impl BTreeSet { self.map.replace(value) } + /// Inserts the given `value` into the set if it is not present, then + /// returns a reference to the value in the set. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::from([1, 2, 3]); + /// assert_eq!(set.len(), 3); + /// assert_eq!(set.get_or_insert(2), &2); + /// assert_eq!(set.get_or_insert(100), &100); + /// assert_eq!(set.len(), 4); // 100 was inserted + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn get_or_insert(&mut self, value: T) -> &T + where + T: Ord, + { + self.map.entry(value).insert_entry(SetValZST).into_key() + } + + /// Inserts a value computed from `f` into the set if the given `value` is + /// not present, then returns a reference to the value in the set. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set: BTreeSet = ["cat", "dog", "horse"] + /// .iter().map(|&pet| pet.to_owned()).collect(); + /// + /// assert_eq!(set.len(), 3); + /// for &pet in &["cat", "dog", "fish"] { + /// let value = set.get_or_insert_with(pet, str::to_owned); + /// assert_eq!(value, pet); + /// } + /// assert_eq!(set.len(), 4); // a new "fish" was inserted + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T + where + T: Borrow + Ord, + Q: Ord, + F: FnOnce(&Q) -> T, + { + self.map.get_or_insert_with(value, f) + } + + /// Gets the given value's corresponding entry in the set for in-place manipulation. + /// + /// # Examples + /// + /// TODO + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn entry(&mut self, value: T) -> Entry<'_, T, A> + where + T: Ord, + { + match self.map.entry(value) { + map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }), + map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }), + } + } + /// If the set contains an element equal to the value, removes it from the /// set and drops it. Returns whether such an element was present. /// diff --git a/library/alloc/src/collections/btree/set/entry.rs b/library/alloc/src/collections/btree/set/entry.rs new file mode 100644 index 000000000000..4f2b0282a2da --- /dev/null +++ b/library/alloc/src/collections/btree/set/entry.rs @@ -0,0 +1,388 @@ +use core::fmt::{self, Debug}; + +use Entry::*; + +use super::{SetValZST, map}; +use crate::alloc::{Allocator, Global}; + +/// A view into a single entry in a set, which may either be vacant or occupied. +/// +/// This `enum` is constructed from the [`entry`] method on [`BTreeSet`]. +/// +/// [`BTreeSet`]: super::BTreeSet +/// [`entry`]: super::BTreeSet::entry +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::BTreeSet; +/// +/// let mut set = BTreeSet::new(); +/// set.extend(["a", "b", "c"]); +/// assert_eq!(set.len(), 3); +/// +/// // Existing value (insert) +/// let entry = set.entry("a"); +/// let _raw_o = entry.insert(); +/// assert_eq!(set.len(), 3); +/// // Nonexistent value (insert) +/// set.entry("d").insert(); +/// +/// // Existing value (or_insert) +/// set.entry("b").or_insert(); +/// // Nonexistent value (or_insert) +/// set.entry("e").or_insert(); +/// +/// println!("Our BTreeSet: {:?}", set); +/// assert!(set.iter().eq(&["a", "b", "c", "d", "e"])); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "none")] +pub enum Entry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + /// An occupied entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::from(["a", "b"]); + /// + /// match set.entry("a") { + /// Entry::Vacant(_) => unreachable!(), + /// Entry::Occupied(_) => { } + /// } + /// ``` + #[unstable(feature = "btree_set_entry", issue = "none")] + Occupied(OccupiedEntry<'a, T, A>), + + /// A vacant entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// + /// match set.entry("a") { + /// Entry::Occupied(_) => unreachable!(), + /// Entry::Vacant(_) => { } + /// } + /// ``` + #[unstable(feature = "btree_set_entry", issue = "none")] + Vacant(VacantEntry<'a, T, A>), +} + +#[unstable(feature = "btree_set_entry", issue = "none")] +impl Debug for Entry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), + Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), + } + } +} + +/// A view into an occupied entry in a `BTreeSet`. +/// It is part of the [`Entry`] enum. +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::{Entry, BTreeSet}; +/// +/// let mut set = BTreeSet::new(); +/// set.extend(["a", "b", "c"]); +/// +/// let _entry_o = set.entry("a").insert(); +/// assert_eq!(set.len(), 3); +/// +/// // Existing key +/// match set.entry("a") { +/// Entry::Vacant(_) => unreachable!(), +/// Entry::Occupied(view) => { +/// assert_eq!(view.get(), &"a"); +/// } +/// } +/// +/// assert_eq!(set.len(), 3); +/// +/// // Existing key (take) +/// match set.entry("c") { +/// Entry::Vacant(_) => unreachable!(), +/// Entry::Occupied(view) => { +/// assert_eq!(view.remove(), "c"); +/// } +/// } +/// assert_eq!(set.get(&"c"), None); +/// assert_eq!(set.len(), 2); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "none")] +pub struct OccupiedEntry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + pub(super) inner: map::OccupiedEntry<'a, T, SetValZST, A>, +} + +#[unstable(feature = "btree_set_entry", issue = "none")] +impl Debug for OccupiedEntry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OccupiedEntry").field("value", self.get()).finish() + } +} + +/// A view into a vacant entry in a `BTreeSet`. +/// It is part of the [`Entry`] enum. +/// +/// # Examples +/// +/// ``` +/// #![feature(btree_set_entry)] +/// +/// use std::collections::btree_set::{Entry, BTreeSet}; +/// +/// let mut set = BTreeSet::<&str>::new(); +/// +/// let entry_v = match set.entry("a") { +/// Entry::Vacant(view) => view, +/// Entry::Occupied(_) => unreachable!(), +/// }; +/// entry_v.insert(); +/// assert!(set.contains("a") && set.len() == 1); +/// +/// // Nonexistent key (insert) +/// match set.entry("b") { +/// Entry::Vacant(view) => view.insert(), +/// Entry::Occupied(_) => unreachable!(), +/// } +/// assert!(set.contains("b") && set.len() == 2); +/// ``` +#[unstable(feature = "btree_set_entry", issue = "none")] +pub struct VacantEntry< + 'a, + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global, +> { + pub(super) inner: map::VacantEntry<'a, T, SetValZST, A>, +} + +#[unstable(feature = "btree_set_entry", issue = "none")] +impl Debug for VacantEntry<'_, T, A> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("VacantEntry").field(self.get()).finish() + } +} + +impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> { + /// Sets the value of the entry, and returns an `OccupiedEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// let entry = set.entry("horseyland").insert(); + /// + /// assert_eq!(entry.get(), &"horseyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn insert(self) -> OccupiedEntry<'a, T, A> { + match self { + Occupied(entry) => entry, + Vacant(entry) => entry.insert_entry(), + } + } + + /// Ensures a value is in the entry by inserting if it was vacant. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// + /// // nonexistent key + /// set.entry("poneyland").or_insert(); + /// assert!(set.contains("poneyland")); + /// + /// // existing key + /// set.entry("poneyland").or_insert(); + /// assert!(set.contains("poneyland")); + /// assert_eq!(set.len(), 1); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn or_insert(self) { + if let Vacant(entry) = self { + entry.insert(); + } + } + + /// Returns a reference to this entry's value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// // existing key + /// assert_eq!(set.entry("poneyland").get(), &"poneyland"); + /// // nonexistent key + /// assert_eq!(set.entry("horseland").get(), &"horseland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn get(&self) -> &T { + match *self { + Occupied(ref entry) => entry.get(), + Vacant(ref entry) => entry.get(), + } + } +} + +impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> { + /// Gets a reference to the value in the entry. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// match set.entry("poneyland") { + /// Entry::Vacant(_) => panic!(), + /// Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"), + /// } + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn get(&self) -> &T { + self.inner.key() + } + + /// Takes the value out of the entry, and returns it. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry; + /// + /// let mut set = BTreeSet::new(); + /// set.entry("poneyland").or_insert(); + /// + /// if let Entry::Occupied(o) = set.entry("poneyland") { + /// assert_eq!(o.remove(), "poneyland"); + /// } + /// + /// assert_eq!(set.contains("poneyland"), false); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn remove(self) -> T { + self.inner.remove_entry().0 + } +} + +impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> { + /// Gets a reference to the value that would be used when inserting + /// through the `VacantEntry`. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// + /// let mut set = BTreeSet::new(); + /// assert_eq!(set.entry("poneyland").get(), &"poneyland"); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn get(&self) -> &T { + self.inner.key() + } + + /// Take ownership of the value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::btree_set::{Entry, BTreeSet}; + /// + /// let mut set = BTreeSet::new(); + /// + /// match set.entry("poneyland") { + /// Entry::Occupied(_) => panic!(), + /// Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"), + /// } + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn into_value(self) -> T { + self.inner.into_key() + } + + /// Sets the value of the entry with the VacantEntry's value. + /// + /// # Examples + /// + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry; + /// + /// let mut set = BTreeSet::new(); + /// + /// if let Entry::Vacant(o) = set.entry("poneyland") { + /// o.insert(); + /// } + /// assert!(set.contains("poneyland")); + /// ``` + #[inline] + #[unstable(feature = "btree_set_entry", issue = "none")] + pub fn insert(self) { + self.inner.insert(SetValZST); + } + + #[inline] + fn insert_entry(self) -> OccupiedEntry<'a, T, A> { + OccupiedEntry { inner: self.inner.insert_entry(SetValZST) } + } +} From 82b8ea8a7a63ccc9be8e6c557fc4b2fb2cd14145 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 27 Nov 2024 11:43:05 -0800 Subject: [PATCH 06/10] Add a tracking issue for `btree_set_entry` --- library/alloc/src/collections/btree/set.rs | 8 ++--- .../alloc/src/collections/btree/set/entry.rs | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 9b7c345e0c31..a9c64fd41d52 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -15,7 +15,7 @@ use crate::vec::Vec; mod entry; -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] pub use self::entry::{Entry, OccupiedEntry, VacantEntry}; /// An ordered set based on a B-Tree. @@ -950,7 +950,7 @@ impl BTreeSet { /// assert_eq!(set.len(), 4); // 100 was inserted /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn get_or_insert(&mut self, value: T) -> &T where T: Ord, @@ -979,7 +979,7 @@ impl BTreeSet { /// assert_eq!(set.len(), 4); // a new "fish" was inserted /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T where T: Borrow + Ord, @@ -995,7 +995,7 @@ impl BTreeSet { /// /// TODO #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn entry(&mut self, value: T) -> Entry<'_, T, A> where T: Ord, diff --git a/library/alloc/src/collections/btree/set/entry.rs b/library/alloc/src/collections/btree/set/entry.rs index 4f2b0282a2da..a60d22f9ece7 100644 --- a/library/alloc/src/collections/btree/set/entry.rs +++ b/library/alloc/src/collections/btree/set/entry.rs @@ -38,7 +38,7 @@ use crate::alloc::{Allocator, Global}; /// println!("Our BTreeSet: {:?}", set); /// assert!(set.iter().eq(&["a", "b", "c", "d", "e"])); /// ``` -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] pub enum Entry< 'a, T, @@ -60,7 +60,7 @@ pub enum Entry< /// Entry::Occupied(_) => { } /// } /// ``` - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] Occupied(OccupiedEntry<'a, T, A>), /// A vacant entry. @@ -79,11 +79,11 @@ pub enum Entry< /// Entry::Vacant(_) => { } /// } /// ``` - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] Vacant(VacantEntry<'a, T, A>), } -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] impl Debug for Entry<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -129,7 +129,7 @@ impl Debug for Entry<'_, T, A> { /// assert_eq!(set.get(&"c"), None); /// assert_eq!(set.len(), 2); /// ``` -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] pub struct OccupiedEntry< 'a, T, @@ -138,7 +138,7 @@ pub struct OccupiedEntry< pub(super) inner: map::OccupiedEntry<'a, T, SetValZST, A>, } -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] impl Debug for OccupiedEntry<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedEntry").field("value", self.get()).finish() @@ -171,7 +171,7 @@ impl Debug for OccupiedEntry<'_, T, A> { /// } /// assert!(set.contains("b") && set.len() == 2); /// ``` -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] pub struct VacantEntry< 'a, T, @@ -180,7 +180,7 @@ pub struct VacantEntry< pub(super) inner: map::VacantEntry<'a, T, SetValZST, A>, } -#[unstable(feature = "btree_set_entry", issue = "none")] +#[unstable(feature = "btree_set_entry", issue = "133549")] impl Debug for VacantEntry<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("VacantEntry").field(self.get()).finish() @@ -203,7 +203,7 @@ impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> { /// assert_eq!(entry.get(), &"horseyland"); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn insert(self) -> OccupiedEntry<'a, T, A> { match self { Occupied(entry) => entry, @@ -232,7 +232,7 @@ impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> { /// assert_eq!(set.len(), 1); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn or_insert(self) { if let Vacant(entry) = self { entry.insert(); @@ -257,7 +257,7 @@ impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> { /// assert_eq!(set.entry("horseland").get(), &"horseland"); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn get(&self) -> &T { match *self { Occupied(ref entry) => entry.get(), @@ -285,7 +285,7 @@ impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> { /// } /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn get(&self) -> &T { self.inner.key() } @@ -310,7 +310,7 @@ impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> { /// assert_eq!(set.contains("poneyland"), false); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn remove(self) -> T { self.inner.remove_entry().0 } @@ -331,7 +331,7 @@ impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> { /// assert_eq!(set.entry("poneyland").get(), &"poneyland"); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn get(&self) -> &T { self.inner.key() } @@ -353,7 +353,7 @@ impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> { /// } /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn into_value(self) -> T { self.inner.into_key() } @@ -376,7 +376,7 @@ impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> { /// assert!(set.contains("poneyland")); /// ``` #[inline] - #[unstable(feature = "btree_set_entry", issue = "none")] + #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn insert(self) { self.inner.insert(SetValZST); } From 21b1ab1779a6f58f4a77bad0e1d3a21efcd9bc47 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 27 Nov 2024 12:22:21 -0800 Subject: [PATCH 07/10] Fill in a `BTreeSet::entry` example --- library/alloc/src/collections/btree/set.rs | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index a9c64fd41d52..6f8c3b2d152b 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -993,7 +993,37 @@ impl BTreeSet { /// /// # Examples /// - /// TODO + /// ``` + /// #![feature(btree_set_entry)] + /// + /// use std::collections::BTreeSet; + /// use std::collections::btree_set::Entry::*; + /// + /// let mut singles = BTreeSet::new(); + /// let mut dupes = BTreeSet::new(); + /// + /// for ch in "a short treatise on fungi".chars() { + /// if let Vacant(dupe_entry) = dupes.entry(ch) { + /// // We haven't already seen a duplicate, so + /// // check if we've at least seen it once. + /// match singles.entry(ch) { + /// Vacant(single_entry) => { + /// // We found a new character for the first time. + /// single_entry.insert() + /// } + /// Occupied(single_entry) => { + /// // We've already seen this once, "move" it to dupes. + /// single_entry.remove(); + /// dupe_entry.insert(); + /// } + /// } + /// } + /// } + /// + /// assert!(!singles.contains(&'t') && dupes.contains(&'t')); + /// assert!(singles.contains(&'u') && !dupes.contains(&'u')); + /// assert!(!singles.contains(&'v') && !dupes.contains(&'v')); + /// ``` #[inline] #[unstable(feature = "btree_set_entry", issue = "133549")] pub fn entry(&mut self, value: T) -> Entry<'_, T, A> From 0f8ebba54a8e41a9daccbbedae88e8798f4557c3 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 29 Nov 2024 00:24:36 +0900 Subject: [PATCH 08/10] Support #[repr(simd)] types in input/output of PowerPC inline assembly --- compiler/rustc_codegen_gcc/src/asm.rs | 10 +- compiler/rustc_codegen_llvm/src/asm.rs | 10 +- compiler/rustc_span/src/symbol.rs | 2 + compiler/rustc_target/src/asm/powerpc.rs | 6 +- .../asm-experimental-arch.md | 6 +- tests/assembly/asm/powerpc-types.rs | 237 +++++++++++++++++- tests/codegen/asm/powerpc-clobbers.rs | 13 +- tests/ui/asm/powerpc/bad-reg.aix64.stderr | 136 +++++----- tests/ui/asm/powerpc/bad-reg.powerpc.stderr | 172 +++++++------ tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 160 ++++++------ .../ui/asm/powerpc/bad-reg.powerpc64le.stderr | 136 +++++----- tests/ui/asm/powerpc/bad-reg.rs | 59 +++-- 12 files changed, 595 insertions(+), 352 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 341d1b9c179b..a1f9eab10e76 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -656,9 +656,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { + | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", @@ -736,9 +736,11 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { + cx.type_vector(cx.type_i32(), 4) + } InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { + | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 9aa01bd1b956..1483d576362b 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -656,9 +656,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> PowerPC(PowerPCInlineAsmRegClass::reg) => "r", PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", PowerPC(PowerPCInlineAsmRegClass::freg) => "f", - PowerPC(PowerPCInlineAsmRegClass::cr) - | PowerPC(PowerPCInlineAsmRegClass::xer) - | PowerPC(PowerPCInlineAsmRegClass::vreg) => { + PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", + PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") } RiscV(RiscVInlineAsmRegClass::reg) => "r", @@ -825,9 +824,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(), PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), - PowerPC(PowerPCInlineAsmRegClass::cr) - | PowerPC(PowerPCInlineAsmRegClass::xer) - | PowerPC(PowerPCInlineAsmRegClass::vreg) => { + PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4), + PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") } RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3a07c283e0eb..6cd754a47e94 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -392,6 +392,7 @@ symbols! { allow_fail, allow_internal_unsafe, allow_internal_unstable, + altivec, alu32, always, and, @@ -2154,6 +2155,7 @@ symbols! { volatile_store, vreg, vreg_low16, + vsx, vtable_align, vtable_size, warn, diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index aa8b26170bee..a5a96b87e367 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -51,7 +51,11 @@ impl PowerPCInlineAsmRegClass { } } Self::freg => types! { _: F32, F64; }, - Self::vreg => &[], + // FIXME: vsx also supports integers and floats: https://github.com/rust-lang/rust/pull/131551#discussion_r1797651773 + Self::vreg => types! { + altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4); + vsx: VecI64(2), VecF64(2); + }, Self::cr | Self::xer => &[], } } diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 12a73f0508b2..f2d0caa5e37c 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -34,7 +34,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` | | PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` | | PowerPC | `freg` | `f[0-31]` | `f` | -| PowerPC | `vreg` | `v[0-31]` | Only clobbers | +| PowerPC | `vreg` | `v[0-31]` | `v` | | PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers | | PowerPC | `xer` | `xer` | Only clobbers | | wasm32 | `local` | None\* | `r` | @@ -75,7 +75,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | -| PowerPC | `vreg` | N/A | Only clobbers | +| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | +| PowerPC | `vreg` | `vsx` | `i64x2`, `f64x2` | | PowerPC | `cr` | N/A | Only clobbers | | PowerPC | `xer` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | @@ -181,6 +182,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | None | `0` | None | | PowerPC | `reg_nonzero` | None | `3` | None | | PowerPC | `freg` | None | `0` | None | +| PowerPC | `vreg` | None | `0` | None | | SPARC | `reg` | None | `%o0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | diff --git a/tests/assembly/asm/powerpc-types.rs b/tests/assembly/asm/powerpc-types.rs index 85321e5f345a..d67e0f66f66f 100644 --- a/tests/assembly/asm/powerpc-types.rs +++ b/tests/assembly/asm/powerpc-types.rs @@ -1,9 +1,15 @@ -//@ revisions: powerpc powerpc64 +//@ revisions: powerpc powerpc_altivec powerpc_vsx powerpc64 powerpc64_vsx //@ assembly-output: emit-asm //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc -//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc_altivec] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec --cfg altivec +//@[powerpc_altivec] needs-llvm-components: powerpc +//@[powerpc_vsx] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec,+vsx --cfg altivec --cfg vsx +//@[powerpc_vsx] needs-llvm-components: powerpc +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu --cfg altivec //@[powerpc64] needs-llvm-components: powerpc +//@[powerpc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx --cfg altivec --cfg vsx +//@[powerpc64_vsx] needs-llvm-components: powerpc //@ compile-flags: -Zmerge-functions=disabled #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)] @@ -11,6 +17,13 @@ #![no_core] #![allow(asm_sub_register, non_camel_case_types)] +#[cfg_attr(altivec, cfg(not(target_feature = "altivec")))] +#[cfg_attr(not(altivec), cfg(target_feature = "altivec"))] +compile_error!("altivec cfg and target feature mismatch"); +#[cfg_attr(vsx, cfg(not(target_feature = "vsx")))] +#[cfg_attr(not(vsx), cfg(target_feature = "vsx"))] +compile_error!("vsx cfg and target feature mismatch"); + #[rustc_builtin_macro] macro_rules! asm { () => {}; @@ -29,8 +42,23 @@ trait Sized {} #[lang = "copy"] trait Copy {} +impl Copy for [T; N] {} + type ptr = *const i32; +#[repr(simd)] +pub struct i8x16([i8; 16]); +#[repr(simd)] +pub struct i16x8([i16; 8]); +#[repr(simd)] +pub struct i32x4([i32; 4]); +#[repr(simd)] +pub struct i64x2([i64; 2]); +#[repr(simd)] +pub struct f32x4([f32; 4]); +#[repr(simd)] +pub struct f64x2([f64; 2]); + impl Copy for i8 {} impl Copy for u8 {} impl Copy for i16 {} @@ -39,6 +67,13 @@ impl Copy for i64 {} impl Copy for f32 {} impl Copy for f64 {} impl Copy for ptr {} +impl Copy for i8x16 {} +impl Copy for i16x8 {} +impl Copy for i32x4 {} +impl Copy for i64x2 {} +impl Copy for f32x4 {} +impl Copy for f64x2 {} + extern "C" { fn extern_func(); static extern_static: u8; @@ -124,6 +159,72 @@ check!(reg_f32, f32, freg, "fmr"); // CHECK: #NO_APP check!(reg_f64, f64, freg, "fmr"); +// powerpc_altivec-LABEL: vreg_i8x16: +// powerpc_altivec: #APP +// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i8x16: +// powerpc64: #APP +// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64: #NO_APP +#[cfg(altivec)] +check!(vreg_i8x16, i8x16, vreg, "vmr"); + +// powerpc_altivec-LABEL: vreg_i16x8: +// powerpc_altivec: #APP +// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i16x8: +// powerpc64: #APP +// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64: #NO_APP +#[cfg(altivec)] +check!(vreg_i16x8, i16x8, vreg, "vmr"); + +// powerpc_altivec-LABEL: vreg_i32x4: +// powerpc_altivec: #APP +// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i32x4: +// powerpc64: #APP +// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64: #NO_APP +#[cfg(altivec)] +check!(vreg_i32x4, i32x4, vreg, "vmr"); + +// powerpc_vsx-LABEL: vreg_i64x2: +// powerpc_vsx: #APP +// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_i64x2: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vreg_i64x2, i64x2, vreg, "vmr"); + +// powerpc_altivec-LABEL: vreg_f32x4: +// powerpc_altivec: #APP +// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_f32x4: +// powerpc64: #APP +// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64: #NO_APP +#[cfg(altivec)] +check!(vreg_f32x4, f32x4, vreg, "vmr"); + +// powerpc_vsx-LABEL: vreg_f64x2: +// powerpc_vsx: #APP +// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64x2: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vreg_f64x2, f64x2, vreg, "vmr"); + // CHECK-LABEL: reg_i8_r0: // CHECK: #APP // CHECK: mr 0, 0 @@ -197,3 +298,135 @@ check_reg!(reg_f32_f18, f32, "18", "f18", "fmr"); // CHECK: fmr 18, 18 // CHECK: #NO_APP check_reg!(reg_f64_f18, f64, "18", "f18", "fmr"); + +// powerpc_altivec-LABEL: vreg_i8x16_v0: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 0, 0 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i8x16_v0: +// powerpc64: #APP +// powerpc64: vmr 0, 0 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i8x16_v0, i8x16, "0", "v0", "vmr"); + +// powerpc_altivec-LABEL: vreg_i16x8_v0: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 0, 0 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i16x8_v0: +// powerpc64: #APP +// powerpc64: vmr 0, 0 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i16x8_v0, i16x8, "0", "v0", "vmr"); + +// powerpc_altivec-LABEL: vreg_i32x4_v0: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 0, 0 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i32x4_v0: +// powerpc64: #APP +// powerpc64: vmr 0, 0 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i32x4_v0, i32x4, "0", "v0", "vmr"); + +// powerpc_vsx-LABEL: vreg_i64x2_v0: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_i64x2_v0: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_i64x2_v0, i64x2, "0", "v0", "vmr"); + +// powerpc_altivec-LABEL: vreg_f32x4_v0: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 0, 0 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_f32x4_v0: +// powerpc64: #APP +// powerpc64: vmr 0, 0 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr"); + +// powerpc_vsx-LABEL: vreg_f64x2_v0: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64x2_v0: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr"); + +// powerpc_altivec-LABEL: vreg_i8x16_v18: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 18, 18 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i8x16_v18: +// powerpc64: #APP +// powerpc64: vmr 18, 18 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i8x16_v18, i8x16, "18", "v18", "vmr"); + +// powerpc_altivec-LABEL: vreg_i16x8_v18: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 18, 18 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i16x8_v18: +// powerpc64: #APP +// powerpc64: vmr 18, 18 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i16x8_v18, i16x8, "18", "v18", "vmr"); + +// powerpc_altivec-LABEL: vreg_i32x4_v18: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 18, 18 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_i32x4_v18: +// powerpc64: #APP +// powerpc64: vmr 18, 18 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_i32x4_v18, i32x4, "18", "v18", "vmr"); + +// powerpc_vsx-LABEL: vreg_i64x2_v18: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 18, 18 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_i64x2_v18: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 18, 18 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_i64x2_v18, i64x2, "18", "v18", "vmr"); + +// powerpc_altivec-LABEL: vreg_f32x4_v18: +// powerpc_altivec: #APP +// powerpc_altivec: vmr 18, 18 +// powerpc_altivec: #NO_APP +// powerpc64-LABEL: vreg_f32x4_v18: +// powerpc64: #APP +// powerpc64: vmr 18, 18 +// powerpc64: #NO_APP +#[cfg(altivec)] +check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr"); + +// powerpc_vsx-LABEL: vreg_f64x2_v18: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 18, 18 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64x2_v18: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 18, 18 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr"); diff --git a/tests/codegen/asm/powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs index e97e8300ca74..2832377cef00 100644 --- a/tests/codegen/asm/powerpc-clobbers.rs +++ b/tests/codegen/asm/powerpc-clobbers.rs @@ -7,6 +7,7 @@ //@[powerpc64le] needs-llvm-components: powerpc //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc +// ignore-tidy-linelength #![crate_type = "rlib"] #![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] @@ -48,15 +49,23 @@ pub unsafe fn xer_clobber() { asm!("", out("xer") _, options(nostack, nomem, preserves_flags)); } +// Output format depends on the availability of altivec. // CHECK-LABEL: @v0_clobber -// CHECK: call void asm sideeffect "", "~{v0}"() +// powerpc: call void asm sideeffect "", "~{v0}"() +// powerpc64: call <4 x i32> asm sideeffect "", "=&{v0}"() +// powerpc64le: call <4 x i32> asm sideeffect "", "=&{v0}"() +// aix64: call <4 x i32> asm sideeffect "", "=&{v0}"() #[no_mangle] pub unsafe fn v0_clobber() { asm!("", out("v0") _, options(nostack, nomem, preserves_flags)); } +// Output format depends on the availability of altivec. // CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() #[no_mangle] pub unsafe fn clobber_abi() { asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 34105ceac049..332bdf0ff546 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -1,125 +1,101 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("lr") _); | ^^^^^^^^^^^ error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("ctr") _); | ^^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:112:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:72:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:75:26 + --> $DIR/bad-reg.rs:118:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:79:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:85:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:88:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:93:18 - | -LL | asm!("", in("v0") x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:96:18 - | -LL | asm!("", out("v0") x); - | ^^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:99:26 - | -LL | asm!("/* {} */", in(vreg) x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:102:26 - | -LL | asm!("/* {} */", out(vreg) _); - | ^^^^^^^^^^^ - error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:106:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -127,7 +103,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:108:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -135,7 +111,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:110:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -143,7 +119,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -151,7 +127,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -159,7 +135,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -167,7 +143,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -175,7 +151,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -183,13 +159,37 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:27 + --> $DIR/bad-reg.rs:76:27 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:79:28 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:87:35 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:109:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +197,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:69:28 + --> $DIR/bad-reg.rs:112:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +205,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:72:33 + --> $DIR/bad-reg.rs:115:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +213,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:79:28 + --> $DIR/bad-reg.rs:122:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +221,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:82:29 + --> $DIR/bad-reg.rs:125:29 | LL | asm!("", out("xer") x); | ^ @@ -229,36 +229,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:85:34 + --> $DIR/bad-reg.rs:128:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:93:27 - | -LL | asm!("", in("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:96:28 - | -LL | asm!("", out("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:99:35 - | -LL | asm!("/* {} */", in(vreg) x); - | ^ - | - = note: register class `vreg` supports these types: - -error: aborting due to 38 previous errors +error: aborting due to 34 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index 34105ceac049..13fc5a048d82 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -1,125 +1,101 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("lr") _); | ^^^^^^^^^^^ error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("ctr") _); | ^^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:112:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:72:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:75:26 + --> $DIR/bad-reg.rs:118:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:79:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:85:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:88:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:93:18 - | -LL | asm!("", in("v0") x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:96:18 - | -LL | asm!("", out("v0") x); - | ^^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:99:26 - | -LL | asm!("/* {} */", in(vreg) x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:102:26 - | -LL | asm!("/* {} */", out(vreg) _); - | ^^^^^^^^^^^ - error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:106:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -127,7 +103,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:108:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -135,7 +111,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:110:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -143,7 +119,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -151,7 +127,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -159,7 +135,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -167,7 +143,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -175,7 +151,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -183,13 +159,73 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:66:18 + | +LL | asm!("", in("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:68:18 + | +LL | asm!("", out("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:70:18 + | +LL | asm!("", in("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:73:18 + | +LL | asm!("", out("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:76:18 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:79:18 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:82:26 + | +LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:84:26 + | +LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:87:26 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:90:26 + | +LL | asm!("/* {} */", out(vreg) _); // requires altivec + | ^^^^^^^^^^^ + error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:27 + --> $DIR/bad-reg.rs:109:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +233,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:69:28 + --> $DIR/bad-reg.rs:112:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +241,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:72:33 + --> $DIR/bad-reg.rs:115:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +249,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:79:28 + --> $DIR/bad-reg.rs:122:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +257,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:82:29 + --> $DIR/bad-reg.rs:125:29 | LL | asm!("", out("xer") x); | ^ @@ -229,36 +265,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:85:34 + --> $DIR/bad-reg.rs:128:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:93:27 - | -LL | asm!("", in("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:96:28 - | -LL | asm!("", out("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:99:35 - | -LL | asm!("/* {} */", in(vreg) x); - | ^ - | - = note: register class `vreg` supports these types: - -error: aborting due to 38 previous errors +error: aborting due to 41 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 34105ceac049..9e0dd80b3dca 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -1,125 +1,101 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("lr") _); | ^^^^^^^^^^^ error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("ctr") _); | ^^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:112:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:72:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:75:26 + --> $DIR/bad-reg.rs:118:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:79:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:85:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:88:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:93:18 - | -LL | asm!("", in("v0") x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:96:18 - | -LL | asm!("", out("v0") x); - | ^^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:99:26 - | -LL | asm!("/* {} */", in(vreg) x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:102:26 - | -LL | asm!("/* {} */", out(vreg) _); - | ^^^^^^^^^^^ - error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:106:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -127,7 +103,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:108:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -135,7 +111,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:110:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -143,7 +119,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -151,7 +127,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -159,7 +135,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -167,7 +143,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -175,7 +151,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -183,13 +159,61 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ +error: `vsx` target feature is not enabled + --> $DIR/bad-reg.rs:70:27 + | +LL | asm!("", in("v0") v64x2); // requires vsx + | ^^^^^ + | + = note: this is required to use type `i64x2` with register class `vreg` + +error: `vsx` target feature is not enabled + --> $DIR/bad-reg.rs:73:28 + | +LL | asm!("", out("v0") v64x2); // requires vsx + | ^^^^^ + | + = note: this is required to use type `i64x2` with register class `vreg` + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:76:27 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:79:28 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: `vsx` target feature is not enabled + --> $DIR/bad-reg.rs:84:35 + | +LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx + | ^^^^^ + | + = note: this is required to use type `i64x2` with register class `vreg` + error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:27 + --> $DIR/bad-reg.rs:87:35 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:109:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +221,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:69:28 + --> $DIR/bad-reg.rs:112:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +229,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:72:33 + --> $DIR/bad-reg.rs:115:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +237,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:79:28 + --> $DIR/bad-reg.rs:122:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +245,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:82:29 + --> $DIR/bad-reg.rs:125:29 | LL | asm!("", out("xer") x); | ^ @@ -229,36 +253,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:85:34 + --> $DIR/bad-reg.rs:128:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:93:27 - | -LL | asm!("", in("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:96:28 - | -LL | asm!("", out("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:99:35 - | -LL | asm!("/* {} */", in(vreg) x); - | ^ - | - = note: register class `vreg` supports these types: - -error: aborting due to 38 previous errors +error: aborting due to 37 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 34105ceac049..332bdf0ff546 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -1,125 +1,101 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("lr") _); | ^^^^^^^^^^^ error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("ctr") _); | ^^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:112:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:72:26 + --> $DIR/bad-reg.rs:115:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:75:26 + --> $DIR/bad-reg.rs:118:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:79:18 + --> $DIR/bad-reg.rs:122:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:125:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:85:26 + --> $DIR/bad-reg.rs:128:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:88:26 + --> $DIR/bad-reg.rs:131:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:93:18 - | -LL | asm!("", in("v0") x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:96:18 - | -LL | asm!("", out("v0") x); - | ^^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:99:26 - | -LL | asm!("/* {} */", in(vreg) x); - | ^^^^^^^^^^ - -error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:102:26 - | -LL | asm!("/* {} */", out(vreg) _); - | ^^^^^^^^^^^ - error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:106:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -127,7 +103,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:108:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -135,7 +111,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:110:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -143,7 +119,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:112:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -151,7 +127,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:114:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -159,7 +135,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:116:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -167,7 +143,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:118:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -175,7 +151,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:120:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -183,13 +159,37 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:27 + --> $DIR/bad-reg.rs:76:27 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:79:28 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:87:35 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:109:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +197,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:69:28 + --> $DIR/bad-reg.rs:112:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +205,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:72:33 + --> $DIR/bad-reg.rs:115:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +213,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:79:28 + --> $DIR/bad-reg.rs:122:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +221,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:82:29 + --> $DIR/bad-reg.rs:125:29 | LL | asm!("", out("xer") x); | ^ @@ -229,36 +229,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:85:34 + --> $DIR/bad-reg.rs:128:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:93:27 - | -LL | asm!("", in("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:96:28 - | -LL | asm!("", out("v0") x); - | ^ - | - = note: register class `vreg` supports these types: - -error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:99:35 - | -LL | asm!("/* {} */", in(vreg) x); - | ^ - | - = note: register class `vreg` supports these types: - -error: aborting due to 38 previous errors +error: aborting due to 34 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 5023ad51838a..f34c45663a02 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -8,17 +8,28 @@ //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc //@ needs-asm-support +// ignore-tidy-linelength #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, rustc_attrs, lang_items, repr_simd, asm_experimental_arch)] #![no_core] +#![allow(non_camel_case_types)] #[lang = "sized"] trait Sized {} #[lang = "copy"] trait Copy {} +#[repr(simd)] +pub struct i32x4([i32; 4]); +#[repr(simd)] +pub struct i64x2([i64; 2]); + +impl Copy for [T; N] {} impl Copy for i32 {} +impl Copy for i64 {} +impl Copy for i32x4 {} +impl Copy for i64x2 {} #[rustc_builtin_macro] macro_rules! asm { @@ -27,6 +38,8 @@ macro_rules! asm { fn f() { let mut x = 0; + let mut v32x4 = i32x4([0; 4]); + let mut v64x2 = i64x2([0; 2]); unsafe { // Unsupported registers asm!("", out("sp") _); @@ -47,6 +60,36 @@ fn f() { //~^ ERROR invalid register `ctr`: the counter register cannot be used as an operand for inline asm asm!("", out("vrsave") _); //~^ ERROR invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm + + // vreg + asm!("", out("v0") _); // always ok + asm!("", in("v0") v32x4); // requires altivec + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + asm!("", out("v0") v32x4); // requires altivec + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + asm!("", in("v0") v64x2); // requires vsx + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64]~^^ ERROR `vsx` target feature is not enabled + asm!("", out("v0") v64x2); // requires vsx + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64]~^^ ERROR `vsx` target feature is not enabled + asm!("", in("v0") x); // FIXME: should be ok if vsx is available + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("", out("v0") x); // FIXME: should be ok if vsx is available + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("/* {} */", in(vreg) v32x4); // requires altivec + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + asm!("/* {} */", in(vreg) v64x2); // requires vsx + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64]~^^ ERROR `vsx` target feature is not enabled + asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("/* {} */", out(vreg) _); // requires altivec + //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + // v20-v31 are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("v20") _); asm!("", out("v21") _); asm!("", out("v22") _); @@ -87,20 +130,6 @@ fn f() { //~| ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(xer) _); //~^ ERROR can only be used as a clobber - // vreg - asm!("", out("v0") _); // ok - // FIXME: will be supported in the subsequent patch: https://github.com/rust-lang/rust/pull/131551 - asm!("", in("v0") x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("", out("v0") x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("/* {} */", in(vreg) x); - //~^ ERROR can only be used as a clobber - //~| ERROR type `i32` cannot be used with this register class - asm!("/* {} */", out(vreg) _); - //~^ ERROR can only be used as a clobber // Overlapping-only registers asm!("", out("cr") _, out("cr0") _); From df8feb5067f99e20059c7ee8021d9ba5273bfe68 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 29 Nov 2024 03:10:07 +0900 Subject: [PATCH 09/10] Support floats in input/output in vector registers of PowerPC inline assembly --- compiler/rustc_codegen_llvm/src/asm.rs | 42 ++++++++++++ compiler/rustc_target/src/asm/powerpc.rs | 4 +- .../asm-experimental-arch.md | 2 +- tests/assembly/asm/powerpc-types.rs | 66 +++++++++++++++++++ tests/ui/asm/powerpc/bad-reg.aix64.stderr | 6 +- tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 6 +- .../ui/asm/powerpc/bad-reg.powerpc64le.stderr | 6 +- 7 files changed, 120 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 1483d576362b..d1804cb49ad1 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1040,6 +1040,26 @@ fn llvm_fixup_input<'ll, 'tcx>( let value = bx.or(value, bx.const_u32(0xFFFF_0000)); bx.bitcast(value, bx.type_f32()) } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F32) => + { + let value = bx.insert_element( + bx.const_undef(bx.type_vector(bx.type_f32(), 4)), + value, + bx.const_usize(0), + ); + bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)) + } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F64) => + { + let value = bx.insert_element( + bx.const_undef(bx.type_vector(bx.type_f64(), 2)), + value, + bx.const_usize(0), + ); + bx.bitcast(value, bx.type_vector(bx.type_f64(), 2)) + } _ => value, } } @@ -1175,6 +1195,18 @@ fn llvm_fixup_output<'ll, 'tcx>( let value = bx.trunc(value, bx.type_i16()); bx.bitcast(value, bx.type_f16()) } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F32) => + { + let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)); + bx.extract_element(value, bx.const_usize(0)) + } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F64) => + { + let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2)); + bx.extract_element(value, bx.const_usize(0)) + } _ => value, } } @@ -1299,6 +1331,16 @@ fn llvm_fixup_output_type<'ll, 'tcx>( { cx.type_f32() } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F32) => + { + cx.type_vector(cx.type_f32(), 4) + } + (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) + if s.primitive() == Primitive::Float(Float::F64) => + { + cx.type_vector(cx.type_f64(), 2) + } _ => layout.llvm_type(cx), } } diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs index a5a96b87e367..f3934afa6d94 100644 --- a/compiler/rustc_target/src/asm/powerpc.rs +++ b/compiler/rustc_target/src/asm/powerpc.rs @@ -51,10 +51,10 @@ impl PowerPCInlineAsmRegClass { } } Self::freg => types! { _: F32, F64; }, - // FIXME: vsx also supports integers and floats: https://github.com/rust-lang/rust/pull/131551#discussion_r1797651773 + // FIXME: vsx also supports integers?: https://github.com/rust-lang/rust/pull/131551#discussion_r1862535963 Self::vreg => types! { altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4); - vsx: VecI64(2), VecF64(2); + vsx: F32, F64, VecI64(2), VecF64(2); }, Self::cr | Self::xer => &[], } diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index f2d0caa5e37c..c2f4170d7d29 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -76,7 +76,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) | | PowerPC | `freg` | None | `f32`, `f64` | | PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` | -| PowerPC | `vreg` | `vsx` | `i64x2`, `f64x2` | +| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` | | PowerPC | `cr` | N/A | Only clobbers | | PowerPC | `xer` | N/A | Only clobbers | | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | diff --git a/tests/assembly/asm/powerpc-types.rs b/tests/assembly/asm/powerpc-types.rs index d67e0f66f66f..aa35c4d88658 100644 --- a/tests/assembly/asm/powerpc-types.rs +++ b/tests/assembly/asm/powerpc-types.rs @@ -225,6 +225,28 @@ check!(vreg_f32x4, f32x4, vreg, "vmr"); #[cfg(vsx)] check!(vreg_f64x2, f64x2, vreg, "vmr"); +// powerpc_vsx-LABEL: vreg_f32: +// powerpc_vsx: #APP +// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f32: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vreg_f32, f32, vreg, "vmr"); + +// powerpc_vsx-LABEL: vreg_f64: +// powerpc_vsx: #APP +// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vreg_f64, f64, vreg, "vmr"); + // CHECK-LABEL: reg_i8_r0: // CHECK: #APP // CHECK: mr 0, 0 @@ -365,6 +387,28 @@ check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr"); #[cfg(vsx)] check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr"); +// powerpc_vsx-LABEL: vreg_f32_v0: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f32_v0: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f32_v0, f32, "0", "v0", "vmr"); + +// powerpc_vsx-LABEL: vreg_f64_v0: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64_v0: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f64_v0, f64, "0", "v0", "vmr"); + // powerpc_altivec-LABEL: vreg_i8x16_v18: // powerpc_altivec: #APP // powerpc_altivec: vmr 18, 18 @@ -430,3 +474,25 @@ check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr"); // powerpc64_vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr"); + +// powerpc_vsx-LABEL: vreg_f32_v18: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 18, 18 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f32_v18: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 18, 18 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f32_v18, f32, "18", "v18", "vmr"); + +// powerpc_vsx-LABEL: vreg_f64_v18: +// powerpc_vsx: #APP +// powerpc_vsx: vmr 18, 18 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vreg_f64_v18: +// powerpc64_vsx: #APP +// powerpc64_vsx: vmr 18, 18 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vreg_f64_v18, f64, "18", "v18", "vmr"); diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 332bdf0ff546..036641951cc9 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -170,7 +170,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:79:28 @@ -178,7 +178,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:87:35 @@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:109:27 diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 9e0dd80b3dca..6a9d552bfe29 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:79:28 @@ -194,7 +194,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: `vsx` target feature is not enabled --> $DIR/bad-reg.rs:84:35 @@ -210,7 +210,7 @@ error: type `i32` cannot be used with this register class LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:109:27 diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 332bdf0ff546..036641951cc9 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -170,7 +170,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:79:28 @@ -178,7 +178,7 @@ error: type `i32` cannot be used with this register class LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:87:35 @@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ | - = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2 + = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:109:27 From 5b9a77a09dffec853d37fe7f722166b3996823d6 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Fri, 29 Nov 2024 16:04:12 +0100 Subject: [PATCH 10/10] CI: split x86_64-mingw job --- src/bootstrap/mk/Makefile.in | 8 +++++--- src/ci/github-actions/jobs.yml | 16 +++++++++++++--- src/ci/shared.sh | 3 ++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 92c8f5dc452f..a1f38b9ac147 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -108,11 +108,13 @@ ci-msvc: ci-msvc-py ci-msvc-ps1 ## MingW native builders -# test both x and bootstrap entrypoints +# Set of tests that should represent half of the time of the test suite. +# Used to split tests across multiple CI runners. +# Test both x and bootstrap entrypoints. ci-mingw-x: - $(Q)$(CFG_SRC_DIR)/x test --stage 2 tidy + $(Q)$(CFG_SRC_DIR)/x test --stage 2 --skip=compiler --skip=src ci-mingw-bootstrap: - $(Q)$(BOOTSTRAP) test --stage 2 --skip tidy + $(Q)$(BOOTSTRAP) test --stage 2 --skip=tests --skip=coverage-map --skip=coverage-run --skip=library --skip=tidyselftest ci-mingw: ci-mingw-x ci-mingw-bootstrap .PHONY: dist diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 2f59892acf6a..454c855c75d2 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -439,14 +439,24 @@ auto: NO_DOWNLOAD_CI_LLVM: 1 <<: *job-windows-8c - - image: x86_64-mingw + # x86_64-mingw is split into two jobs to run tests in parallel. + - image: x86_64-mingw-1 env: - SCRIPT: make ci-mingw + SCRIPT: make ci-mingw-x RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 - <<: *job-windows-8c + <<: *job-windows + + - image: x86_64-mingw-2 + env: + SCRIPT: make ci-mingw-bootstrap + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu + # We are intentionally allowing an old toolchain on this builder (and that's + # incompatible with LLVM downloads today). + NO_DOWNLOAD_CI_LLVM: 1 + <<: *job-windows - image: dist-x86_64-msvc env: diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 1e6a008a5de8..9fce68947f42 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -53,7 +53,8 @@ function isLinux { } function isKnownToBeMingwBuild { - isGitHubActions && [[ "${CI_JOB_NAME}" == *mingw ]] + # CI_JOB_NAME must end with "mingw" and optionally `-N` to be considered a MinGW build. + isGitHubActions && [[ "${CI_JOB_NAME}" =~ mingw(-[0-9]+)?$ ]] } function isCiBranch {