[libc-commits] [clang] [libc] [libcxx] [clang][X86] Emit AVX level mismatch psABI warnings on function definitions (PR #199091)
Benjamin Luke via libc-commits
libc-commits at lists.llvm.org
Thu May 21 11:49:59 PDT 2026
https://github.com/freaknbigpanda created https://github.com/llvm/llvm-project/pull/199091
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.
>From f4f2c695e7c6e0a5b2cbc1ef045908353caf9069 Mon Sep 17 00:00:00 2001
From: Benjamin Luke <benjamin.luke at sony.com>
Date: Wed, 20 May 2026 11:53:38 -0700
Subject: [PATCH] [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 at +2 {{AVX vector return of type 'vec256' (vector of 8 'int' values) without 'avx' enabled changes the ABI}}
+// omp-warning at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +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 at +2 {{AVX vector return of type 'v8f' (vector of 8 'float' values) without 'avx' enabled changes the ABI}}
+// noavx-warning at +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 at +2 {{AVX vector return of type 'v16f' (vector of 16 'float' values) without 'avx512f' enabled changes the ABI}}
+// noavx512-warning at +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",
]
More information about the libc-commits
mailing list