mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
MDEV-20386 WITH_MSAN fails due to inline asm
In commit 94d0bb4dbe
(MDEV-20377)
we replaced some inline assembler code with calls to GCC-style
builtin functions. These functions would only be available if
the target allows SSE4.2 instructions to be used. Hence, the
cmake -DWITH_MSAN=ON build would fail unless the default x86 (IA-32)
or AMD64 target was overridden.
It turns out that the problem can be solved by overriding the default
target architecture for specific functions with the help of GCC function
attributes.
ut_crc32c_8(), ut_crc32c_64(): Use the compiler-builtin intrinsic
functions. For GCC before 5, the header file <nmmintrin.h> does not
really work, and we must keep using the compiler built-in functions.
For the Microsoft compiler, we will keep using <intrin.h> because
we will also need the definition of the __cpuid() function.
On GCC and clang, we prefer to invoke inline assembler for that.
Curiously, the inline assembler in has_sse4_2() or crc32_pclmul()
is not causing any trouble for MSAN. Also, the inline assembler
in WolfSSL appears to be fine now. Something might have changed
between clang-8 and clang-10 (10.0.1).
This commit is contained in:
parent
9ef36faa61
commit
31e6c96b04
1 changed files with 15 additions and 24 deletions
|
@ -86,8 +86,17 @@ mysys/my_perf.c, contributed by Facebook under the following license.
|
|||
#include "ut0crc32.h"
|
||||
#include "my_valgrind.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#ifdef HAVE_CPUID_INSTRUCTION
|
||||
# ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# elif defined __GNUC__ && !defined __clang__ && __GNUC__ < 5
|
||||
/* <nmmintrin.h> does not really work in GCC before version 5 */
|
||||
# define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data)
|
||||
# define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data)
|
||||
# define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data)
|
||||
# else
|
||||
# include <nmmintrin.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* CRC32 hardware implementation. */
|
||||
|
@ -123,43 +132,25 @@ static inline bool has_sse4_2()
|
|||
@param crc CRC-32C checksum so far
|
||||
@param data data to be checksummed
|
||||
@return the updated CRC-32C */
|
||||
__attribute__((target("sse4.2")))
|
||||
static inline ulint ut_crc32c_8(ulint crc, byte data)
|
||||
{
|
||||
# ifdef _MSC_VER
|
||||
return _mm_crc32_u8(static_cast<uint32_t>(crc), data);
|
||||
# elif __has_feature(memory_sanitizer)
|
||||
return __builtin_ia32_crc32qi(static_cast<uint32_t>(crc), data);
|
||||
# else
|
||||
asm("crc32b %1, %0" : "+r" (crc) : "rm" (data));
|
||||
return crc;
|
||||
# endif
|
||||
}
|
||||
|
||||
/** Append 64 bits (8 aligned bytes) to a CRC-32C checksum
|
||||
@param[in] crc CRC-32C checksum so far
|
||||
@param[in] data 8 bytes of aligned data
|
||||
@return the updated CRC-32C */
|
||||
__attribute__((target("sse4.2")))
|
||||
static inline ulint ut_crc32c_64(ulint crc, uint64_t data)
|
||||
{
|
||||
# ifdef _MSC_VER
|
||||
# ifdef _M_X64
|
||||
# if SIZEOF_SIZE_T > 4
|
||||
return _mm_crc32_u64(crc, data);
|
||||
# elif defined(_M_IX86)
|
||||
# else
|
||||
crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data));
|
||||
crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
|
||||
return crc;
|
||||
# else
|
||||
# error Unsupported processor type
|
||||
# endif
|
||||
# elif __has_feature(memory_sanitizer)
|
||||
return __builtin_ia32_crc32di(crc, data);
|
||||
# elif defined __x86_64__
|
||||
asm("crc32q %1, %0" : "+r" (crc) : "rm" (data));
|
||||
return crc;
|
||||
# else
|
||||
asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data)));
|
||||
asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data >> 32)));
|
||||
return crc;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue