[libc-commits] [libc] [libc] Silence sanitizer OOB reports in SIMD read/write helpers. (PR #211148)
via libc-commits
libc-commits at lists.llvm.org
Tue Jul 21 17:51:04 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Alexey Samsonov (vonosmas)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/211148.diff
1 Files Affected:
- (modified) libc/src/__support/CPP/simd.h (+18-14)
``````````diff
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(
``````````
</details>
https://github.com/llvm/llvm-project/pull/211148
More information about the libc-commits
mailing list