about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/vec-in-place.rs42
1 files changed, 31 insertions, 11 deletions
diff --git a/tests/codegen/vec-in-place.rs b/tests/codegen/vec-in-place.rs
index 9992604221b..d68067ceb19 100644
--- a/tests/codegen/vec-in-place.rs
+++ b/tests/codegen/vec-in-place.rs
@@ -1,11 +1,13 @@
 // ignore-debug: the debug assertions get in the way
 // compile-flags: -O -Z merge-functions=disabled
+// min-llvm-version: 16
 #![crate_type = "lib"]
 
 // Ensure that trivial casts of vec elements are O(1)
 
 pub struct Wrapper<T>(T);
 
+// previously repr(C) caused the optimization to fail
 #[repr(C)]
 pub struct Foo {
     a: u64,
@@ -14,9 +16,8 @@ pub struct Foo {
     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 repr(C) or non-Copy structs.
+// implementing Copy exercises the TrustedRandomAccess specialization inside the in-place
+// specialization
 #[derive(Copy, Clone)]
 pub struct Bar {
     a: u64,
@@ -25,6 +26,14 @@ pub struct Bar {
     d: u64,
 }
 
+// this exercises the try-fold codepath
+pub struct Baz {
+    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> {
@@ -52,18 +61,29 @@ pub fn vec_iterator_cast_unwrap(vec: Vec<Wrapper<u8>>) -> Vec<u8> {
 // CHECK-LABEL: @vec_iterator_cast_aggregate
 #[no_mangle]
 pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec<Foo> {
-    // FIXME These checks should be the same as other functions.
-    // CHECK-NOT: @__rust_alloc
-    // CHECK-NOT: @__rust_alloc
+    // CHECK-NOT: loop
+    // CHECK-NOT: call
     vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect()
 }
 
-// CHECK-LABEL: @vec_iterator_cast_deaggregate
+// CHECK-LABEL: @vec_iterator_cast_deaggregate_tra
 #[no_mangle]
-pub fn vec_iterator_cast_deaggregate(vec: Vec<Bar>) -> Vec<[u64; 4]> {
-    // FIXME These checks should be the same as other functions.
-    // CHECK-NOT: @__rust_alloc
-    // CHECK-NOT: @__rust_alloc
+pub fn vec_iterator_cast_deaggregate_tra(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()
+}
+
+// CHECK-LABEL: @vec_iterator_cast_deaggregate_fold
+#[no_mangle]
+pub fn vec_iterator_cast_deaggregate_fold(vec: Vec<Baz>) -> 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