Skip to content

Commit 6bf3249

Browse files
[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 #155736
1 parent 9e53ef3 commit 6bf3249

File tree

6 files changed

+83
-22
lines changed

6 files changed

+83
-22
lines changed

clang/include/clang/Sema/SemaARM.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class SemaARM : public SemaBase {
9696
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
9797
SmallVectorImpl<SourceLocation> &Locs,
9898
SmallVectorImpl<SmallString<64>> &NewParams);
99+
bool checkSVETypeSupport(QualType Ty, SourceLocation Loc,
100+
const FunctionDecl *FD,
101+
const llvm::StringMap<bool> &FeatureMap);
99102
};
100103

101104
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);

clang/lib/Sema/Sema.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,16 +2254,10 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
22542254
}
22552255

22562256
// Don't allow SVE types in functions without a SVE target.
2257-
if (Ty->isSVESizelessBuiltinType() && FD && !FD->getType().isNull()) {
2257+
if (Ty->isSVESizelessBuiltinType() && FD) {
22582258
llvm::StringMap<bool> CallerFeatureMap;
22592259
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
2260-
if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
2261-
if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
2262-
Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
2263-
else if (!IsArmStreamingFunction(FD,
2264-
/*IncludeLocallyStreaming=*/true))
2265-
Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
2266-
}
2260+
ARM().checkSVETypeSupport(Ty, Loc, FD, CallerFeatureMap);
22672261
}
22682262

22692263
if (auto *VT = Ty->getAs<VectorType>();

clang/lib/Sema/SemaARM.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,4 +1684,24 @@ bool SemaARM::checkTargetClonesAttr(
16841684
return false;
16851685
}
16861686

1687+
bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
1688+
const FunctionDecl *FD,
1689+
const llvm::StringMap<bool> &FeatureMap) {
1690+
if (!Ty->isSVESizelessBuiltinType())
1691+
return false;
1692+
1693+
if (FeatureMap.lookup("sve"))
1694+
return false;
1695+
1696+
// No SVE environment available.
1697+
if (!FeatureMap.lookup("sme"))
1698+
return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
1699+
1700+
// SVE environment only available to streaming functions.
1701+
if (FD && !FD->getType().isNull() &&
1702+
!IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))
1703+
return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
1704+
1705+
return false;
1706+
}
16871707
} // namespace clang

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9132,20 +9132,10 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
91329132
const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
91339133
llvm::StringMap<bool> CallerFeatureMap;
91349134
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
9135-
9136-
if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
9137-
if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) {
9138-
Diag(NewVD->getLocation(), diag::err_sve_vector_in_non_sve_target) << T;
9139-
NewVD->setInvalidDecl();
9140-
return;
9141-
} else if (!IsArmStreamingFunction(FD,
9142-
/*IncludeLocallyStreaming=*/true)) {
9143-
Diag(NewVD->getLocation(),
9144-
diag::err_sve_vector_in_non_streaming_function)
9145-
<< T;
9146-
NewVD->setInvalidDecl();
9147-
return;
9148-
}
9135+
if (ARM().checkSVETypeSupport(T, NewVD->getLocation(), FD,
9136+
CallerFeatureMap)) {
9137+
NewVD->setInvalidDecl();
9138+
return;
91499139
}
91509140
}
91519141

clang/lib/Sema/SemaExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4189,6 +4189,14 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
41894189
<< ""
41904190
<< "__builtin_vectorelements" << T << ArgRange;
41914191

4192+
if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
4193+
if (T->isSVESizelessBuiltinType()) {
4194+
llvm::StringMap<bool> CallerFeatureMap;
4195+
S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
4196+
return S.ARM().checkSVETypeSupport(T, Loc, FD, CallerFeatureMap);
4197+
}
4198+
}
4199+
41924200
return false;
41934201
}
41944202

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
2+
// REQUIRES: aarch64-registered-target
3+
4+
#include <arm_sve.h>
5+
6+
__attribute__((target("sve")))
7+
long test_builtin_vectorelements_sve(void) {
8+
return __builtin_vectorelements(svuint8_t);
9+
}
10+
11+
__attribute__((target("sve2p1")))
12+
long test_builtin_vectorelements_sve2p1(void) {
13+
return __builtin_vectorelements(svuint8_t);
14+
}
15+
16+
long test_builtin_vectorelements_no_sve(void) {
17+
// expected-error@+1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a target without sve}}
18+
return __builtin_vectorelements(svuint8_t);
19+
}
20+
21+
__attribute__((target("sme")))
22+
long test_builtin_vectorelements_sme_streaming(void) __arm_streaming {
23+
return __builtin_vectorelements(svuint8_t);
24+
}
25+
26+
__attribute__((target("sme2p1")))
27+
long test_builtin_vectorelements_sme2p1_streaming(void) __arm_streaming {
28+
return __builtin_vectorelements(svuint8_t);
29+
}
30+
31+
__attribute__((target("sme")))
32+
long test_builtin_vectorelements_sme(void) {
33+
// expected-error@+1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a non-streaming function}}
34+
return __builtin_vectorelements(svuint8_t);
35+
}
36+
37+
__attribute__((target("sve,sme")))
38+
long test_builtin_vectorelements_sve_sme_streaming_compatible(void) __arm_streaming_compatible {
39+
return __builtin_vectorelements(svuint8_t);
40+
}
41+
42+
__attribute__((target("sme")))
43+
long test_builtin_vectorelements_sme_streaming_compatible(void) __arm_streaming_compatible {
44+
// expected-error@+1 {{SVE vector type 'svuint8_t' (aka '__SVUint8_t') cannot be used in a non-streaming function}}
45+
return __builtin_vectorelements(svuint8_t);
46+
}

0 commit comments

Comments
 (0)