[clang] 6bf3249 - [Clang][Sema] Emit diagnostic for __builtin_vectorelements(<SVEType>) when SVE is not available. (#168097)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 25 05:14:14 PST 2025
Author: Paul Walker
Date: 2025-11-25T13:14:10Z
New Revision: 6bf3249fe9771c5732d993304ecee11f55927f9f
URL: https://github.com/llvm/llvm-project/commit/6bf3249fe9771c5732d993304ecee11f55927f9f
DIFF: https://github.com/llvm/llvm-project/commit/6bf3249fe9771c5732d993304ecee11f55927f9f.diff
LOG: [Clang][Sema] Emit diagnostic for __builtin_vectorelements(<SVEType>) when SVE is not available. (#168097)
As is done for other targets, I've moved the target type checking code
into SemaARM and migrated existing uses.
Fixes https://github.com/llvm/llvm-project/issues/155736
Added:
clang/test/Sema/AArch64/builtin_vectorelements.c
Modified:
clang/include/clang/Sema/SemaARM.h
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaARM.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaExpr.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index 104992e8826c3..1e8941a381dc5 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -96,6 +96,9 @@ class SemaARM : public SemaBase {
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams);
+ bool checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+ const FunctionDecl *FD,
+ const llvm::StringMap<bool> &FeatureMap);
};
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 46addea232b03..1541b2cc95d8c 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2254,16 +2254,10 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
}
// Don't allow SVE types in functions without a SVE target.
- if (Ty->isSVESizelessBuiltinType() && FD && !FD->getType().isNull()) {
+ if (Ty->isSVESizelessBuiltinType() && FD) {
llvm::StringMap<bool> CallerFeatureMap;
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
- if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
- if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
- Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
- else if (!IsArmStreamingFunction(FD,
- /*IncludeLocallyStreaming=*/true))
- Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
- }
+ ARM().checkSVETypeSupport(Ty, Loc, FD, CallerFeatureMap);
}
if (auto *VT = Ty->getAs<VectorType>();
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 39f37cc679efa..a5164a94b57fa 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1684,4 +1684,24 @@ bool SemaARM::checkTargetClonesAttr(
return false;
}
+bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
+ const FunctionDecl *FD,
+ const llvm::StringMap<bool> &FeatureMap) {
+ if (!Ty->isSVESizelessBuiltinType())
+ return false;
+
+ if (FeatureMap.lookup("sve"))
+ return false;
+
+ // No SVE environment available.
+ if (!FeatureMap.lookup("sme"))
+ return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
+
+ // SVE environment only available to streaming functions.
+ if (FD && !FD->getType().isNull() &&
+ !IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))
+ return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
+
+ return false;
+}
} // namespace clang
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 651437a6f4c30..7ad1f17263c4d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9132,20 +9132,10 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
llvm::StringMap<bool> CallerFeatureMap;
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
-
- if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
- if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) {
- Diag(NewVD->getLocation(), diag::err_sve_vector_in_non_sve_target) << T;
- NewVD->setInvalidDecl();
- return;
- } else if (!IsArmStreamingFunction(FD,
- /*IncludeLocallyStreaming=*/true)) {
- Diag(NewVD->getLocation(),
- diag::err_sve_vector_in_non_streaming_function)
- << T;
- NewVD->setInvalidDecl();
- return;
- }
+ if (ARM().checkSVETypeSupport(T, NewVD->getLocation(), FD,
+ CallerFeatureMap)) {
+ NewVD->setInvalidDecl();
+ return;
}
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d3c2cc559ea20..c808dec12a6cf 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4189,6 +4189,14 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
<< ""
<< "__builtin_vectorelements" << T << ArgRange;
+ if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
+ if (T->isSVESizelessBuiltinType()) {
+ llvm::StringMap<bool> CallerFeatureMap;
+ S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
+ return S.ARM().checkSVETypeSupport(T, Loc, FD, CallerFeatureMap);
+ }
+ }
+
return false;
}
diff --git a/clang/test/Sema/AArch64/builtin_vectorelements.c b/clang/test/Sema/AArch64/builtin_vectorelements.c
new file mode 100644
index 0000000000000..3391da3fc81e1
--- /dev/null
+++ b/clang/test/Sema/AArch64/builtin_vectorelements.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+__attribute__((target("sve")))
+long test_builtin_vectorelements_sve(void) {
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sve2p1")))
+long test_builtin_vectorelements_sve2p1(void) {
+ return __builtin_vectorelements(svuint8_t);
+}
+
+long test_builtin_vectorelements_no_sve(void) {
+ // expected-error at +1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a target without sve}}
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sme")))
+long test_builtin_vectorelements_sme_streaming(void) __arm_streaming {
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sme2p1")))
+long test_builtin_vectorelements_sme2p1_streaming(void) __arm_streaming {
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sme")))
+long test_builtin_vectorelements_sme(void) {
+ // expected-error at +1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a non-streaming function}}
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sve,sme")))
+long test_builtin_vectorelements_sve_sme_streaming_compatible(void) __arm_streaming_compatible {
+ return __builtin_vectorelements(svuint8_t);
+}
+
+__attribute__((target("sme")))
+long test_builtin_vectorelements_sme_streaming_compatible(void) __arm_streaming_compatible {
+ // expected-error at +1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a non-streaming function}}
+ return __builtin_vectorelements(svuint8_t);
+}
More information about the cfe-commits
mailing list