mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Enable MSAN in mem*Overflow15 functions
This commit is contained in:
parent
7f8449f6d8
commit
10c09b5817
@ -13,6 +13,9 @@
|
||||
#undef __msan_unpoison_string
|
||||
|
||||
#define __msan_unpoison(X, Y) /// NOLINT
|
||||
/// Given a pointer and **its size**, unpoisons up to 15 bytes **at the end**
|
||||
/// See memcmpSmall.h / memcpySmall.h
|
||||
#define __msan_unpoison_overflow_15(X, Y) /// NOLINT
|
||||
#define __msan_test_shadow(X, Y) (false) /// NOLINT
|
||||
#define __msan_print_shadow(X, Y) /// NOLINT
|
||||
#define __msan_unpoison_string(X) /// NOLINT
|
||||
@ -24,6 +27,8 @@
|
||||
# undef __msan_print_shadow
|
||||
# undef __msan_unpoison_string
|
||||
# include <sanitizer/msan_interface.h>
|
||||
# undef __msan_unpoison_overflow_15
|
||||
# define __msan_unpoison_overflow_15(PTR, PTR_SIZE) __msan_unpoison(&(PTR)[(PTR_SIZE) - ((PTR_SIZE) % 16)], ((PTR_SIZE) % 16))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <base/simd.h>
|
||||
|
||||
#include <Core/Defines.h>
|
||||
#include <Common/MemorySanitizer.h>
|
||||
|
||||
|
||||
namespace detail
|
||||
@ -26,9 +27,8 @@ inline int cmp(T a, T b)
|
||||
|
||||
|
||||
/// We can process uninitialized memory in the functions below.
|
||||
/// Results don't depend on the values inside uninitialized memory but Memory Sanitizer cannot see it.
|
||||
/// Disable optimized functions if compile with Memory Sanitizer.
|
||||
#if defined(__AVX512BW__) && defined(__AVX512VL__) && !defined(MEMORY_SANITIZER)
|
||||
/// Results don't depend on the values inside uninitialized memory
|
||||
#if defined(__AVX512BW__) && defined(__AVX512VL__)
|
||||
# include <immintrin.h>
|
||||
|
||||
|
||||
@ -42,6 +42,9 @@ inline int cmp(T a, T b)
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -74,6 +77,9 @@ inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char
|
||||
template <typename Char>
|
||||
inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -144,6 +150,9 @@ inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_siz
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, const Char * b, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, size);
|
||||
__msan_unpoison_overflow_15(b, size);
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
uint16_t mask = _mm_cmp_epi8_mask(
|
||||
@ -174,6 +183,9 @@ inline bool memequalSmallAllowOverflow15(const Char * a, size_t a_size, const Ch
|
||||
if (a_size != b_size)
|
||||
return false;
|
||||
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < a_size; offset += 16)
|
||||
{
|
||||
uint16_t mask = _mm_cmp_epi8_mask(
|
||||
@ -246,6 +258,7 @@ inline bool memequal16(const void * a, const void * b)
|
||||
/** Compare memory region to zero */
|
||||
inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(reinterpret_cast<const char *>(data), size);
|
||||
const __m128i zero16 = _mm_setzero_si128();
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
@ -263,7 +276,7 @@ inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(__SSE2__) && !defined(MEMORY_SANITIZER)
|
||||
#elif defined(__SSE2__)
|
||||
# include <emmintrin.h>
|
||||
|
||||
|
||||
@ -277,6 +290,9 @@ inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -309,6 +325,9 @@ inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char
|
||||
template <typename Char>
|
||||
inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -380,6 +399,9 @@ inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_siz
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, const Char * b, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, size);
|
||||
__msan_unpoison_overflow_15(b, size);
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
uint16_t mask = _mm_movemask_epi8(_mm_cmpeq_epi8(
|
||||
@ -410,6 +432,9 @@ inline bool memequalSmallAllowOverflow15(const Char * a, size_t a_size, const Ch
|
||||
if (a_size != b_size)
|
||||
return false;
|
||||
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < a_size; offset += 16)
|
||||
{
|
||||
uint16_t mask = _mm_movemask_epi8(_mm_cmpeq_epi8(
|
||||
@ -483,6 +508,8 @@ inline bool memequal16(const void * a, const void * b)
|
||||
/** Compare memory region to zero */
|
||||
inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(reinterpret_cast<const char *>(data), size);
|
||||
|
||||
const __m128i zero16 = _mm_setzero_si128();
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
@ -509,6 +536,9 @@ inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -534,6 +564,9 @@ inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char
|
||||
template <typename Char>
|
||||
inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, a_size);
|
||||
__msan_unpoison_overflow_15(b, b_size);
|
||||
|
||||
size_t min_size = std::min(a_size, b_size);
|
||||
|
||||
for (size_t offset = 0; offset < min_size; offset += 16)
|
||||
@ -599,6 +632,9 @@ inline int memcmpSmallLikeZeroPaddedAllowOverflow15(const Char * a, size_t a_siz
|
||||
template <typename Char>
|
||||
inline int memcmpSmallAllowOverflow15(const Char * a, const Char * b, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(a, size);
|
||||
__msan_unpoison_overflow_15(b, size);
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
uint64_t mask = getNibbleMask(vceqq_u8(
|
||||
@ -625,6 +661,9 @@ inline bool memequalSmallAllowOverflow15(const Char * a, size_t a_size, const Ch
|
||||
if (a_size != b_size)
|
||||
return false;
|
||||
|
||||
__msan_unpoison(&a[a_size - a_size % 16], a_size % 16);
|
||||
__msan_unpoison(&b[b_size - b_size % 16], b_size % 16);
|
||||
|
||||
for (size_t offset = 0; offset < a_size; offset += 16)
|
||||
{
|
||||
uint64_t mask = getNibbleMask(vceqq_u8(
|
||||
@ -683,6 +722,7 @@ inline bool memequal16(const void * a, const void * b)
|
||||
|
||||
inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size)
|
||||
{
|
||||
__msan_unpoison_overflow_15(reinterpret_cast<const char *>(data), size);
|
||||
for (size_t offset = 0; offset < size; offset += 16)
|
||||
{
|
||||
uint64_t mask = getNibbleMask(vceqzq_u8(vld1q_u8(reinterpret_cast<const unsigned char *>(data) + offset)));
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Common/MemorySanitizer.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <sys/types.h> /// ssize_t
|
||||
|
||||
@ -38,6 +40,7 @@ namespace detail
|
||||
{
|
||||
inline void memcpySmallAllowReadWriteOverflow15Impl(char * __restrict dst, const char * __restrict src, ssize_t n)
|
||||
{
|
||||
__msan_unpoison_overflow_15(src, n);
|
||||
while (n > 0)
|
||||
{
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(dst),
|
||||
@ -64,6 +67,7 @@ namespace detail
|
||||
{
|
||||
inline void memcpySmallAllowReadWriteOverflow15Impl(char * __restrict dst, const char * __restrict src, ssize_t n)
|
||||
{
|
||||
__msan_unpoison_overflow_15(src, n);
|
||||
while (n > 0)
|
||||
{
|
||||
vst1q_s8(reinterpret_cast<signed char *>(dst), vld1q_s8(reinterpret_cast<const signed char *>(src)));
|
||||
|
Loading…
Reference in New Issue
Block a user