Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions clang/lib/Sema/SemaARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,8 @@ static ArmSMEState getSMEState(unsigned BuiltinID) {

bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) {
if (const FunctionDecl *FD =
SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) {
std::optional<ArmStreamingType> BuiltinType;

switch (BuiltinID) {
Expand Down Expand Up @@ -690,7 +691,8 @@ bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID,

bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) {
if (const FunctionDecl *FD =
SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) {
std::optional<ArmStreamingType> BuiltinType;

switch (BuiltinID) {
Expand Down Expand Up @@ -719,7 +721,8 @@ bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID,
bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID,
CallExpr *TheCall) {
if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) {
if (const FunctionDecl *FD =
SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) {

switch (BuiltinID) {
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,45 @@ void missing_zt0(void) __arm_streaming {

__arm_new("zt0")
void new_zt0(void) __arm_streaming { svzero_zt(0); }

/// C++ lambda tests:

void use_streaming_builtin_in_lambda(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_out("za")
{
[&]{
/// The lambda is its own function and does not inherit the SME attributes (so this should error).
// expected-error@+1 {{builtin can only be called from a streaming function}}
svld1_hor_za64(0, slice_base, pg, ptr);
}();
}

void use_streaming_builtin(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_out("za")
{
/// Without the lambda the same builtin is okay (as the SME attributes apply).
svld1_hor_za64(0, slice_base, pg, ptr);
}

int16x8_t use_neon_builtin_sm(int16x8_t splat) __arm_streaming_compatible {
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33);
}

int16x8_t use_neon_builtin_sm_in_lambda(int16x8_t splat) __arm_streaming_compatible {
return [&]{
/// This should not error (as we switch out of streaming mode to execute the lambda).
/// Note: The result int16x8_t is spilled and reloaded as a q-register.
return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33);
}();
}

float use_incomp_sve_builtin_sm() __arm_streaming {
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
return svadda(svptrue_b32(), 0, svdup_f32(1));
}

float incomp_sve_sm_fadda_sm_in_lambda(void) __arm_streaming {
return [&]{
/// This should work like the Neon builtin.
return svadda(svptrue_b32(), 0, svdup_f32(1));
}();
}