-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Ensure swap_nonoverlapping
is really always untyped
#137412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use std::mem::{size_of, align_of}; | ||
|
||
// See <https://github.com/rust-lang/rust/issues/134713> | ||
|
||
#[repr(C)] | ||
struct Foo(usize, u8); | ||
|
||
fn main() { | ||
let buf1: [usize; 2] = [1000, 2000]; | ||
let buf2: [usize; 2] = [3000, 4000]; | ||
|
||
// Foo and [usize; 2] have the same size and alignment, | ||
// so swap_nonoverlapping should treat them the same | ||
assert_eq!(size_of::<Foo>(), size_of::<[usize; 2]>()); | ||
assert_eq!(align_of::<Foo>(), align_of::<[usize; 2]>()); | ||
|
||
let mut b1 = buf1; | ||
let mut b2 = buf2; | ||
// Safety: b1 and b2 are distinct local variables, | ||
// with the same size and alignment as Foo. | ||
unsafe { | ||
std::ptr::swap_nonoverlapping( | ||
b1.as_mut_ptr().cast::<Foo>(), | ||
b2.as_mut_ptr().cast::<Foo>(), | ||
1, | ||
); | ||
} | ||
assert_eq!(b1, buf2); | ||
assert_eq!(b2, buf1); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,3 +51,31 @@ pub fn swap_simd(x: &mut __m128, y: &mut __m128) { | |
// CHECK-NEXT: retq | ||
swap(x, y) | ||
} | ||
|
||
// CHECK-LABEL: swap_string: | ||
#[no_mangle] | ||
pub fn swap_string(x: &mut String, y: &mut String) { | ||
// CHECK-NOT: mov | ||
// CHECK-COUNT-4: movups | ||
// CHECK-NOT: mov | ||
// CHECK-COUNT-4: movq | ||
// CHECK-NOT: mov | ||
swap(x, y) | ||
} | ||
|
||
// CHECK-LABEL: swap_44_bytes: | ||
#[no_mangle] | ||
pub fn swap_44_bytes(x: &mut [u8; 44], y: &mut [u8; 44]) { | ||
// Ensure we do better than a long run of byte copies, | ||
// see <https://github.com/rust-lang/rust/issues/134946> | ||
|
||
// CHECK-NOT: movb | ||
// CHECK-COUNT-8: movups{{.+}}xmm | ||
// CHECK-NOT: movb | ||
// CHECK-COUNT-4: movq | ||
// CHECK-NOT: movb | ||
// CHECK-COUNT-4: movl | ||
// CHECK-NOT: movb | ||
// CHECK: retq | ||
Comment on lines
+69
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note for reviewers: the codegen tests here are more about demonstrating what actually happens on a variety of types, and the exact details don't matter that much. Reviewing the rust code is enough to know that LLVM will swap it, but for example here what we're trying to see is that it's not just a huge row of |
||
swap(x, y) | ||
} |
Uh oh!
There was an error while loading. Please reload this page.