|
1 | 1 | //@ compile-flags: -O
|
| 2 | +//@ min-llvm-version: 18 (which added `dead_on_unwind`) |
2 | 3 | #![crate_type = "lib"]
|
3 | 4 | #![feature(exact_size_is_empty)]
|
| 5 | +#![feature(iter_advance_by)] |
| 6 | +#![feature(iter_next_chunk)] |
4 | 7 |
|
5 |
| -use std::vec; |
| 8 | +use std::{array, vec}; |
6 | 9 |
|
7 | 10 | // CHECK-LABEL: @vec_iter_len_nonnull
|
8 | 11 | #[no_mangle]
|
@@ -56,3 +59,60 @@ pub fn vec_iter_next_back_nonnull(it: &mut vec::IntoIter<u8>) -> Option<u8> {
|
56 | 59 | // CHECK: ret
|
57 | 60 | it.next_back()
|
58 | 61 | }
|
| 62 | + |
| 63 | +// CHECK-LABEL: @vec_iter_next_transfers_ownership |
| 64 | +#[no_mangle] |
| 65 | +pub fn vec_iter_next_transfers_ownership(it: &mut vec::IntoIter<Box<i32>>) -> Option<Box<i32>> { |
| 66 | + // CHECK-NOT: __rust_dealloc |
| 67 | + it.next() |
| 68 | +} |
| 69 | + |
| 70 | +// CHECK-LABEL: @vec_iter_advance_drops_item |
| 71 | +#[no_mangle] |
| 72 | +pub fn vec_iter_advance_drops_item(it: &mut vec::IntoIter<Box<i32>>) { |
| 73 | + // CHECK-NOT: __rust_dealloc |
| 74 | + // CHECK: call void @__rust_dealloc |
| 75 | + // CHECK-SAME: noundef 4 |
| 76 | + // CHECK-SAME: noundef 4 |
| 77 | + // CHECK-NOT: __rust_dealloc |
| 78 | + _ = it.advance_by(1); |
| 79 | +} |
| 80 | + |
| 81 | +// CHECK-LABEL: @vec_iter_next_chunk_short |
| 82 | +// CHECK-SAME: ptr{{.+}}%[[RET:.+]], |
| 83 | +#[no_mangle] |
| 84 | +pub fn vec_iter_next_chunk_short( |
| 85 | + it: &mut vec::IntoIter<u8>, |
| 86 | +) -> Result<[u8; 4], array::IntoIter<u8, 4>> { |
| 87 | + // CHECK-NOT: alloca |
| 88 | + // CHECK: %[[ACTUAL_LEN:.+]] = sub nuw |
| 89 | + |
| 90 | + // CHECK: %[[OUT1:.+]] = getelementptr inbounds i8, ptr %[[RET]] |
| 91 | + // CHECK: call void @llvm.memcpy{{.+}}(ptr{{.+}}%[[OUT1]],{{.+}} %[[ACTUAL_LEN]], i1 false) |
| 92 | + // CHECK: br |
| 93 | + |
| 94 | + // CHECK: %[[FULL:.+]] = load i32, |
| 95 | + // CHECK: %[[OUT2:.+]] = getelementptr inbounds i8, ptr %[[RET]] |
| 96 | + // CHECK: store i32 %[[FULL]], ptr %[[OUT2]] |
| 97 | + // CHECK: br |
| 98 | + it.next_chunk::<4>() |
| 99 | +} |
| 100 | + |
| 101 | +// CHECK-LABEL: @vec_iter_next_chunk_long |
| 102 | +// CHECK-SAME: ptr{{.+}}%[[RET:.+]], |
| 103 | +#[no_mangle] |
| 104 | +pub fn vec_iter_next_chunk_long( |
| 105 | + it: &mut vec::IntoIter<u8>, |
| 106 | +) -> Result<[u8; 123], array::IntoIter<u8, 123>> { |
| 107 | + // CHECK-NOT: alloca |
| 108 | + // CHECK: %[[ACTUAL_LEN:.+]] = sub nuw |
| 109 | + |
| 110 | + // CHECK: %[[OUT1:.+]] = getelementptr inbounds i8, ptr %[[RET]] |
| 111 | + // CHECK: call void @llvm.memcpy{{.+}}(ptr{{.+}}%[[OUT1]],{{.+}} %[[ACTUAL_LEN]], i1 false) |
| 112 | + // CHECK: br |
| 113 | + |
| 114 | + // CHECK: %[[OUT2:.+]] = getelementptr inbounds i8, ptr %[[RET]] |
| 115 | + // CHECK: call void @llvm.memcpy{{.+}}(ptr{{.+}}%[[OUT2]],{{.+}} 123, i1 false) |
| 116 | + // CHECK: br |
| 117 | + it.next_chunk::<123>() |
| 118 | +} |
0 commit comments