Skip to content

Commit 3c67f04

Browse files
committed
Fix infinite recursion in x86_64 memcmp if SSE2 is not present
Fixes rust-lang#470
1 parent dde946c commit 3c67f04

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/mem/x86_64.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,16 @@ pub unsafe fn compare_bytes(a: *const u8, b: *const u8, n: usize) -> i32 {
143143
let c8 = |a: *const u64, b, n| cmp(a, b, n, c4);
144144
let c16 = |a: *const u128, b, n| cmp(a, b, n, c8);
145145
let c32 = |a: *const [u128; 2], b, n| cmp(a, b, n, c16);
146-
c32(a.cast(), b.cast(), n)
146+
// [u128; 2] internally uses raw_eq for comparisons, which may emit a call to memcmp
147+
// above a certain size threshold. When SSE2 is enabled this threshold does not seem
148+
// to be reached but without SSE2 a call is emitted, leading to infinite recursion.
149+
//
150+
// While replacing [u128; 2] with (u128, u128) fixes the issues it degrades performance
151+
// severely. Likewise, removing c32() has a lesser but still significant impact. Instead the
152+
// [u128; 2] case is only enabled when SSE2 is present.
153+
if cfg!(target_feature = "sse2") {
154+
c32(a.cast(), b.cast(), n)
155+
} else {
156+
c16(a.cast(), b.cast(), n)
157+
}
147158
}

0 commit comments

Comments
 (0)