Skip to content

Commit 0accf99

Browse files
[Clang][Sema] Emit diagnostic for __builtin_vectorelements(<SVEType>) when SVE is not available.
As is done for other targets, I've moved the target type checking code into SemaARM and migrated existing uses. Fixes #155736
1 parent 8eb28ca commit 0accf99

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
@@ -1685,4 +1685,24 @@ bool SemaARM::checkTargetClonesAttr(
16851685
return false;
16861686
}
16871687

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

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9125,20 +9125,10 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
91259125
const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
91269126
llvm::StringMap<bool> CallerFeatureMap;
91279127
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
9128-
9129-
if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
9130-
if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap)) {
9131-
Diag(NewVD->getLocation(), diag::err_sve_vector_in_non_sve_target) << T;
9132-
NewVD->setInvalidDecl();
9133-
return;
9134-
} else if (!IsArmStreamingFunction(FD,
9135-
/*IncludeLocallyStreaming=*/true)) {
9136-
Diag(NewVD->getLocation(),
9137-
diag::err_sve_vector_in_non_streaming_function)
9138-
<< T;
9139-
NewVD->setInvalidDecl();
9140-
return;
9141-
}
9128+
if (ARM().checkSVETypeSupport(T, NewVD->getLocation(), FD,
9129+
CallerFeatureMap)) {
9130+
NewVD->setInvalidDecl();
9131+
return;
91429132
}
91439133
}
91449134

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)