From: Yann Collet Date: Tue, 8 Oct 2024 22:54:48 +0000 (-0700) Subject: introduce memory barrier to force test order X-Git-Tag: v1.5.7^2~76^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=197c258a79a94b60ec45020defc5fb6a2f570e80;p=thirdparty%2Fzstd.git introduce memory barrier to force test order suggested by @terrelln --- diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 3c6e75131..9d0cefeac 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -106,7 +106,15 @@ ZSTD_match4Found_cmov(const BYTE* currentPtr, const BYTE* matchAddress, U32 curr * However expression below compiles into conditional move. */ const BYTE* mvalAddr = ZSTD_selectAddr(currentIdx, lowLimit, matchAddress, fakeAddress); - return ((MEM_read32(currentPtr) == MEM_read32(mvalAddr)) & (currentIdx >= lowLimit)); + /* Note: this used to be written as : return test1 && test2; + * Unfortunately, once inlined, these tests become branches, + * in which case it becomes critical that they are executed in the right order (test1 then test2). + * So we have to write these tests in a specific manner to ensure their ordering. + */ + if (MEM_read32(currentPtr) != MEM_read32(mvalAddr)) return 0; + /* force ordering of these tests, which matters once the function is inlined, as they become branches */ + __asm__(""); + return currentIdx >= lowLimit; } static int