Skip to content

Commit 31e6c96

Browse files
committed
MDEV-20386 WITH_MSAN fails due to inline asm
In commit 94d0bb4 (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).
1 parent 9ef36fa commit 31e6c96

File tree

1 file changed

+15
-24
lines changed

1 file changed

+15
-24
lines changed

storage/innobase/ut/ut0crc32.cc

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,17 @@ mysys/my_perf.c, contributed by Facebook under the following license.
8686
#include "ut0crc32.h"
8787
#include "my_valgrind.h"
8888

89-
#ifdef _MSC_VER
90-
# include <intrin.h>
89+
#ifdef HAVE_CPUID_INSTRUCTION
90+
# ifdef _MSC_VER
91+
# include <intrin.h>
92+
# elif defined __GNUC__ && !defined __clang__ && __GNUC__ < 5
93+
/* <nmmintrin.h> does not really work in GCC before version 5 */
94+
# define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data)
95+
# define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data)
96+
# define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data)
97+
# else
98+
# include <nmmintrin.h>
99+
# endif
91100
#endif
92101

93102
/* CRC32 hardware implementation. */
@@ -123,43 +132,25 @@ static inline bool has_sse4_2()
123132
@param crc CRC-32C checksum so far
124133
@param data data to be checksummed
125134
@return the updated CRC-32C */
135+
__attribute__((target("sse4.2")))
126136
static inline ulint ut_crc32c_8(ulint crc, byte data)
127137
{
128-
# ifdef _MSC_VER
129138
return _mm_crc32_u8(static_cast<uint32_t>(crc), data);
130-
# elif __has_feature(memory_sanitizer)
131-
return __builtin_ia32_crc32qi(static_cast<uint32_t>(crc), data);
132-
# else
133-
asm("crc32b %1, %0" : "+r" (crc) : "rm" (data));
134-
return crc;
135-
# endif
136139
}
137140

138141
/** Append 64 bits (8 aligned bytes) to a CRC-32C checksum
139142
@param[in] crc CRC-32C checksum so far
140143
@param[in] data 8 bytes of aligned data
141144
@return the updated CRC-32C */
145+
__attribute__((target("sse4.2")))
142146
static inline ulint ut_crc32c_64(ulint crc, uint64_t data)
143147
{
144-
# ifdef _MSC_VER
145-
# ifdef _M_X64
148+
# if SIZEOF_SIZE_T > 4
146149
return _mm_crc32_u64(crc, data);
147-
# elif defined(_M_IX86)
150+
# else
148151
crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data));
149152
crc= _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
150153
return crc;
151-
# else
152-
# error Unsupported processor type
153-
# endif
154-
# elif __has_feature(memory_sanitizer)
155-
return __builtin_ia32_crc32di(crc, data);
156-
# elif defined __x86_64__
157-
asm("crc32q %1, %0" : "+r" (crc) : "rm" (data));
158-
return crc;
159-
# else
160-
asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data)));
161-
asm("crc32l %1, %0" : "+r" (crc) : "rm" (static_cast<uint32_t>(data >> 32)));
162-
return crc;
163154
# endif
164155
}
165156

0 commit comments

Comments
 (0)