Auto merge of #152361 - JonathanBrouwer:rollup-Qkwz1vN, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - rust-lang/rust#151869 (add test for codegen of SIMD vector from array repeat) - rust-lang/rust#152077 (bootstrap: always propagate `CARGO_TARGET_{host}_LINKER`) - rust-lang/rust#126100 (Reword the caveats on `array::map`) - rust-lang/rust#152275 (Stop having two different alignment constants) - rust-lang/rust#152325 (Remove more adhoc groups that correspond to teams)
This commit is contained in:
commit
1c316d3461
12 changed files with 105 additions and 49 deletions
|
|
@ -284,9 +284,10 @@ pub unsafe trait GlobalAlloc {
|
|||
/// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html
|
||||
#[stable(feature = "global_alloc", since = "1.28.0")]
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
|
||||
// SAFETY: the caller must ensure that the `new_size` does not overflow.
|
||||
// `layout.align()` comes from a `Layout` and is thus guaranteed to be valid.
|
||||
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, layout.align()) };
|
||||
let alignment = layout.alignment();
|
||||
// SAFETY: the caller must ensure that the `new_size` does not overflow
|
||||
// when rounded up to the next multiple of `alignment`.
|
||||
let new_layout = unsafe { Layout::from_size_alignment_unchecked(new_size, alignment) };
|
||||
// SAFETY: the caller must ensure that `new_layout` is greater than zero.
|
||||
let new_ptr = unsafe { self.alloc(new_layout) };
|
||||
if !new_ptr.is_null() {
|
||||
|
|
|
|||
|
|
@ -516,20 +516,47 @@ impl<T, const N: usize> [T; N] {
|
|||
///
|
||||
/// # Note on performance and stack usage
|
||||
///
|
||||
/// Unfortunately, usages of this method are currently not always optimized
|
||||
/// as well as they could be. This mainly concerns large arrays, as mapping
|
||||
/// over small arrays seem to be optimized just fine. Also note that in
|
||||
/// debug mode (i.e. without any optimizations), this method can use a lot
|
||||
/// of stack space (a few times the size of the array or more).
|
||||
/// Note that this method is *eager*. It evaluates `f` all `N` times before
|
||||
/// returning the new array.
|
||||
///
|
||||
/// Therefore, in performance-critical code, try to avoid using this method
|
||||
/// on large arrays or check the emitted code. Also try to avoid chained
|
||||
/// maps (e.g. `arr.map(...).map(...)`).
|
||||
/// That means that `arr.map(f).map(g)` is, in general, *not* equivalent to
|
||||
/// `array.map(|x| g(f(x)))`, as the former calls `f` 4 times then `g` 4 times,
|
||||
/// whereas the latter interleaves the calls (`fgfgfgfg`).
|
||||
///
|
||||
/// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
|
||||
/// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
|
||||
/// really need a new array of the same size as the result. Rust's lazy
|
||||
/// iterators tend to get optimized very well.
|
||||
/// A consequence of this is that it can have fairly-high stack usage, especially
|
||||
/// in debug mode or for long arrays. The backend may be able to optimize it
|
||||
/// away, but especially for complicated mappings it might not be able to.
|
||||
///
|
||||
/// If you're doing a one-step `map` and really want an array as the result,
|
||||
/// then absolutely use this method. Its implementation uses a bunch of tricks
|
||||
/// to help the optimizer handle it well. Particularly for simple arrays,
|
||||
/// like `[u8; 3]` or `[f32; 4]`, there's nothing to be concerned about.
|
||||
///
|
||||
/// However, if you don't actually need an *array* of the results specifically,
|
||||
/// just to process them, then you likely want [`Iterator::map`] instead.
|
||||
///
|
||||
/// For example, rather than doing an array-to-array map of all the elements
|
||||
/// in the array up-front and only iterating after that completes,
|
||||
///
|
||||
/// ```
|
||||
/// # let my_array = [1, 2, 3];
|
||||
/// # let f = |x: i32| x + 1;
|
||||
/// for x in my_array.map(f) {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// It's often better to use an iterator along the lines of
|
||||
///
|
||||
/// ```
|
||||
/// # let my_array = [1, 2, 3];
|
||||
/// # let f = |x: i32| x + 1;
|
||||
/// for x in my_array.into_iter().map(f) {
|
||||
/// // ...
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// as that's more likely to avoid large temporaries.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
|||
|
|
@ -1260,7 +1260,10 @@ pub trait SizedTypeProperties: Sized {
|
|||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||
const ALIGNMENT: Alignment = Alignment::of::<Self>();
|
||||
const ALIGNMENT: Alignment = {
|
||||
// This can't panic since type alignment is always a power of two.
|
||||
Alignment::new(Self::ALIGN).unwrap()
|
||||
};
|
||||
|
||||
/// `true` if this type requires no storage.
|
||||
/// `false` if its [size](size_of) is greater than zero.
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ impl Alignment {
|
|||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn of<T>() -> Self {
|
||||
// This can't actually panic since type alignment is always a power of two.
|
||||
const { Alignment::new(align_of::<T>()).unwrap() }
|
||||
<T as mem::SizedTypeProperties>::ALIGNMENT
|
||||
}
|
||||
|
||||
/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::core::build_steps::tool::SourceType;
|
|||
use crate::core::config::SplitDebuginfo;
|
||||
use crate::core::config::flags::Color;
|
||||
use crate::utils::build_stamp;
|
||||
use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_args, linker_flags};
|
||||
use crate::utils::helpers::{self, LldThreads, check_cfg_arg, linker_flags};
|
||||
use crate::{
|
||||
BootstrapCommand, CLang, Compiler, Config, DryRun, EXTRA_CHECK_CFGS, GitRepo, Mode,
|
||||
RemapScheme, TargetSelection, command, prepare_behaviour_dump_dir, t,
|
||||
|
|
@ -310,7 +310,15 @@ impl Cargo {
|
|||
}
|
||||
}
|
||||
|
||||
for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
|
||||
// We need to set host linker flags for compiling build scripts and proc-macros.
|
||||
// This is done the same way as the target linker flags below, so cargo won't see
|
||||
// any fingerprint difference between host==target versus cross-compiled targets
|
||||
// when it comes to those host build artifacts.
|
||||
if let Some(host_linker) = builder.linker(compiler.host) {
|
||||
let host = crate::envify(&compiler.host.triple);
|
||||
self.command.env(format!("CARGO_TARGET_{host}_LINKER"), host_linker);
|
||||
}
|
||||
for arg in linker_flags(builder, compiler.host, LldThreads::Yes) {
|
||||
self.hostflags.arg(&arg);
|
||||
}
|
||||
|
||||
|
|
@ -319,11 +327,11 @@ impl Cargo {
|
|||
self.command.env(format!("CARGO_TARGET_{target}_LINKER"), target_linker);
|
||||
}
|
||||
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
|
||||
// `linker_args` here.
|
||||
// `linker_args` here. Cargo will pass that to both rustc and rustdoc invocations.
|
||||
for flag in linker_flags(builder, target, LldThreads::Yes) {
|
||||
self.rustflags.arg(&flag);
|
||||
}
|
||||
for arg in linker_args(builder, target, LldThreads::Yes) {
|
||||
for arg in linker_flags(builder, target, LldThreads::Yes) {
|
||||
self.rustdocflags.arg(&arg);
|
||||
}
|
||||
|
||||
|
|
|
|||
40
tests/codegen-llvm/simd/array-repeat.rs
Normal file
40
tests/codegen-llvm/simd/array-repeat.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//@ add-minicore
|
||||
//@ revisions: X86 AARCH64 RISCV S390X
|
||||
//@ [X86] compile-flags: -Copt-level=3 --target=x86_64-unknown-linux-gnu
|
||||
//@ [X86] needs-llvm-components: x86
|
||||
//@ [AARCH64] compile-flags: -Copt-level=3 --target=aarch64-unknown-linux-gnu
|
||||
//@ [AARCH64] needs-llvm-components: aarch64
|
||||
//@ [RISCV] compile-flags: -Copt-level=3 --target riscv64gc-unknown-linux-gnu -Ctarget-feature=+v
|
||||
//@ [RISCV] needs-llvm-components: riscv
|
||||
//@ [S390X] compile-flags: -Copt-level=3 --target s390x-unknown-linux-gnu -Ctarget-feature=+vector
|
||||
//@ [S390X] needs-llvm-components: systemz
|
||||
#![crate_type = "lib"]
|
||||
#![feature(repr_simd)]
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
#[repr(simd)]
|
||||
pub struct Simd<T, const N: usize>(pub [T; N]);
|
||||
|
||||
pub type u8x16 = Simd<u8, 16>;
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/97804.
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
fn foo(v: u16, p: &mut [u8; 16]) {
|
||||
// An array repeat transmuted into a SIMD type should emit a canonical LLVM splat sequence:
|
||||
//
|
||||
// CHECK-LABEL: foo
|
||||
// CHECK: start
|
||||
// CHECK-NEXT: %0 = insertelement <8 x i16> poison, i16 %v, i64 0
|
||||
// CHECK-NEXT: %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <8 x i32> zeroinitializer
|
||||
// CHECK-NEXT: store <8 x i16> %1, ptr %p, align 1
|
||||
// CHECK-NEXT: ret void
|
||||
unsafe {
|
||||
let v: u8x16 = mem::transmute([v; 8]);
|
||||
*p = mem::transmute(v);
|
||||
}
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute);
|
||||
- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _6 };
|
||||
+ _6 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute);
|
||||
- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _6 };
|
||||
+ _6 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute);
|
||||
- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _6 };
|
||||
+ _6 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
StorageLive(_4);
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
- _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as *const [bool; 0] (Transmute);
|
||||
- _6 = const <[bool; 0] as std::mem::SizedTypeProperties>::ALIGNMENT as *const [bool; 0] (Transmute);
|
||||
- _5 = NonNull::<[bool; 0]> { pointer: copy _6 };
|
||||
+ _6 = const {0x1 as *const [bool; 0]};
|
||||
+ _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
StorageLive(_1);
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
- _3 = const std::ptr::Alignment::of::<u8>::{constant#0};
|
||||
- _3 = const <u8 as std::mem::SizedTypeProperties>::ALIGNMENT;
|
||||
- _2 = copy _3 as *mut u8 (Transmute);
|
||||
+ _3 = const std::ptr::Alignment {{ _inner_repr_trick: std::ptr::alignment::AlignmentEnum::_Align1Shl0 }};
|
||||
+ _2 = const {0x1 as *mut u8};
|
||||
|
|
|
|||
|
|
@ -1536,13 +1536,6 @@ mir-opt = [
|
|||
"@wesleywiser",
|
||||
"@saethlin",
|
||||
]
|
||||
types = [
|
||||
"@jackh726",
|
||||
"@lcnr",
|
||||
"@oli-obk",
|
||||
"@spastorino",
|
||||
"@BoxyUwU",
|
||||
]
|
||||
borrowck = [
|
||||
"@davidtwco",
|
||||
"@matthewjasper"
|
||||
|
|
@ -1562,21 +1555,6 @@ style-team = [
|
|||
"@joshtriplett",
|
||||
"@traviscross",
|
||||
]
|
||||
project-const-traits = [
|
||||
"@fee1-dead",
|
||||
"@fmease",
|
||||
"@oli-obk",
|
||||
]
|
||||
project-stable-mir = [
|
||||
"@celinval",
|
||||
"@oli-obk",
|
||||
"@scottmcm",
|
||||
"@makai410",
|
||||
]
|
||||
project-exploit-mitigations = [
|
||||
"@cuviper",
|
||||
"@rcvalle",
|
||||
]
|
||||
compiletest = [
|
||||
"@jieyouxu",
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue