From c7daf18570169d354cbfb587a4e1a55277e4ce06 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sat, 19 Dec 2020 18:35:36 -0500 Subject: [PATCH 1/3] Remove pointer comparison from slice equality --- library/core/src/slice/cmp.rs | 27 ------------------------- src/test/codegen/slice-ref-ptr-check.rs | 12 +++++++++++ 2 files changed, 12 insertions(+), 27 deletions(-) create mode 100644 src/test/codegen/slice-ref-ptr-check.rs diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 18073f4afedf7..72af47c71dd64 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -75,28 +75,6 @@ where } } -// Use an equal-pointer optimization when types are `Eq` -// We can't make `A` and `B` the same type because `min_specialization` won't -// allow it. -impl SlicePartialEq for [A] -where - A: MarkerEq, -{ - default fn equal(&self, other: &[B]) -> bool { - if self.len() != other.len() { - return false; - } - - // While performance would suffer if `guaranteed_eq` just returned `false` - // for all arguments, correctness and return value of this function are not affected. - if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) { - return true; - } - - self.iter().zip(other.iter()).all(|(x, y)| x == y) - } -} - // Use memcmp for bytewise equality when the types allow impl SlicePartialEq for [A] where @@ -107,11 +85,6 @@ where return false; } - // While performance would suffer if `guaranteed_eq` just returned `false` - // for all arguments, correctness and return value of this function are not affected. - if self.as_ptr().guaranteed_eq(other.as_ptr() as *const A) { - return true; - } // SAFETY: `self` and `other` are references and are thus guaranteed to be valid. // The two slices have been checked to have the same size above. unsafe { diff --git a/src/test/codegen/slice-ref-ptr-check.rs b/src/test/codegen/slice-ref-ptr-check.rs new file mode 100644 index 0000000000000..0184ba373c226 --- /dev/null +++ b/src/test/codegen/slice-ref-ptr-check.rs @@ -0,0 +1,12 @@ +// compile-flags: -C opt-level=3 + +#![crate_type = "lib"] + +// #71602: check that there is no pointer comparison generated for slice equality + +// CHECK-LABEL: @is_zero_slice +#[no_mangle] +pub fn is_zero_slice(data: &[u8; 4]) -> bool { + // CHECK-NOT: %{{.+}} = icmp eq [4 x i8]* {{.+}} + *data == [0; 4] +} From f29b6b8d40bbf4ab45c66d3df0ba6ab74448e415 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Wed, 23 Dec 2020 15:57:00 -0500 Subject: [PATCH 2/3] change test to check for bcmp --- src/test/codegen/slice-ref-equality.rs | 16 ++++++++++++++++ src/test/codegen/slice-ref-ptr-check.rs | 12 ------------ 2 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 src/test/codegen/slice-ref-equality.rs delete mode 100644 src/test/codegen/slice-ref-ptr-check.rs diff --git a/src/test/codegen/slice-ref-equality.rs b/src/test/codegen/slice-ref-equality.rs new file mode 100644 index 0000000000000..80aa29f19944f --- /dev/null +++ b/src/test/codegen/slice-ref-equality.rs @@ -0,0 +1,16 @@ +// compile-flags: -C opt-level=3 + +#![crate_type = "lib"] + +// #71602: check that slice equality just generates a single bcmp + +// CHECK-LABEL: @is_zero_slice +#[no_mangle] +pub fn is_zero_slice(data: &[u8; 4]) -> bool { + // CHECK: start: + // CHECK-NEXT: %{{.+}} = getelementptr {{.+}} + // CHECK-NEXT: %[[BCMP:.+]] = tail call i32 @bcmp({{.+}}) + // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[BCMP]], 0 + // CHECK-NEXT: ret i1 %[[EQ]] + *data == [0; 4] +} diff --git a/src/test/codegen/slice-ref-ptr-check.rs b/src/test/codegen/slice-ref-ptr-check.rs deleted file mode 100644 index 0184ba373c226..0000000000000 --- a/src/test/codegen/slice-ref-ptr-check.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-flags: -C opt-level=3 - -#![crate_type = "lib"] - -// #71602: check that there is no pointer comparison generated for slice equality - -// CHECK-LABEL: @is_zero_slice -#[no_mangle] -pub fn is_zero_slice(data: &[u8; 4]) -> bool { - // CHECK-NOT: %{{.+}} = icmp eq [4 x i8]* {{.+}} - *data == [0; 4] -} From fae3edec018119a09c108d30f695f99ba464699c Mon Sep 17 00:00:00 2001 From: erikdesjardins Date: Wed, 23 Dec 2020 23:59:26 -0500 Subject: [PATCH 3/3] also handle memcmp --- src/test/codegen/slice-ref-equality.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/codegen/slice-ref-equality.rs b/src/test/codegen/slice-ref-equality.rs index 80aa29f19944f..acc7879e7b189 100644 --- a/src/test/codegen/slice-ref-equality.rs +++ b/src/test/codegen/slice-ref-equality.rs @@ -9,7 +9,7 @@ pub fn is_zero_slice(data: &[u8; 4]) -> bool { // CHECK: start: // CHECK-NEXT: %{{.+}} = getelementptr {{.+}} - // CHECK-NEXT: %[[BCMP:.+]] = tail call i32 @bcmp({{.+}}) + // CHECK-NEXT: %[[BCMP:.+]] = tail call i32 @{{bcmp|memcmp}}({{.+}}) // CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[BCMP]], 0 // CHECK-NEXT: ret i1 %[[EQ]] *data == [0; 4]