diff options
Diffstat (limited to 'tests/codegen-llvm/iter-repeat-n-trivial-drop.rs')
| -rw-r--r-- | tests/codegen-llvm/iter-repeat-n-trivial-drop.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs new file mode 100644 index 00000000000..28173530324 --- /dev/null +++ b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs @@ -0,0 +1,70 @@ +//@ compile-flags: -C opt-level=3 +//@ only-x86_64 +//@ needs-deterministic-layouts + +#![crate_type = "lib"] +#![feature(iter_repeat_n)] +#![feature(array_repeat)] + +#[derive(Clone)] +pub struct NotCopy(u16); + +impl Drop for NotCopy { + fn drop(&mut self) {} +} + +// For a type where `Drop::drop` doesn't do anything observable and a clone is the +// same as a move, make sure that the extra case for the last item disappears. + +#[no_mangle] +// CHECK-LABEL: @iter_repeat_n_next +pub fn iter_repeat_n_next(it: &mut std::iter::RepeatN<NotCopy>) -> Option<NotCopy> { + // CHECK-NEXT: start: + // CHECK-NOT: br + // CHECK: %[[COUNT:.+]] = load i64 + // CHECK-NEXT: %[[COUNT_ZERO:.+]] = icmp eq i64 %[[COUNT]], 0 + // CHECK-NEXT: br i1 %[[COUNT_ZERO]], label %[[EMPTY:.+]], label %[[NOT_EMPTY:.+]] + + // CHECK: [[NOT_EMPTY]]: + // CHECK-NOT: br + // CHECK: %[[DEC:.+]] = add i64 %[[COUNT]], -1 + // CHECK-NEXT: %[[VAL:.+]] = load i16 + // CHECK-NEXT: store i64 %[[DEC]] + // CHECK-NEXT: br label %[[EMPTY]] + + // CHECK: [[EMPTY]]: + // CHECK-NOT: br + // CHECK: phi i16 + // CHECK-SAME: [ %[[VAL]], %[[NOT_EMPTY]] ] + // CHECK-NOT: br + // CHECK: ret + + it.next() +} + +// And as a result, using the iterator can optimize without special cases for +// the last iteration, like `memset`ing all the items in one call. + +#[no_mangle] +// CHECK-LABEL: @vec_extend_via_iter_repeat_n +pub fn vec_extend_via_iter_repeat_n() -> Vec<u8> { + // CHECK: %[[ADDR:.+]] = tail call {{(noalias )?}}noundef dereferenceable_or_null(1234) ptr @{{.*}}__rust_alloc(i64 noundef {{(range\(i64 1, 0\) )?}}1234, i64 noundef {{(range\(i64 1, -9223372036854775807\) )?}}1) + // CHECK: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(1234) %[[ADDR]], i8 42, i64 1234, + + let n = 1234_usize; + let mut v = Vec::with_capacity(n); + v.extend(std::iter::repeat_n(42_u8, n)); + v +} + +// Array repeat uses `RepeatN::next_unchecked` internally, +// so also check that the distinction disappears there. + +#[no_mangle] +// CHECK-LABEL: @array_repeat_not_copy +pub unsafe fn array_repeat_not_copy(item: NotCopy) -> [NotCopy; 8] { + // CHECK: insertelement {{.+}} i16 %item + // CHECK: shufflevector <8 x i16> {{.+}} zeroinitializer + // CHECK: store <8 x i16> + std::array::repeat(item) +} |
