https://github.com/freaknbigpanda updated https://github.com/llvm/llvm-project/pull/199091
>From f4f2c695e7c6e0a5b2cbc1ef045908353caf9069 Mon Sep 17 00:00:00 2001 From: Benjamin Luke <[email protected]> Date: Wed, 20 May 2026 11:53:38 -0700 Subject: [PATCH 1/4] [clang][X86] Emit AVX level mismatch psABI warnings on function definitions Emit -WpsABI for x86_64 function definitions whose return type or parameter type uses a vector wider than 128 bits without the required ABI feature enabled. 256-bit vectors require avx, and 512-bit vectors require avx512f. Previously this diagnostic was only emitted at call sites, so definitions with wide vector signatures could be introduced without a warning until they were called. Use the function feature map so attribute(target("avx/avx512f")) definitions are accepted, and emit no warnings for prototype-only declarations. --- clang/lib/CodeGen/Targets/X86.cpp | 51 +++++++++++++++++++ clang/test/CodeGen/X86/mmx-inline-asm-error.c | 2 + clang/test/CodeGen/target-builtin-error-3.c | 6 +++ clang/test/CodeGen/target-features-error-2.c | 1 + clang/test/CodeGenCXX/target-avx-abi-diag.cpp | 37 ++++++++++++++ libc/src/mathvec/generic/CMakeLists.txt | 2 + libcxx/utils/libcxx/test/params.py | 3 ++ 7 files changed, 102 insertions(+) create mode 100644 clang/test/CodeGenCXX/target-avx-abi-diag.cpp diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 61ab591f55be9..6ea4df1bc5438 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -9,6 +9,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/SourceLocation.h" #include "llvm/ADT/SmallBitVector.h" using namespace clang; @@ -1509,6 +1510,9 @@ class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args, QualType ReturnType) const override; + + void checkFunctionABI(CodeGenModule &CGM, + const FunctionDecl *FD) const override; }; } // namespace @@ -1571,6 +1575,53 @@ static bool checkAVXParam(DiagnosticsEngine &Diag, ASTContext &Ctx, return false; } +void X86_64TargetCodeGenInfo::checkFunctionABI(CodeGenModule &CGM, + const FunctionDecl *FD) const { + auto GetReturnTypeLoc = [](const FunctionDecl *FD) { + if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo()) { + TypeLoc TL = TSI->getTypeLoc(); + + if (auto FTL = TL.IgnoreParens().getAs<FunctionTypeLoc>()) + return FTL.getReturnLoc().getBeginLoc(); + } + + return FD->getLocation(); + }; + + auto Check = [&](QualType Ty, SourceLocation Loc, bool IsReturn) { + if (!Ty->isVectorType()) + return false; + if (CGM.getContext().getTypeSize(Ty) <= 128) + return false; + + StringRef Feature = + CGM.getContext().getTypeSize(Ty) > 256 ? "avx512f" : "avx"; + + llvm::StringMap<bool> FeatureMap; + CGM.getContext().getFunctionFeatureMap(FeatureMap, FD); + if (!FeatureMap.lookup(Feature)) { + CGM.getDiags().Report(Loc, diag::warn_avx_calling_convention) + << !IsReturn << Ty << Feature; + return true; + } + + return false; + }; + + // First check the return type and emit diagnostic if required + Check(FD->getReturnType(), GetReturnTypeLoc(FD), true); + + // Go through the parameters and emit a warning for the first vector found + // without the matching function AVX level attribute + for (const ParmVarDecl *P : FD->parameters()) { + SourceLocation Loc = P->getLocation(); + if (Loc.isInvalid()) + Loc = P->getBeginLoc(); + if (Check(P->getType(), Loc, false)) + return; + } +} + void X86_64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, diff --git a/clang/test/CodeGen/X86/mmx-inline-asm-error.c b/clang/test/CodeGen/X86/mmx-inline-asm-error.c index 8a2f991a537a2..7f7f53a553057 100644 --- a/clang/test/CodeGen/X86/mmx-inline-asm-error.c +++ b/clang/test/CodeGen/X86/mmx-inline-asm-error.c @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -verify=omp -triple x86_64-unknown-unknown -emit-llvm-only -fopenmp %s typedef int vec256 __attribute__((ext_vector_type(8))); +// omp-warning@+2 {{AVX vector return of type 'vec256' (vector of 8 'int' values) without 'avx' enabled changes the ABI}} +// omp-warning@+1 {{AVX vector argument of type 'vec256' (vector of 8 'int' values) without 'avx' enabled changes the ABI}} vec256 foo(vec256 in) { vec256 out; diff --git a/clang/test/CodeGen/target-builtin-error-3.c b/clang/test/CodeGen/target-builtin-error-3.c index 056dc940f7a93..840ca7534905d 100644 --- a/clang/test/CodeGen/target-builtin-error-3.c +++ b/clang/test/CodeGen/target-builtin-error-3.c @@ -17,32 +17,38 @@ typedef __attribute__ ((ext_vector_type(16),__aligned__( 64))) float float16; static inline half8 __attribute__((__overloadable__)) convert_half( float8 a ) { return __extension__ ({ __m256 __a = (a); (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)__a, (0x00)); }); // expected-error {{'__builtin_ia32_vcvtps2ph256' needs target feature f16c}} } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} static inline half16 __attribute__((__overloadable__)) convert_half( float16 a ) { half16 r; r.lo = convert_half(a.lo); return r; } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} void avx_test( uint16_t *destData, float16 argbF) { ((half16U *)destData)[0] = convert_half(argbF); } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} half16 test( float16 a ) { half16 r; r.lo = convert_half(a.lo); return r; } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} void avx_test2( uint16_t *destData, float16 argbF) { // expected-warning@+1{{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} ((half16U *)destData)[0] = test(argbF); } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} __attribute__((always_inline)) half16 test2( float16 a ) { half16 r; r.lo = convert_half(a.lo); return r; } +// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} void avx_test3( uint16_t *destData, float16 argbF) { ((half16U *)destData)[0] = test2(argbF); diff --git a/clang/test/CodeGen/target-features-error-2.c b/clang/test/CodeGen/target-features-error-2.c index 1599b0135b747..8f2ef35b8a931 100644 --- a/clang/test/CodeGen/target-features-error-2.c +++ b/clang/test/CodeGen/target-features-error-2.c @@ -8,6 +8,7 @@ #include <x86intrin.h> #if NEED_AVX_1 +// expected-warning@+1 {{AVX vector argument of type '__m256i' (vector of 4 'long long' values) without 'avx' enabled changes the ABI}} int baz(__m256i a) { return _mm256_extract_epi32(a, 3); // expected-error {{'__builtin_ia32_vec_ext_v8si' needs target feature avx}} } diff --git a/clang/test/CodeGenCXX/target-avx-abi-diag.cpp b/clang/test/CodeGenCXX/target-avx-abi-diag.cpp new file mode 100644 index 0000000000000..5048cb092e67f --- /dev/null +++ b/clang/test/CodeGenCXX/target-avx-abi-diag.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -emit-llvm -disable-llvm-passes -verify=noavx,noavx512 -o - %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -target-feature +avx -emit-llvm -disable-llvm-passes -verify=noavx512 -o - %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -target-feature +avx512f -emit-llvm -disable-llvm-passes -verify=both -o - %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -Wno-psabi -emit-llvm -disable-llvm-passes -verify=suppressed -o - %s +// REQUIRES: x86-registered-target + +// both-no-diagnostics +// suppressed-no-diagnostics + +typedef float v8f __attribute__((vector_size(32))); +typedef float v16f __attribute__((vector_size(64))); + +// Prototype-only declarations do not warn. +v8f proto256(v8f); +v16f proto512(v16f); + +// noavx-warning@+2 {{AVX vector return of type 'v8f' (vector of 8 'float' values) without 'avx' enabled changes the ABI}} +// noavx-warning@+1 {{AVX vector argument of type 'v8f' (vector of 8 'float' values) without 'avx' enabled changes the ABI}} +v8f def256(v8f x) { + return x; +} + +// noavx512-warning@+2 {{AVX vector return of type 'v16f' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} +// noavx512-warning@+1 {{AVX vector argument of type 'v16f' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} +v16f def512(v16f x) { + return x; +} + +__attribute__((target("avx"))) +v8f def256_avx(v8f x) { + return x; +} + +__attribute__((target("avx512f"))) +v16f def512_avx512(v16f x) { + return x; +} diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt index d5d94d5ed56b5..0592ec1258cbf 100644 --- a/libc/src/mathvec/generic/CMakeLists.txt +++ b/libc/src/mathvec/generic/CMakeLists.txt @@ -7,6 +7,8 @@ add_entrypoint_object( DEPENDS libc.src.__support.macros.properties.cpu_features libc.src.__support.mathvec.expf + COMPILE_OPTIONS + -Wno-psabi FLAGS ROUND_OPT FMA_OPT diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index d0bb38ab84df4..2c78a32b1449b 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -76,6 +76,9 @@ # We're not annotating all the APIs, since that's a lot of annotations compared to how many we actually care about "-Wno-nullability-completeness", + # Adding this for now to get the build to pass but needs more detailed review + "-Wno-psabi", + # Technically not a warning flag, but might as well be: "-flax-vector-conversions=none", ] >From 2f8a49024db0e5bd83e4816bbe6403505950de1f Mon Sep 17 00:00:00 2001 From: Benjamin Luke <[email protected]> Date: Thu, 21 May 2026 11:57:54 -0700 Subject: [PATCH 2/4] darker format --- libcxx/utils/libcxx/test/params.py | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index 2c78a32b1449b..c9e6f767679fa 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -75,7 +75,6 @@ # We're not annotating all the APIs, since that's a lot of annotations compared to how many we actually care about "-Wno-nullability-completeness", - # Adding this for now to get the build to pass but needs more detailed review "-Wno-psabi", >From 16bfb09bc2f62f02ee656e3d918335d04f17c166 Mon Sep 17 00:00:00 2001 From: freaknbigpanda <[email protected]> Date: Wed, 27 May 2026 17:10:57 -0700 Subject: [PATCH 3/4] Restricted warnings to externally visible definitions, for internal definitions ABI mismatch will be diagnosed at the call site. Added test to make sure we don't emit anything for internal definitions. Improved the warning by returning valid source locations for functions that don't have a valid FunctionTypeLoc, previously we were returning warnings with no location. Added test to cover this case for lambda's with deduced return type. --- clang/lib/CodeGen/Targets/X86.cpp | 18 +++++++++++++++--- clang/test/CodeGenCXX/target-avx-abi-diag.cpp | 18 ++++++++++++++++++ libc/src/mathvec/generic/CMakeLists.txt | 2 -- libcxx/include/__algorithm/simd_utils.h | 7 ++++--- libcxx/utils/libcxx/test/params.py | 2 -- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 6ea4df1bc5438..08fd35c7bdc30 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1581,11 +1581,18 @@ void X86_64TargetCodeGenInfo::checkFunctionABI(CodeGenModule &CGM, if (const TypeSourceInfo *TSI = FD->getTypeSourceInfo()) { TypeLoc TL = TSI->getTypeLoc(); - if (auto FTL = TL.IgnoreParens().getAs<FunctionTypeLoc>()) - return FTL.getReturnLoc().getBeginLoc(); + if (auto FTL = TL.IgnoreParens().getAs<FunctionTypeLoc>()) { + SourceLocation Loc = FTL.getReturnLoc().getBeginLoc(); + if (Loc.isValid()) + return Loc; + } } - return FD->getLocation(); + SourceLocation Loc = FD->getLocation(); + if (Loc.isValid()) + return Loc; + + return FD->getBeginLoc(); }; auto Check = [&](QualType Ty, SourceLocation Loc, bool IsReturn) { @@ -1608,6 +1615,11 @@ void X86_64TargetCodeGenInfo::checkFunctionABI(CodeGenModule &CGM, return false; }; + // psABI warnings & errors for function definitions that are only visible + // in this translation unit are handled at call site by checkFunctionCallABI + if (!FD->isExternallyVisible()) + return; + // First check the return type and emit diagnostic if required Check(FD->getReturnType(), GetReturnTypeLoc(FD), true); diff --git a/clang/test/CodeGenCXX/target-avx-abi-diag.cpp b/clang/test/CodeGenCXX/target-avx-abi-diag.cpp index 5048cb092e67f..66312d513058e 100644 --- a/clang/test/CodeGenCXX/target-avx-abi-diag.cpp +++ b/clang/test/CodeGenCXX/target-avx-abi-diag.cpp @@ -26,6 +26,11 @@ v16f def512(v16f x) { return x; } +// Internal definitions do not warn +static v8f internal_def256(v8f x) { + return x; +} + __attribute__((target("avx"))) v8f def256_avx(v8f x) { return x; @@ -35,3 +40,16 @@ __attribute__((target("avx512f"))) v16f def512_avx512(v16f x) { return x; } + +// Check to make sure deduced return lambdas still have valid source location which allows these pragmas to work +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpsabi" +template <class T> +T template_lambda_return() { + return []() { return T{}; }(); +} + +v8f use_template_lambda_return() { + return template_lambda_return<v8f>(); +} +#pragma clang diagnostic pop diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt index 0592ec1258cbf..d5d94d5ed56b5 100644 --- a/libc/src/mathvec/generic/CMakeLists.txt +++ b/libc/src/mathvec/generic/CMakeLists.txt @@ -7,8 +7,6 @@ add_entrypoint_object( DEPENDS libc.src.__support.macros.properties.cpu_features libc.src.__support.mathvec.expf - COMPILE_OPTIONS - -Wno-psabi FLAGS ROUND_OPT FMA_OPT diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h index f73c9ea4b6ea7..9b1a698c86102 100644 --- a/libcxx/include/__algorithm/simd_utils.h +++ b/libcxx/include/__algorithm/simd_utils.h @@ -90,6 +90,9 @@ inline constexpr size_t __native_vector_size = 1; template <class _ArithmeticT, size_t _Np> using __simd_vector __attribute__((__ext_vector_type__(_Np))) _LIBCPP_NODEBUG = _ArithmeticT; +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi") + template <class _VecT> inline constexpr size_t __simd_vector_size_v = []<bool _False = false>() -> size_t { static_assert(_False, "Not a vector!"); @@ -115,8 +118,6 @@ template <class _VecT, class _Iter> } // Load the first _Np elements, zero the rest -_LIBCPP_DIAGNOSTIC_PUSH -_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi") template <class _VecT, size_t _Np, class _Iter> [[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __partial_load(_Iter __iter) noexcept { return [=]<size_t... _LoadIndices, size_t... _ZeroIndices>( @@ -133,7 +134,6 @@ __broadcast(__simd_vector_underlying_type_t<_VecT> __val) { return _VecT{((void)_Indices, __val)...}; }(make_index_sequence<__simd_vector_size_v<_VecT>>()); } -_LIBCPP_DIAGNOSTIC_POP template <class _Tp, size_t _Np> [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept { @@ -183,6 +183,7 @@ template <class _Tp, size_t _Np> [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_not_set(__simd_vector<_Tp, _Np> __vec) noexcept { return std::__find_first_set(~__vec); } +_LIBCPP_DIAGNOSTIC_POP _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py index c9e6f767679fa..d0bb38ab84df4 100644 --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -75,8 +75,6 @@ # We're not annotating all the APIs, since that's a lot of annotations compared to how many we actually care about "-Wno-nullability-completeness", - # Adding this for now to get the build to pass but needs more detailed review - "-Wno-psabi", # Technically not a warning flag, but might as well be: "-flax-vector-conversions=none", >From 4a7148e42c94e84a3cc6268aa89becefd450fee8 Mon Sep 17 00:00:00 2001 From: freaknbigpanda <[email protected]> Date: Wed, 27 May 2026 18:12:38 -0700 Subject: [PATCH 4/4] fix test --- clang/test/CodeGen/target-builtin-error-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGen/target-builtin-error-3.c b/clang/test/CodeGen/target-builtin-error-3.c index 840ca7534905d..75754f40ac44d 100644 --- a/clang/test/CodeGen/target-builtin-error-3.c +++ b/clang/test/CodeGen/target-builtin-error-3.c @@ -17,7 +17,7 @@ typedef __attribute__ ((ext_vector_type(16),__aligned__( 64))) float float16; static inline half8 __attribute__((__overloadable__)) convert_half( float8 a ) { return __extension__ ({ __m256 __a = (a); (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)__a, (0x00)); }); // expected-error {{'__builtin_ia32_vcvtps2ph256' needs target feature f16c}} } -// expected-warning@+1 {{AVX vector argument of type 'float16' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}} +// Internal definitions do not warn. static inline half16 __attribute__((__overloadable__)) convert_half( float16 a ) { half16 r; r.lo = convert_half(a.lo); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
