-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #95695 - the8472:vec-codegen-tests, r=Mark-Simulacrum
Add codegen tests for additional cases where noop iterators get optimized away Optimizations have improved over time and now LLVM manages to optimize more in-place-collect noop-iterators to O(1) functions. This updates the codegen test to match. Many but not all cases reported in #79308 work now.
- Loading branch information
Showing
1 changed file
with
63 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,72 @@ | ||
// min-llvm-version: 14.0 | ||
// ignore-debug: the debug assertions get in the way | ||
// compile-flags: -O | ||
// compile-flags: -O -Z merge-functions=disabled | ||
#![crate_type = "lib"] | ||
|
||
// Ensure that trivial casts of vec elements are O(1) | ||
|
||
// CHECK-LABEL: @vec_iterator_cast | ||
pub struct Wrapper<T>(T); | ||
|
||
#[repr(C)] | ||
pub struct Foo { | ||
a: u64, | ||
b: u64, | ||
c: u64, | ||
d: u64, | ||
} | ||
|
||
// Going from an aggregate struct to another type currently requires Copy to | ||
// enable the TrustedRandomAccess specialization. Without it optimizations do not yet | ||
// reliably recognize the loops as noop for for repr(C) or non-Copy structs. | ||
#[derive(Copy, Clone)] | ||
pub struct Bar { | ||
a: u64, | ||
b: u64, | ||
c: u64, | ||
d: u64, | ||
} | ||
|
||
// CHECK-LABEL: @vec_iterator_cast_primitive | ||
#[no_mangle] | ||
pub fn vec_iterator_cast_primitive(vec: Vec<i8>) -> Vec<u8> { | ||
// CHECK-NOT: loop | ||
// CHECK-NOT: call | ||
vec.into_iter().map(|e| e as u8).collect() | ||
} | ||
|
||
// CHECK-LABEL: @vec_iterator_cast_wrapper | ||
#[no_mangle] | ||
pub fn vec_iterator_cast_wrapper(vec: Vec<u8>) -> Vec<Wrapper<u8>> { | ||
// CHECK-NOT: loop | ||
// CHECK-NOT: call | ||
vec.into_iter().map(|e| Wrapper(e)).collect() | ||
} | ||
|
||
// CHECK-LABEL: @vec_iterator_cast_unwrap | ||
#[no_mangle] | ||
pub fn vec_iterator_cast_unwrap(vec: Vec<Wrapper<u8>>) -> Vec<u8> { | ||
// CHECK-NOT: loop | ||
// CHECK-NOT: call | ||
vec.into_iter().map(|e| e.0).collect() | ||
} | ||
|
||
// CHECK-LABEL: @vec_iterator_cast_aggregate | ||
#[no_mangle] | ||
pub fn vec_iterator_cast(vec: Vec<isize>) -> Vec<usize> { | ||
pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec<Foo> { | ||
// CHECK-NOT: loop | ||
// CHECK-NOT: call | ||
vec.into_iter().map(|e| e as usize).collect() | ||
vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect() | ||
} | ||
|
||
// CHECK-LABEL: @vec_iterator_cast_deaggregate | ||
#[no_mangle] | ||
pub fn vec_iterator_cast_deaggregate(vec: Vec<Bar>) -> Vec<[u64; 4]> { | ||
// CHECK-NOT: loop | ||
// CHECK-NOT: call | ||
|
||
// Safety: For the purpose of this test we assume that Bar layout matches [u64; 4]. | ||
// This currently is not guaranteed for repr(Rust) types, but it happens to work here and | ||
// the UCG may add additional guarantees for homogenous types in the future that would make this | ||
// correct. | ||
vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect() | ||
} |