Skip to content

Commit

Permalink
Remove pointer comparison from slice equality
Browse files Browse the repository at this point in the history
This resurrects #71735.

Fixes #71602, helps with #80140.

r? `@Mark-Simulacrum`
  • Loading branch information
bors committed Dec 26, 2020
1 parent 1f5bc17 commit 733cb54
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 27 deletions.
27 changes: 0 additions & 27 deletions library/core/src/slice/cmp.rs
Expand Up @@ -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<A, B> SlicePartialEq<B> for [A]
where
A: MarkerEq<B>,
{
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<A, B> SlicePartialEq<B> for [A]
where
Expand All @@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions 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|memcmp}}({{.+}})
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[BCMP]], 0
// CHECK-NEXT: ret i1 %[[EQ]]
*data == [0; 4]
}

0 comments on commit 733cb54

Please sign in to comment.