mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			58 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			58 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // 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
 | |
|     // 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 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
 | |
| }
 | 
