Skip to content

Commit 7a70647

Browse files
committed
llvm 16 finally reconizes some additional vec in-place conversions as noops
1 parent 932c173 commit 7a70647

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

tests/codegen/vec-in-place.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// ignore-debug: the debug assertions get in the way
22
// compile-flags: -O -Z merge-functions=disabled
3+
// min-llvm-version: 16
34
#![crate_type = "lib"]
45

56
// Ensure that trivial casts of vec elements are O(1)
67

78
pub struct Wrapper<T>(T);
89

10+
// previously repr(C) caused the optimization to fail
911
#[repr(C)]
1012
pub struct Foo {
1113
a: u64,
@@ -14,9 +16,8 @@ pub struct Foo {
1416
d: u64,
1517
}
1618

17-
// Going from an aggregate struct to another type currently requires Copy to
18-
// enable the TrustedRandomAccess specialization. Without it optimizations do not yet
19-
// reliably recognize the loops as noop for repr(C) or non-Copy structs.
19+
// implementing Copy exercises the TrustedRandomAccess specialization inside the in-place
20+
// specialization
2021
#[derive(Copy, Clone)]
2122
pub struct Bar {
2223
a: u64,
@@ -25,6 +26,14 @@ pub struct Bar {
2526
d: u64,
2627
}
2728

29+
// this exercises the try-fold codepath
30+
pub struct Baz {
31+
a: u64,
32+
b: u64,
33+
c: u64,
34+
d: u64,
35+
}
36+
2837
// CHECK-LABEL: @vec_iterator_cast_primitive
2938
#[no_mangle]
3039
pub fn vec_iterator_cast_primitive(vec: Vec<i8>) -> Vec<u8> {
@@ -52,18 +61,29 @@ pub fn vec_iterator_cast_unwrap(vec: Vec<Wrapper<u8>>) -> Vec<u8> {
5261
// CHECK-LABEL: @vec_iterator_cast_aggregate
5362
#[no_mangle]
5463
pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec<Foo> {
55-
// FIXME These checks should be the same as other functions.
56-
// CHECK-NOT: @__rust_alloc
57-
// CHECK-NOT: @__rust_alloc
64+
// CHECK-NOT: loop
65+
// CHECK-NOT: call
5866
vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect()
5967
}
6068

61-
// CHECK-LABEL: @vec_iterator_cast_deaggregate
69+
// CHECK-LABEL: @vec_iterator_cast_deaggregate_tra
6270
#[no_mangle]
63-
pub fn vec_iterator_cast_deaggregate(vec: Vec<Bar>) -> Vec<[u64; 4]> {
64-
// FIXME These checks should be the same as other functions.
65-
// CHECK-NOT: @__rust_alloc
66-
// CHECK-NOT: @__rust_alloc
71+
pub fn vec_iterator_cast_deaggregate_tra(vec: Vec<Bar>) -> Vec<[u64; 4]> {
72+
// CHECK-NOT: loop
73+
// CHECK-NOT: call
74+
75+
// Safety: For the purpose of this test we assume that Bar layout matches [u64; 4].
76+
// This currently is not guaranteed for repr(Rust) types, but it happens to work here and
77+
// the UCG may add additional guarantees for homogenous types in the future that would make this
78+
// correct.
79+
vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect()
80+
}
81+
82+
// CHECK-LABEL: @vec_iterator_cast_deaggregate_fold
83+
#[no_mangle]
84+
pub fn vec_iterator_cast_deaggregate_fold(vec: Vec<Baz>) -> Vec<[u64; 4]> {
85+
// CHECK-NOT: loop
86+
// CHECK-NOT: call
6787

6888
// Safety: For the purpose of this test we assume that Bar layout matches [u64; 4].
6989
// This currently is not guaranteed for repr(Rust) types, but it happens to work here and

0 commit comments

Comments
 (0)