Skip to content

Commit bfa1348

Browse files
committed
Add TableGen checks
1 parent af4cd0b commit bfa1348

File tree

2 files changed

+81
-15
lines changed

2 files changed

+81
-15
lines changed

clang/lib/Sema/SemaARM.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -569,26 +569,20 @@ static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
569569
if (BuiltinType == SemaARM::VerifyRuntimeMode) {
570570
llvm::StringMap<bool> CallerFeatureMapWithoutSVE;
571571
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSVE, FD);
572-
CallerFeatureMapWithoutSVE["sve"] = false;
573-
CallerFeatureMapWithoutSVE["sve2"] = false;
574-
CallerFeatureMapWithoutSVE["sve2p1"] = false;
575-
// FIXME: This list must be updated with future extensions, because when
576-
// an intrinsic is enabled by (sve2p1|sme2p1), disabling just "sve" is
577-
// not sufficient, as the feature dependences are not resolved.
578-
// At the moment, it should be sufficient to test the 'base' architectural
579-
// support for SVE and SME, which must always be provided in the
580-
// target guard. e.g. TargetGuard = "sve-b16b16" without "sme" or "sve"
581-
// is not sufficient.
572+
for (StringRef Feat : {"sve", "sve2", "sve2p1", "sve2-aes", "sve2-sha3",
573+
"sve2-sm4", "sve2-bitperm"})
574+
CallerFeatureMapWithoutSVE[Feat] = false;
582575

583576
// Avoid emitting diagnostics for a function that can never compile.
584577
if (FnType == SemaARM::ArmStreaming && !CallerFeatureMapWithoutSVE["sme"])
585578
return false;
586579

587580
llvm::StringMap<bool> CallerFeatureMapWithoutSME;
588581
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSME, FD);
589-
CallerFeatureMapWithoutSME["sme"] = false;
590-
CallerFeatureMapWithoutSME["sme2"] = false;
591-
CallerFeatureMapWithoutSME["sme2p1"] = false;
582+
for (StringRef Feat :
583+
{"sme", "sme2", "sme2p1", "sme-f64f64", "sme-i16i64", "sme-b16b16",
584+
"sme-f16f16", "sme-f8f32", "sme-f8f16"})
585+
CallerFeatureMapWithoutSME[Feat] = false;
592586

593587
// We know the builtin requires either some combination of SVE flags, or
594588
// some combination of SME flags, but we need to figure out which part

clang/utils/TableGen/SveEmitter.cpp

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,6 +1770,58 @@ void SVEEmitter::createBuiltinZAState(raw_ostream &OS) {
17701770
OS << "#endif\n\n";
17711771
}
17721772

1773+
static StringRef parseGuardParenExpr(StringRef &S) {
1774+
unsigned N = 0;
1775+
assert(S[0] == '(' && "Expected lparen");
1776+
for (unsigned I = 0; I < S.size(); ++I) {
1777+
if (S[I] == '(')
1778+
++N;
1779+
else if (S[I] == ')')
1780+
--N;
1781+
if (N == 0) {
1782+
StringRef Expr = S.substr(1, I - 1);
1783+
S = S.drop_front(I + 1);
1784+
return Expr;
1785+
}
1786+
}
1787+
llvm_unreachable("Unmatched parenthesi");
1788+
}
1789+
1790+
static StringRef parseGuardFeature(StringRef &S) {
1791+
assert(std::isalpha(S[0]) && "expected feature name");
1792+
unsigned I;
1793+
for (I = 0; I < S.size(); ++I) {
1794+
if (S[I] == ',' || S[I] == '|' || S[I] == ')')
1795+
break;
1796+
}
1797+
StringRef Expr = S.take_front(I);
1798+
S = S.drop_front(I);
1799+
return Expr;
1800+
}
1801+
1802+
static StringRef parseGuardExpr(StringRef &S) {
1803+
if (S[0] == '(')
1804+
return parseGuardParenExpr(S);
1805+
if (std::isalpha(S[0]))
1806+
return parseGuardFeature(S);
1807+
llvm_unreachable("Unexpected token in expression");
1808+
}
1809+
1810+
// Parse the TargetGuard and verify that it satisfies at least one of the
1811+
// features from the Required list.
1812+
static bool verifyGuard(StringRef S, ArrayRef<StringRef> Required) {
1813+
if (S.empty())
1814+
return false;
1815+
StringRef LHS = parseGuardExpr(S);
1816+
if (S.empty())
1817+
return llvm::any_of(Required, [LHS](StringRef R) { return R == LHS; });
1818+
if (S[0] == '|')
1819+
return verifyGuard(LHS, Required) && verifyGuard(S.drop_front(1), Required);
1820+
if (S[0] == ',')
1821+
return verifyGuard(LHS, Required) || verifyGuard(S.drop_front(1), Required);
1822+
llvm_unreachable("Unexpected token in expression");
1823+
}
1824+
17731825
void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) {
17741826
std::vector<const Record *> RV = Records.getAllDerivedDefinitions("Inst");
17751827
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
@@ -1802,9 +1854,29 @@ void SVEEmitter::createStreamingAttrs(raw_ostream &OS, ACLEKind Kind) {
18021854

18031855
if (Def->isFlagSet(IsStreamingFlag))
18041856
StreamingMap["ArmStreaming"].insert(Def->getMangledName());
1805-
else if (Def->isFlagSet(VerifyRuntimeMode))
1857+
else if (Def->isFlagSet(VerifyRuntimeMode)) {
1858+
// Verify that the target guards contain at least one feature that
1859+
// actually enables SVE or SME (explicitly, or implicitly). This is needed
1860+
// for the code in SemaARM.cpp (checkArmStreamingBuiltin) that checks
1861+
// whether the required runtime mode for an intrinsic matches with the
1862+
// given set of target features and function attributes.
1863+
//
1864+
// The feature lists below must match the disabled features in
1865+
// 'checkArmStreamingBuiltin'!
1866+
if (!Def->getSVEGuard().empty() &&
1867+
!verifyGuard(Def->getSVEGuard(),
1868+
{"sve", "sve2", "sve2p1", "sve2-aes", "sve2-sha3",
1869+
"sve2-sm4", "sve2-bitperm"}))
1870+
llvm_unreachable(
1871+
"SVE guard must include at least one base SVE version");
1872+
if (!Def->getSMEGuard().empty() &&
1873+
!verifyGuard(Def->getSMEGuard(),
1874+
{"sme", "sme2", "sme2p1", "sme-f64f64", "sme-i16i64",
1875+
"sme-b16b16", "sme-f16f16", "sme-f8f32", "sme-f8f16"}))
1876+
llvm_unreachable(
1877+
"SME guard must include at least one base SME version");
18061878
StreamingMap["VerifyRuntimeMode"].insert(Def->getMangledName());
1807-
else if (Def->isFlagSet(IsStreamingCompatibleFlag))
1879+
} else if (Def->isFlagSet(IsStreamingCompatibleFlag))
18081880
StreamingMap["ArmStreamingCompatible"].insert(Def->getMangledName());
18091881
else
18101882
StreamingMap["ArmNonStreaming"].insert(Def->getMangledName());

0 commit comments

Comments
 (0)