| //@ compile-flags: -Copt-level=3 | 
 | //@ needs-deterministic-layouts | 
 | #![crate_type = "lib"] | 
 | #![feature(exact_size_is_empty)] | 
 |  | 
 | // The slice iterator used to `assume` that the `start` pointer was non-null. | 
 | // That ought to be unneeded, though, since the type is `NonNull`, so this test | 
 | // confirms that the appropriate metadata is included to denote that. | 
 |  | 
 | // It also used to `assume` the `end` pointer was non-null, but that's no longer | 
 | // needed as the code changed to read it as a `NonNull`, and thus gets the | 
 | // appropriate `!nonnull` annotations naturally. | 
 |  | 
 | // CHECK-LABEL: @slice_iter_next( | 
 | #[no_mangle] | 
 | pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { | 
 |     // CHECK: %[[START:.+]] = load ptr, ptr %it, | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} | 
 |     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: icmp eq ptr %[[START]], %[[END]] | 
 |  | 
 |     // CHECK: store ptr{{.+}}, ptr %it, | 
 |  | 
 |     it.next() | 
 | } | 
 |  | 
 | // CHECK-LABEL: @slice_iter_next_back( | 
 | #[no_mangle] | 
 | pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { | 
 |     // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} | 
 |     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: %[[START:.+]] = load ptr, ptr %it, | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: icmp eq ptr %[[START]], %[[END]] | 
 |  | 
 |     // CHECK: store ptr{{.+}}, ptr %[[ENDP]], | 
 |  | 
 |     it.next_back() | 
 | } | 
 |  | 
 | // The slice iterator `new` methods used to `assume` that the pointer is non-null, | 
 | // but passing slices already requires that, to the extent that LLVM actually | 
 | // removed the `call @llvm.assume` anyway.  These tests just demonstrate that the | 
 | // attribute is there, and confirms adding the assume back doesn't do anything. | 
 |  | 
 | // CHECK-LABEL: @slice_iter_new | 
 | // CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) | 
 | #[no_mangle] | 
 | pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: insertvalue {{.+}} ptr %slice.0, 0 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: insertvalue {{.+}} ptr %[[END]], 1 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: } | 
 |     slice.iter() | 
 | } | 
 |  | 
 | // CHECK-LABEL: @slice_iter_mut_new | 
 | // CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) | 
 | #[no_mangle] | 
 | pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: %[[END:.+]] = getelementptr inbounds{{( nuw)?}} i32{{.+}} %slice.0{{.+}} %slice.1 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: insertvalue {{.+}} ptr %slice.0, 0 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: insertvalue {{.+}} ptr %[[END]], 1 | 
 |     // CHECK-NOT: slice | 
 |     // CHECK: } | 
 |     slice.iter_mut() | 
 | } | 
 |  | 
 | // CHECK-LABEL: @slice_iter_is_empty | 
 | #[no_mangle] | 
 | pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { | 
 |     // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} | 
 |     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: %[[START:.+]] = load ptr, ptr %it, | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |  | 
 |     // CHECK: %[[RET:.+]] = icmp eq ptr %[[START]], %[[END]] | 
 |     // CHECK: ret i1 %[[RET]] | 
 |     it.is_empty() | 
 | } | 
 |  | 
 | // CHECK-LABEL: @slice_iter_len | 
 | #[no_mangle] | 
 | pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize { | 
 |     // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} | 
 |     // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |     // CHECK: %[[START:.+]] = load ptr, ptr %it, | 
 |     // CHECK-SAME: !nonnull | 
 |     // CHECK-SAME: !noundef | 
 |  | 
 |     // CHECK: ptrtoint | 
 |     // CHECK: ptrtoint | 
 |     // CHECK: sub nuw | 
 |     // CHECK: lshr exact | 
 |     it.len() | 
 | } |