[libc-commits] [libc] [libc] Silence sanitizer OOB reports in SIMD read/write helpers. (PR #211148)

Alexey Samsonov via libc-commits libc-commits at lists.llvm.org
Tue Jul 21 17:50:19 PDT 2026


https://github.com/vonosmas created https://github.com/llvm/llvm-project/pull/211148

Use `LIBC_NO_SANITIZE_OOB_ACCESS` for small SIMD helper functions (load/store/gather/scatter/expand/compress). Even though the actual functions which have logical OOB reads (such as `clang_vector::string_length`) already have `LIBC_NO_SANITIZE_OOB_ACCESS` attribute to ignore OOB reads, it's not enough - as we see downstream reports from ASan builds of llvm-libc (using tip-of-trunk Clang), both with `-O1` and `-O2`. We simply can't rely on the SIMD helpers being inlined into the caller function,  with their memory reads/writes ignored.

Thus, apply the `no_sanitize` attribute to the helpers themselves. This is clearly suboptimal, as we're effectively disabling sanitizer checks for *all* the code using SIMD to read/write from memory, but it seems to be the easiest reasonable fix. After all, code using SIMD (like code using explicit intrinsics or inline assembly) should be written only in special cases, with author knowing what they're doing.

>From 25588945cc90364cbdda7ed05561640a7269368d Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas at gmail.com>
Date: Wed, 22 Jul 2026 00:44:34 +0000
Subject: [PATCH] [libc] Silence sanitizer OOB reports in SIMD read/write
 helpers.

---
 libc/src/__support/CPP/simd.h | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/libc/src/__support/CPP/simd.h b/libc/src/__support/CPP/simd.h
index 88d1ea4091a4e..93fecc71d36d0 100644
--- a/libc/src/__support/CPP/simd.h
+++ b/libc/src/__support/CPP/simd.h
@@ -289,7 +289,8 @@ LIBC_INLINE constexpr static T hmax(simd<T, N> v) {
 
 // Accessor helpers.
 template <typename T>
-LIBC_INLINE T constexpr static load(const void *ptr, bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS
+    LIBC_INLINE T constexpr static load(const void *ptr, bool aligned = false) {
   if (aligned)
     ptr = __builtin_assume_aligned(ptr, alignof(T));
   T tmp;
@@ -298,13 +299,14 @@ LIBC_INLINE T constexpr static load(const void *ptr, bool aligned = false) {
   return tmp;
 }
 template <typename T, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static void store(T v, void *ptr, bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static void
+store(T v, void *ptr, bool aligned = false) {
   if (aligned)
     ptr = __builtin_assume_aligned(ptr, alignof(T));
   __builtin_memcpy_inline(ptr, &v, sizeof(T));
 }
 template <typename T, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static T
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static T
 load_masked(simd<bool, simd_size_v<T>> mask, const void *ptr,
             T passthru = internal::poison<T>(), bool aligned = false) {
   if (aligned)
@@ -313,33 +315,34 @@ load_masked(simd<bool, simd_size_v<T>> mask, const void *ptr,
       mask, reinterpret_cast<const simd_element_type_t<T> *>(ptr), passthru);
 }
 template <typename T, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static void store_masked(simd<bool, simd_size_v<T>> mask,
-                                               T v, void *ptr,
-                                               bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static void
+store_masked(simd<bool, simd_size_v<T>> mask, T v, void *ptr,
+             bool aligned = false) {
   if (aligned)
     ptr = __builtin_assume_aligned(ptr, alignof(T));
   __builtin_masked_store(mask, v,
                          reinterpret_cast<simd_element_type_t<T> *>(ptr));
 }
 template <typename T, typename Idx, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static T gather(simd<bool, simd_size_v<T>> mask, Idx idx,
-                                      const void *base, bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static T
+gather(simd<bool, simd_size_v<T>> mask, Idx idx, const void *base,
+       bool aligned = false) {
   if (aligned)
     base = __builtin_assume_aligned(base, alignof(T));
   return __builtin_masked_gather(
       mask, idx, reinterpret_cast<const simd_element_type_t<T> *>(base));
 }
 template <typename T, typename Idx, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static void scatter(simd<bool, simd_size_v<T>> mask,
-                                          Idx idx, T v, void *base,
-                                          bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static void
+scatter(simd<bool, simd_size_v<T>> mask, Idx idx, T v, void *base,
+        bool aligned = false) {
   if (aligned)
     base = __builtin_assume_aligned(base, alignof(T));
   __builtin_masked_scatter(mask, idx, v,
                            reinterpret_cast<simd_element_type_t<T> *>(base));
 }
 template <typename T, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static T
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static T
 expand(simd<bool, simd_size_v<T>> mask, const void *ptr,
        T passthru = internal::poison<T>(), bool aligned = false) {
   if (aligned)
@@ -348,8 +351,9 @@ expand(simd<bool, simd_size_v<T>> mask, const void *ptr,
       mask, reinterpret_cast<const simd_element_type_t<T> *>(ptr), passthru);
 }
 template <typename T, internal::enable_if_simd_t<T> = 0>
-LIBC_INLINE constexpr static void compress(simd<bool, simd_size_v<T>> mask, T v,
-                                           void *ptr, bool aligned = false) {
+LIBC_NO_SANITIZE_OOB_ACCESS LIBC_INLINE constexpr static void
+compress(simd<bool, simd_size_v<T>> mask, T v, void *ptr,
+         bool aligned = false) {
   if (aligned)
     ptr = __builtin_assume_aligned(ptr, alignof(T));
   __builtin_masked_compress_store(



More information about the libc-commits mailing list