summaryrefslogtreecommitdiffstats
path: root/tests/codegen/iter-repeat-n-trivial-drop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen/iter-repeat-n-trivial-drop.rs')
-rw-r--r--tests/codegen/iter-repeat-n-trivial-drop.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/tests/codegen/iter-repeat-n-trivial-drop.rs b/tests/codegen/iter-repeat-n-trivial-drop.rs
new file mode 100644
index 000000000..24059f190
--- /dev/null
+++ b/tests/codegen/iter-repeat-n-trivial-drop.rs
@@ -0,0 +1,56 @@
+// compile-flags: -O
+// only-x86_64
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+#![feature(iter_repeat_n)]
+
+#[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-NEXT: %[[DEC:.+]] = add i64 %[[COUNT]], -1
+ // CHECK-NEXT: store i64 %[[DEC]]
+ // CHECK-NOT: br
+ // CHECK: %[[VAL:.+]] = load i16
+ // CHECK-NEXT: br label %[[EMPTY]]
+
+ // CHECK: [[EMPTY]]:
+ // CHECK-NOT: br
+ // CHECK: phi i16 [ undef, %start ], [ %[[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 noundef dereferenceable_or_null(1234) ptr @__rust_alloc(i64 noundef 1234, i64 noundef 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
+}