1
1
// ignore-debug: the debug assertions get in the way
2
2
// compile-flags: -O -Z merge-functions=disabled
3
+ // min-llvm-version: 16
3
4
#![ crate_type = "lib" ]
4
5
5
6
// Ensure that trivial casts of vec elements are O(1)
6
7
7
8
pub struct Wrapper < T > ( T ) ;
8
9
10
+ // previously repr(C) caused the optimization to fail
9
11
#[ repr( C ) ]
10
12
pub struct Foo {
11
13
a : u64 ,
@@ -14,9 +16,8 @@ pub struct Foo {
14
16
d : u64 ,
15
17
}
16
18
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
20
21
#[ derive( Copy , Clone ) ]
21
22
pub struct Bar {
22
23
a : u64 ,
@@ -25,6 +26,14 @@ pub struct Bar {
25
26
d : u64 ,
26
27
}
27
28
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
+
28
37
// CHECK-LABEL: @vec_iterator_cast_primitive
29
38
#[ no_mangle]
30
39
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> {
52
61
// CHECK-LABEL: @vec_iterator_cast_aggregate
53
62
#[ no_mangle]
54
63
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
58
66
vec. into_iter ( ) . map ( |e| unsafe { std:: mem:: transmute ( e) } ) . collect ( )
59
67
}
60
68
61
- // CHECK-LABEL: @vec_iterator_cast_deaggregate
69
+ // CHECK-LABEL: @vec_iterator_cast_deaggregate_tra
62
70
#[ 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
67
87
68
88
// Safety: For the purpose of this test we assume that Bar layout matches [u64; 4].
69
89
// This currently is not guaranteed for repr(Rust) types, but it happens to work here and
0 commit comments