[libc-commits] [libc] 20fe9f3 - [libc] Don't declare vector_size types that cannot be compiled (#221119)

via libc-commits libc-commits at lists.llvm.org
Mon Sep 14 11:57:31 PDT 2026


Author: Roland McGrath
Date: 2026-09-14T18:57:25Z
New Revision: 20fe9f35da9952f60188212c5f51debb07af24ca

URL: https://github.com/llvm/llvm-project/commit/20fe9f35da9952f60188212c5f51debb07af24ca
DIFF: https://github.com/llvm/llvm-project/commit/20fe9f35da9952f60188212c5f51debb07af24ca.diff

LOG: [libc] Don't declare vector_size types that cannot be compiled (#221119)

On machines where [[gnu::vector_size(N)]] types are generally
supported, each given N can only be used when the corresponding
CPU features are enabled by the particular -m switches et al.
Don't make any use of a type that's not enabled for native
register use according to the predefines reflecting -m switches.
Even inline and template functions that wind up being unused can
make the compiler give errors about the use of a type whose use
is disabled for ABI or ISA configuration reasons.

Added: 
    

Modified: 
    libc/src/__support/macros/properties/cpu_features.h
    libc/src/string/memory_utils/op_generic.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/macros/properties/cpu_features.h b/libc/src/__support/macros/properties/cpu_features.h
index 7f11f6409f2ee..77daeb7c1fcc2 100644
--- a/libc/src/__support/macros/properties/cpu_features.h
+++ b/libc/src/__support/macros/properties/cpu_features.h
@@ -44,6 +44,7 @@
 #define LIBC_TARGET_CPU_HAS_SSE2
 #define LIBC_TARGET_CPU_HAS_FPU_FLOAT
 #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 128
 #endif
 
 #if defined(__SSE4_2__)
@@ -52,6 +53,8 @@
 
 #if defined(__AVX__)
 #define LIBC_TARGET_CPU_HAS_AVX
+#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 256
 #endif
 
 #if defined(__AVX2__)
@@ -60,6 +63,8 @@
 
 #if defined(__AVX512F__)
 #define LIBC_TARGET_CPU_HAS_AVX512F
+#undef LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
 #endif
 
 #if defined(__AVX512BW__)
@@ -87,6 +92,7 @@
 
 #if defined(__ARM_NEON)
 #define LIBC_TARGET_CPU_HAS_ARM_NEON
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX 512
 #endif
 
 #if defined(__riscv_flen)
@@ -105,6 +111,10 @@
 #endif // LIBC_TARGET_CPU_HAS_RISCV_FPU_DOUBLE
 #endif // __riscv_flen
 
+#if defined(__riscv_v_min_vlen)
+#define LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX __riscv_v_min_vlen
+#endif // __riscv_v_min_vlen
+
 #if defined(__NVPTX__) || defined(__AMDGPU__) || defined(__SPIRV__)
 #define LIBC_TARGET_CPU_HAS_FPU_FLOAT
 #define LIBC_TARGET_CPU_HAS_FPU_DOUBLE

diff  --git a/libc/src/string/memory_utils/op_generic.h b/libc/src/string/memory_utils/op_generic.h
index 670ef085f9dee..46e965fa9a229 100644
--- a/libc/src/string/memory_utils/op_generic.h
+++ b/libc/src/string/memory_utils/op_generic.h
@@ -32,6 +32,7 @@
 #include "src/__support/macros/config.h"     // LIBC_NAMESPACE_DECL
 #include "src/__support/macros/optimization.h"
 #include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
 #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT64
 #include "src/string/memory_utils/op_builtin.h"
 #include "src/string/memory_utils/utils.h"
@@ -40,34 +41,43 @@ static_assert((UINTPTR_MAX == 4294967295U) ||
                   (UINTPTR_MAX == 18446744073709551615UL),
               "We currently only support 32- or 64-bit platforms");
 
-#ifdef LIBC_COMPILER_IS_MSVC
-#ifdef LIBC_TARGET_ARCH_IS_X86
 namespace LIBC_NAMESPACE_DECL {
+
+// Compiler types using the GNU vector attributes.  Clang and GCC support
+// these, but MSVC does not.  However, on x86 MSVC does support the __m*i types
+// instead.  When the compiler does support the types, it's not OK to actually
+// use the ones that correspond to CPU features that are not enabled at compile
+// time by the particular combination of compiler switches used--not even in
+// templates and inlines that are ultimately never used because of other
+// conditionals on when to use which generic_v* types.  For each vector type
+// that is not available either because the target doesn't have them at all, or
+// because the CPU features configured exclude that particular size, is
+// replaced with an aligned byte array.
+
+#if defined(LIBC_COMPILER_IS_MSVC) && defined(LIBC_TARGET_ARCH_IS_X86)
 using generic_v128 = __m128i;
-using generic_v256 = __m256i;
-using generic_v512 = __m512i;
-} // namespace LIBC_NAMESPACE_DECL
+#elif LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX >= 128
+using generic_v128 = uint8_t __attribute__((__vector_size__(16)));
 #else
-// Special handling when target does not have real vector types.
-// We can potentially use uint8x16_t etc. However, MSVC does not provide
-// subscript operation.
-namespace LIBC_NAMESPACE_DECL {
 struct alignas(16) generic_v128 : public cpp::array<uint8_t, 16> {};
-struct alignas(32) generic_v256 : public cpp::array<uint8_t, 32> {};
-struct alignas(64) generic_v512 : public cpp::array<uint8_t, 64> {};
-} // namespace LIBC_NAMESPACE_DECL
 #endif
 
-#else
-namespace LIBC_NAMESPACE_DECL {
-// Compiler types using the vector attributes.
-using generic_v128 = uint8_t __attribute__((__vector_size__(16)));
+#if defined(LIBC_COMPILER_IS_MSVC) && defined(LIBC_TARGET_ARCH_IS_X86)
+using generic_v256 = __m256i;
+#elif LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX >= 256
 using generic_v256 = uint8_t __attribute__((__vector_size__(32)));
+#else
+struct alignas(32) generic_v256 : public cpp::array<uint8_t, 32> {};
+#endif
+
+#if defined(LIBC_COMPILER_IS_MSVC) && defined(LIBC_TARGET_ARCH_IS_X86)
+using generic_v512 = __m512i;
+#elif LIBC_TARGET_CPU_GENERIC_VECTOR_SIZE_MAX >= 512
 using generic_v512 = uint8_t __attribute__((__vector_size__(64)));
-} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_COMPILER_IS_MSVC
+#else
+struct alignas(64) generic_v512 : public cpp::array<uint8_t, 64> {};
+#endif
 
-namespace LIBC_NAMESPACE_DECL {
 namespace generic {
 
 // We accept three types of values as elements for generic operations:


        


More information about the libc-commits mailing list