From 783ea9038479b57f2fe74e35fe47263fecb3765e Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Fri, 25 Sep 2026 13:53:37 -0700 Subject: [PATCH] [libyuv] Enable LIBYUV_ENABLE_ROWWIN and MSAN_MEMSET for MSan builds Enable LIBYUV_ENABLE_ROWWIN instead of LIBYUV_DISABLE_X86 under MemorySanitizer so that C++ SIMD intrinsics in row_win.cc and their corresponding _Any wrappers in row_any.cc are compiled and tested under MSan. Rename MEMSET to MSAN_MEMSET in row_any.cc and scale_any.cc, and initialize vout buffers across all ANY* macros in row_any.cc. Use calloc for align_buffer_64 and align_buffer_page_end under LIBYUV_MSAN, and zero-initialize stack pixel buffers in color_test.cc. Test: out/msan/libyuv_unittest Bug: None Change-Id: I0b9fc69af159531699bb2b2db8b48f39831289ee Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8456982 Reviewed-by: richard winterton --- include/libyuv/cpu_support.h | 4 +- include/libyuv/row.h | 9 +++ source/row_any.cc | 129 +++++++++++++++++++++-------------- source/scale_any.cc | 9 ++- unit_test/color_test.cc | 2 + unit_test/unit_test.h | 22 ++++++ 6 files changed, 121 insertions(+), 54 deletions(-) diff --git a/include/libyuv/cpu_support.h b/include/libyuv/cpu_support.h index d9297b5f2..adb50c42d 100644 --- a/include/libyuv/cpu_support.h +++ b/include/libyuv/cpu_support.h @@ -41,8 +41,8 @@ extern "C" { #if !defined(LIBYUV_DISABLE_SVE) #define LIBYUV_DISABLE_SVE #endif -#if !defined(LIBYUV_DISABLE_X86) -#define LIBYUV_DISABLE_X86 +#if !defined(LIBYUV_ENABLE_ROWWIN) +#define LIBYUV_ENABLE_ROWWIN #endif #endif // __has_feature(memory_sanitizer) #endif // defined(__has_feature) diff --git a/include/libyuv/row.h b/include/libyuv/row.h index dbf501f61..5dc2fd35b 100644 --- a/include/libyuv/row.h +++ b/include/libyuv/row.h @@ -1024,12 +1024,21 @@ struct ArgbConstants { #define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1))) +#ifdef LIBYUV_MSAN +#define align_buffer_64(var, size) \ + size_t var##_mem_size = (size); /* NOLINT */ \ + void* var##_mem = (var##_mem_size > SIZE_MAX - 63) \ + ? NULL \ + : calloc(1, var##_mem_size + 63); /* NOLINT */ \ + uint8_t* var = (uint8_t*)(((intptr_t)var##_mem + 63) & ~63) /* NOLINT */ +#else #define align_buffer_64(var, size) \ size_t var##_mem_size = (size); /* NOLINT */ \ void* var##_mem = (var##_mem_size > SIZE_MAX - 63) \ ? NULL \ : malloc(var##_mem_size + 63); /* NOLINT */ \ uint8_t* var = (uint8_t*)(((intptr_t)var##_mem + 63) & ~63) /* NOLINT */ +#endif #define free_aligned_buffer_64(var) \ free(var##_mem); \ diff --git a/source/row_any.cc b/source/row_any.cc index 0a2b652b5..bcc253715 100644 --- a/source/row_any.cc +++ b/source/row_any.cc @@ -18,21 +18,13 @@ namespace libyuv { extern "C" { #endif -// memset for vin is meant to clear the source buffer so that -// SIMD that reads full multiple of 16 bytes will not trigger msan errors. -// memset is not needed for production, as the garbage values are processed but -// not used, although there may be edge cases for subsampling. -// The size of the buffer is based on the largest read, which can be inferred -// by the source type (e.g. ARGB) and the mask (last parameter), or by examining -// the source code for how much the source pointers are advanced. - // Subsampled source needs to be increase by 1 if not even. #define SS(width, shift) (((width) + (1 << (shift)) - 1) >> (shift)) #ifdef LIBYUV_MSAN -#define MEMSET(a, b, c) memset(a, b, c) +#define MSAN_MEMSET(a, b, c) memset(a, b, c) #else -#define MEMSET(a, b, c) +#define MSAN_MEMSET(a, b, c) #endif // Any 4 planes to 1 @@ -45,7 +37,8 @@ extern "C" { SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -82,7 +75,8 @@ ANY41(MergeARGBRow_Any_NEON, MergeARGBRow_NEON, 0, 0, 4, 15) SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -139,7 +133,8 @@ ANY41C(I422AlphaToARGBRow_Any_LASX, I422AlphaToARGBRow_LASX, 1, 0, 4, 15) SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -230,7 +225,8 @@ ANY41CT(I410AlphaToARGBRow_Any_AVX2, "vin buffer too small"); \ SIMD_ALIGNED(DTYPE vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -284,7 +280,8 @@ ANY41PT(MergeARGB16To8Row_Any_NEON, SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - memset(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + memset(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -366,7 +363,8 @@ ANY31(BlendPlaneRow_Any_NEON, BlendPlaneRow_NEON, 0, 0, 1, 15) SIMD_ALIGNED(uint8_t vout[128]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -492,7 +490,8 @@ ANY31C(I444ToARGBRow_Any_LSX, I444ToARGBRow_LSX, 0, 0, 4, 15) SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -571,7 +570,8 @@ ANY31CT(I212ToAR30Row_Any_NEON, I212ToAR30Row_NEON, 1, 0, uint16_t, 2, 4, 7) "vin buffer too small"); \ SIMD_ALIGNED(DTYPE vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -641,7 +641,8 @@ ANY31PT(MergeXRGB16To8Row_Any_NEON, "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[128]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -765,7 +766,8 @@ ANY21(SobelXYRow_Any_LSX, SobelXYRow_LSX, 0, 1, 1, 4, 15) int width) { \ SIMD_ALIGNED(uint8_t vin[(MASK + 1) * SBPP * 2]); \ SIMD_ALIGNED(uint8_t vout[(MASK + 1) * BPP]); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int awidth = (width + 1) / 2; \ int r = awidth & MASK; \ int n = awidth & ~MASK; \ @@ -801,7 +803,8 @@ ANY21S(YUY2ToNVUVRow_Any_AVX2, YUY2ToNVUVRow_AVX2, 4, 2, 15) "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[128]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -891,7 +894,8 @@ ANY21C(NV12ToRGB565Row_Any_LASX, NV12ToRGB565Row_LASX, 1, 1, 2, 2, 15) SIMD_ALIGNED(uint8_t vout[64]); \ static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -953,7 +957,8 @@ ANY21CT(P410ToARGBRow_Any_NEON, P410ToARGBRow_NEON, 0, 0, uint16_t, 2, 4, 7) SIMD_ALIGNED(T vout[16]); \ static_assert((MASK + 1) * BPP * 2 <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -983,7 +988,8 @@ ANY21PT(MergeUVRow_16_Any_NEON, MergeUVRow_16_NEON, uint16_t, 2, 7) "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[256]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1289,8 +1295,8 @@ ANY11(ARGBExtractAlphaRow_Any_LSX, ARGBExtractAlphaRow_LSX, 0, 4, 1, 15) "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ - MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1322,7 +1328,8 @@ ANY11B(ARGBCopyYToAlphaRow_Any_SSE2, ARGBCopyYToAlphaRow_SSE2, 0, 1, 4, 7) void NAMEANY(const uint8_t* src_ptr, uint8_t* dst_ptr, T param, int width) { \ SIMD_ALIGNED(uint8_t vin[(MASK + 1) * SBPP]); \ SIMD_ALIGNED(uint8_t vout[(MASK + 1) * BPP]); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1430,7 +1437,8 @@ ANY11P(ARGBShuffleRow_Any_LASX, ARGBShuffleRow_LASX, const uint8_t*, 4, 4, 15) void NAMEANY(const STYPE* src_ptr, DTYPE* dst_ptr, int width) { \ SIMD_ALIGNED(uint8_t vin[(MASK + 1) * SBPP]); \ SIMD_ALIGNED(uint8_t vout[(MASK + 1) * BPP]); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1499,7 +1507,8 @@ ANY11T(AB64ToARGBRow_Any_NEON, AB64ToARGBRow_NEON, 8, 4, uint16_t, uint8_t, 7) static_assert((MASK + 1) * SBPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(DTYPE vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1626,7 +1635,8 @@ ANY11C(DivideRow_16_Any_NEON, DivideRow_16_NEON, 2, 2, uint16_t, uint16_t, 15) static_assert((MASK + 1) * SBPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(DTYPE vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1665,7 +1675,8 @@ ANY11SB(Convert8To8Row_Any_AVX2, static_assert((MASK + 1) * SBPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(T vout[32]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1710,7 +1721,8 @@ ANY11P16(HalfFloatRow_Any_LSX, HalfFloatRow_LSX, uint16_t, uint16_t, 2, 2, 31) "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[256]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for YUY2 and msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1750,7 +1762,8 @@ ANY11C(UYVYToARGBRow_Any_LSX, UYVYToARGBRow_LSX, 1, 4, 4, 7) SIMD_ALIGNED(TD vout[64]); \ static_assert((MASK + 1) * BPP * sizeof(TD) <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1806,7 +1819,8 @@ ANY11I(InterpolateRow_16_Any_AVX2, SIMD_ALIGNED(TD vout[64]); \ static_assert((MASK + 1) * sizeof(TD) <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1848,7 +1862,8 @@ ANY11HS(HalfRow_16To8_Any_NEON, HalfRow_16To8_NEON, uint16_t, uint8_t, 15) SIMD_ALIGNED(TD vout[64]); \ static_assert((MASK + 1) * sizeof(TD) <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1899,7 +1914,8 @@ ANY11HWS(HalfWidthRow_16To8_Any_NEON, static_assert((MASK + 1) * BPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[128]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -1969,6 +1985,7 @@ ANY11M(RGB24MirrorRow_Any_NEON, RGB24MirrorRow_NEON, 3, 15) void NAMEANY(uint8_t* dst_ptr, T v32, int width) { \ SIMD_ALIGNED(uint8_t vout[64]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2006,7 +2023,8 @@ ANY1(ARGBSetRow_Any_LSX, ARGBSetRow_LSX, uint32_t, 4, 3) SIMD_ALIGNED(uint8_t vout[256 * 2]); \ static_assert(SS(MASK + 1, DUVSHIFT) <= sizeof(vout) / 2, \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2065,7 +2083,8 @@ ANY12(UYVYToUV422Row_Any_LASX, UYVYToUV422Row_LASX, 1, 4, 1, 31) SIMD_ALIGNED(T vout[16 * 2]); \ static_assert((MASK + 1) * BPP <= sizeof(vout) / 2, \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2094,7 +2113,8 @@ ANY12PT(SplitUVRow_16_Any_NEON, SplitUVRow_16_NEON, uint16_t, 2, 7) uint8_t* dst_b, int width) { \ SIMD_ALIGNED(uint8_t vin[(MASK + 1) * BPP]); \ SIMD_ALIGNED(uint8_t vout[(MASK + 1) * 3]); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2141,7 +2161,8 @@ ANY13(SplitXRGBRow_Any_NEON, SplitXRGBRow_NEON, 4, 15) static_assert((MASK + 1) * BPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[16 * 4]); \ static_assert(MASK + 1 <= sizeof(vout) / 4, "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2180,8 +2201,8 @@ ANY14(SplitARGBRow_Any_NEON, SplitARGBRow_NEON, 4, 15) SIMD_ALIGNED(uint8_t vout[256 * 2]); \ static_assert(SS(MASK + 1, 1) <= sizeof(vout) / 2, \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ - MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2209,7 +2230,8 @@ ANY14(SplitARGBRow_Any_NEON, SplitARGBRow_NEON, 4, 15) static_assert((MASK + 1) * BPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[256 * 2]); \ static_assert(MASK + 1 <= sizeof(vout) / 2, "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2231,8 +2253,8 @@ ANY14(SplitARGBRow_Any_NEON, SplitARGBRow_NEON, 4, 15) SIMD_ALIGNED(uint8_t vout[256 * 2]); \ static_assert(SS(MASK + 1, 1) <= sizeof(vout) / 2, \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ - MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2329,7 +2351,8 @@ ANY12M(ARGBToUV444MatrixRow_Any_NEON_I8MM, ARGBToUV444MatrixRow_NEON_I8MM, 4, 7) static_assert((MASK + 1) * BPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[256]); \ static_assert(MASK + 1 <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2475,7 +2498,8 @@ ANY12S(UYVYToUVRow_Any_LASX, UYVYToUVRow_LASX, 1, 4, 31) SIMD_ALIGNED(uint8_t vout[128]); \ static_assert(SS(MASK + 1, 1) * 2 <= sizeof(vout), \ "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2513,7 +2537,8 @@ ANY11S(AYUVToVURow_Any_SVE2, AYUVToVURow_SVE2, 0, 4, 1) static_assert((MASK + 1) * BPP <= sizeof(vin), "vin buffer too small"); \ SIMD_ALIGNED(T vout[16]); \ static_assert((MASK + 1) * BPP <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2550,7 +2575,8 @@ ANYDETILE(DetileRow_16_Any_AVX, DetileRow_16_AVX, uint16_t, 2, 15) SIMD_ALIGNED(uint8_t vout[8 * 2]); \ static_assert((MASK + 1) / 2 <= sizeof(vout) / 2, \ "vout buffer too small"); \ - memset(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2578,7 +2604,8 @@ ANYDETILESPLITUV(DetileSplitUVRow_Any_SSSE3, DetileSplitUVRow_SSSE3, 15) static_assert(MASK + 1 <= sizeof(vin) / 2, "vin buffer too small"); \ SIMD_ALIGNED(uint8_t vout[16 * 2]); \ static_assert(2 * (MASK + 1) <= sizeof(vout), "vout buffer too small"); \ - MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vin, 0, sizeof(vin)); /* for msan */ \ + MSAN_MEMSET(vout, 0, sizeof(vout)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ @@ -2600,7 +2627,7 @@ ANYDETILEMERGE(DetileToYUY2_Any_NEON, DetileToYUY2_NEON, 15) ANYDETILEMERGE(DetileToYUY2_Any_SSE2, DetileToYUY2_SSE2, 15) #endif -#undef MEMSET +#undef MSAN_MEMSET #ifdef __cplusplus } // extern "C" diff --git a/source/scale_any.cc b/source/scale_any.cc index bf7d16202..9ea05d036 100644 --- a/source/scale_any.cc +++ b/source/scale_any.cc @@ -469,6 +469,12 @@ SDAANY(ScaleUVRowDownEven_Any_NEON, #ifdef SASIMDONLY // This also works and uses memcpy and SIMD instead of C, but is slower on ARM +#ifdef LIBYUV_MSAN +#define MSAN_MEMSET(a, b, c) memset(a, b, c) +#else +#define MSAN_MEMSET(a, b, c) +#endif + // Add rows box filter scale down. Using macro from row_any #define SAROW(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \ void NAMEANY(const uint8_t* src_ptr, uint16_t* dst_ptr, int width) { \ @@ -478,7 +484,8 @@ SDAANY(ScaleUVRowDownEven_Any_NEON, SIMD_ALIGNED(uint16_t dst_temp[32]); \ static_assert((MASK + 1) * BPP <= sizeof(dst_temp), \ "dst_temp buffer too small"); \ - memset(src_temp, 0, sizeof(src_temp)); /* for msan */ \ + MSAN_MEMSET(src_temp, 0, sizeof(src_temp)); /* for msan */ \ + MSAN_MEMSET(dst_temp, 0, sizeof(dst_temp)); /* for msan */ \ int r = width & MASK; \ int n = width & ~MASK; \ if (n > 0) { \ diff --git a/unit_test/color_test.cc b/unit_test/color_test.cc index 1cd1c166e..2f46832e3 100644 --- a/unit_test/color_test.cc +++ b/unit_test/color_test.cc @@ -149,6 +149,7 @@ static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) { memset(orig_y, y, kPixels); memset(orig_u, u, kHalfPixels); memset(orig_v, v, kHalfPixels); + memset(orig_pixels, 0, sizeof(orig_pixels)); /* YUV converted to ARGB. */ I422ToARGB(orig_y, kWidth, orig_u, (kWidth + 1) / 2, orig_v, (kWidth + 1) / 2, @@ -172,6 +173,7 @@ static void YUVJToRGB(int y, int u, int v, int* r, int* g, int* b) { memset(orig_y, y, kPixels); memset(orig_u, u, kHalfPixels); memset(orig_v, v, kHalfPixels); + memset(orig_pixels, 0, sizeof(orig_pixels)); /* YUV converted to ARGB. */ J422ToARGB(orig_y, kWidth, orig_u, (kWidth + 1) / 2, orig_v, (kWidth + 1) / 2, diff --git a/unit_test/unit_test.h b/unit_test/unit_test.h index 24f871f15..dd4822c26 100644 --- a/unit_test/unit_test.h +++ b/unit_test/unit_test.h @@ -69,6 +69,15 @@ static inline bool SizeValid(int src_width, return true; } +#ifdef LIBYUV_MSAN +#define align_buffer_page_end(var, size) \ + uint8_t* var = NULL; \ + uint8_t* var##_mem = \ + reinterpret_cast(calloc(1, ((size) + 4095 + 63) & ~4095)); \ + if (var##_mem) \ + var = reinterpret_cast( \ + (intptr_t)(var##_mem + (((size) + 4095 + 63) & ~4095) - (size)) & ~63) +#else #define align_buffer_page_end(var, size) \ uint8_t* var = NULL; \ uint8_t* var##_mem = \ @@ -76,11 +85,23 @@ static inline bool SizeValid(int src_width, if (var##_mem) \ var = reinterpret_cast( \ (intptr_t)(var##_mem + (((size) + 4095 + 63) & ~4095) - (size)) & ~63) +#endif #define free_aligned_buffer_page_end(var) \ free(var##_mem); \ var = NULL +#ifdef LIBYUV_MSAN +#define align_buffer_page_end_16(var, size) \ + uint16_t* var = NULL; \ + uint8_t* var##_mem = \ + reinterpret_cast(calloc(1, ((size) * 2 + 4095 + 63) & ~4095)); \ + if (var##_mem) \ + var = reinterpret_cast( \ + (intptr_t)(var##_mem + (((size) * 2 + 4095 + 63) & ~4095) - \ + (size) * 2) & \ + ~63) +#else #define align_buffer_page_end_16(var, size) \ uint16_t* var = NULL; \ uint8_t* var##_mem = \ @@ -90,6 +111,7 @@ static inline bool SizeValid(int src_width, (intptr_t)(var##_mem + (((size) * 2 + 4095 + 63) & ~4095) - \ (size) * 2) & \ ~63) +#endif #define free_aligned_buffer_page_end_16(var) \ free(var##_mem); \