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@+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@+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@+1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a non-streaming function}} + return __builtin_vectorelements(svuint8_t); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
