mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +00:00
[Clang][AArch64] Emit 'unimplemented' diagnostic for SME (#80295)
When a function F has ZA and ZT0 state, calls another function G that only shares ZT0 state with its caller, F will have to save ZA before the call to G, and restore it afterwards (rather than setting up a lazy-sve). This is not yet implemented in LLVM and does not result in a compile-time error either. So instead of silently generating incorrect code, it's better to emit an error saying this is not yet implemented. (cherry picked from commit 319f4c03ba2909c7240ac157cc46216bf1518c10)
This commit is contained in:
parent
900e7cbfde
commit
1a791e84d9
@ -3711,6 +3711,12 @@ def err_sme_za_call_no_za_state : Error<
|
||||
"call to a shared ZA function requires the caller to have ZA state">;
|
||||
def err_sme_zt0_call_no_zt0_state : Error<
|
||||
"call to a shared ZT0 function requires the caller to have ZT0 state">;
|
||||
def err_sme_unimplemented_za_save_restore : Error<
|
||||
"call to a function that shares state other than 'za' from a "
|
||||
"function that has live 'za' state requires a spill/fill of ZA, which is not yet "
|
||||
"implemented">;
|
||||
def note_sme_use_preserves_za : Note<
|
||||
"add '__arm_preserves(\"za\")' to the callee if it preserves ZA">;
|
||||
def err_sme_definition_using_sm_in_non_sme_target : Error<
|
||||
"function executed in streaming-SVE mode requires 'sme'">;
|
||||
def err_sme_definition_using_za_in_non_sme_target : Error<
|
||||
|
@ -7545,47 +7545,43 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
|
||||
}
|
||||
}
|
||||
|
||||
// If the callee uses AArch64 SME ZA state but the caller doesn't define
|
||||
// any, then this is an error.
|
||||
FunctionType::ArmStateValue ArmZAState =
|
||||
FunctionType::ArmStateValue CalleeArmZAState =
|
||||
FunctionType::getArmZAState(ExtInfo.AArch64SMEAttributes);
|
||||
if (ArmZAState != FunctionType::ARM_None) {
|
||||
FunctionType::ArmStateValue CalleeArmZT0State =
|
||||
FunctionType::getArmZT0State(ExtInfo.AArch64SMEAttributes);
|
||||
if (CalleeArmZAState != FunctionType::ARM_None ||
|
||||
CalleeArmZT0State != FunctionType::ARM_None) {
|
||||
bool CallerHasZAState = false;
|
||||
bool CallerHasZT0State = false;
|
||||
if (const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
|
||||
auto *Attr = CallerFD->getAttr<ArmNewAttr>();
|
||||
if (Attr && Attr->isNewZA())
|
||||
CallerHasZAState = true;
|
||||
else if (const auto *FPT =
|
||||
CallerFD->getType()->getAs<FunctionProtoType>())
|
||||
CallerHasZAState = FunctionType::getArmZAState(
|
||||
FPT->getExtProtoInfo().AArch64SMEAttributes) !=
|
||||
FunctionType::ARM_None;
|
||||
}
|
||||
|
||||
if (!CallerHasZAState)
|
||||
Diag(Loc, diag::err_sme_za_call_no_za_state);
|
||||
}
|
||||
|
||||
// If the callee uses AArch64 SME ZT0 state but the caller doesn't define
|
||||
// any, then this is an error.
|
||||
FunctionType::ArmStateValue ArmZT0State =
|
||||
FunctionType::getArmZT0State(ExtInfo.AArch64SMEAttributes);
|
||||
if (ArmZT0State != FunctionType::ARM_None) {
|
||||
bool CallerHasZT0State = false;
|
||||
if (const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
|
||||
auto *Attr = CallerFD->getAttr<ArmNewAttr>();
|
||||
if (Attr && Attr->isNewZT0())
|
||||
CallerHasZT0State = true;
|
||||
else if (const auto *FPT =
|
||||
CallerFD->getType()->getAs<FunctionProtoType>())
|
||||
CallerHasZT0State =
|
||||
if (const auto *FPT = CallerFD->getType()->getAs<FunctionProtoType>()) {
|
||||
CallerHasZAState |=
|
||||
FunctionType::getArmZAState(
|
||||
FPT->getExtProtoInfo().AArch64SMEAttributes) !=
|
||||
FunctionType::ARM_None;
|
||||
CallerHasZT0State |=
|
||||
FunctionType::getArmZT0State(
|
||||
FPT->getExtProtoInfo().AArch64SMEAttributes) !=
|
||||
FunctionType::ARM_None;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CallerHasZT0State)
|
||||
if (CalleeArmZAState != FunctionType::ARM_None && !CallerHasZAState)
|
||||
Diag(Loc, diag::err_sme_za_call_no_za_state);
|
||||
|
||||
if (CalleeArmZT0State != FunctionType::ARM_None && !CallerHasZT0State)
|
||||
Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
|
||||
|
||||
if (CallerHasZAState && CalleeArmZAState == FunctionType::ARM_None &&
|
||||
CalleeArmZT0State != FunctionType::ARM_None) {
|
||||
Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
|
||||
Diag(Loc, diag::note_sme_use_preserves_za);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -fsyntax-only -verify=expected-cpp -x c++ %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -fsyntax-only -verify=expected-cpp -x c++ %s
|
||||
|
||||
// Valid attributes
|
||||
|
||||
@ -445,3 +445,12 @@ void conflicting_state_attrs_preserves_out_zt0(void) __arm_preserves("zt0") __ar
|
||||
// expected-cpp-error@+2 {{conflicting attributes for state 'zt0'}}
|
||||
// expected-error@+1 {{conflicting attributes for state 'zt0'}}
|
||||
void conflicting_state_attrs_preserves_inout_zt0(void) __arm_preserves("zt0") __arm_inout("zt0");
|
||||
|
||||
// Test that we get a diagnostic for unimplemented case.
|
||||
void unimplemented_spill_fill_za(void (*share_zt0_only)(void) __arm_inout("zt0")) __arm_inout("za", "zt0") {
|
||||
// expected-cpp-error@+4 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}}
|
||||
// expected-cpp-note@+3 {{add '__arm_preserves("za")' to the callee if it preserves ZA}}
|
||||
// expected-error@+2 {{call to a function that shares state other than 'za' from a function that has live 'za' state requires a spill/fill of ZA, which is not yet implemented}}
|
||||
// expected-note@+1 {{add '__arm_preserves("za")' to the callee if it preserves ZA}}
|
||||
share_zt0_only();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user