Skip to content

Commit 820e27a

Browse files
committed
avoid phi node for pointers flowing into Vec appends
1 parent 6c8138d commit 820e27a

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

library/alloc/src/slice.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,9 @@ impl<T> [T] {
451451
// allocated above with the capacity of `s`, and initialize to `s.len()` in
452452
// ptr::copy_to_non_overlapping below.
453453
unsafe {
454+
use core::hint::assert_unchecked;
455+
456+
assert_unchecked(v.capacity() != 0);
454457
s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
455458
v.set_len(s.len());
456459
}

library/alloc/src/vec/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,8 +2589,17 @@ impl<T, A: Allocator> Vec<T, A> {
25892589
#[track_caller]
25902590
unsafe fn append_elements(&mut self, other: *const [T]) {
25912591
let count = other.len();
2592+
if count == 0 {
2593+
// The early return is not necessary for correctness, but in cases
2594+
// where LLVM sees all the way to the allocation site of `other`
2595+
// this can avoid a phi-node merging the two different pointers
2596+
// when zero-length allocations are special-cased.
2597+
// That in turn can enable more optimizations around the memcpy below.
2598+
return;
2599+
}
25922600
self.reserve(count);
25932601
let len = self.len();
2602+
unsafe { core::hint::assert_unchecked(self.capacity() != 0) };
25942603
unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) };
25952604
self.len += count;
25962605
}

0 commit comments

Comments
 (0)