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
78pub struct Wrapper < T > ( T ) ;
89
10+ // previously repr(C) caused the optimization to fail
911#[ repr( C ) ]
1012pub 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 ) ]
2122pub 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]
3039pub 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]
5463pub 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