[clang] [Clang][AArch64] Warn when calling streaming/non-streaming about vect… (PR #79842)
Dinar Temirbulatov via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 9 07:31:24 PDT 2024
https://github.com/dtemirbulatov updated https://github.com/llvm/llvm-project/pull/79842
>From f27d37a3bbdbdd47770301e8188f5ad7e84b5cc1 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Mon, 29 Jan 2024 14:43:13 +0000
Subject: [PATCH 01/14] [Clang][AArch64] Warn when calling
streaming/non-streaming about vector size might be different.
The compiler doesn't know in advance if the streaming and non-streaming
vector-lengths are different, so it should be safe to give a warning diagnostic
to warn the user about possible undefined behaviour. If the user knows
the vector lengths are equal, they can disable the warning separately.
---
.../clang/Basic/DiagnosticSemaKinds.td | 24 +++++++
clang/lib/Sema/SemaChecking.cpp | 44 +++++++++++-
clang/test/Sema/aarch64-sme-func-attrs.c | 68 ++++++++++++++++++-
3 files changed, 133 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4fbbc42273ba93..65fc3599f5170f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3755,6 +3755,30 @@ def err_sme_definition_using_za_in_non_sme_target : Error<
"function using ZA state requires 'sme'">;
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
+def warn_sme_streaming_caller_pass_args_to_non_streaming : Warning<
+ "streaming caller passes a VL-dependent argument to non-streaming callee, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
+def warn_sme_non_streaming_callee_returns_to_streaming : Warning<
+ "non-streaming callee returns a VL-dependent value to streaming caller, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
+def warn_sme_non_streaming_caller_pass_args_to_streaming : Warning<
+ "non-streaming caller passes a VL-dependent argument to streaming callee, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
+def warn_sme_non_streaming_caller_returns_to_streaming : Warning<
+ "non-streaming callee returns a VL-dependent value to streaming caller, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
+def warn_sme_locally_streaming_has_vl_args : Warning<
+ "non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
+def warn_sme_locally_streaming_returns_vl : Warning<
+ "non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, "
+ "the streaming and non-streaming vector lengths may be different">,
+ InGroup<IgnoredAttributes>;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index b84a779b7189c0..8d601197386b9a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7938,6 +7938,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// For variadic functions, we may have more args than parameters.
// For some K&R functions, we may have less args than parameters.
const auto N = std::min<unsigned>(Proto->getNumParams(), Args.size());
+ bool AnyScalableArgs = false;
for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
// Args[ArgIdx] can be null in malformed code.
if (const Expr *Arg = Args[ArgIdx]) {
@@ -7951,6 +7952,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
checkAIXMemberAlignment((Arg->getExprLoc()), Arg);
QualType ParamTy = Proto->getParamType(ArgIdx);
+ if (ParamTy->isSizelessVectorType())
+ AnyScalableArgs = true;
QualType ArgTy = Arg->getType();
CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
ArgTy, ParamTy);
@@ -7971,6 +7974,45 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
}
}
+ const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
+ if (FD && CallerFD && Context.getTargetInfo().hasFeature("sme") &&
+ !FD->getBuiltinID()) {
+ // If the callee has an AArch64 SME __arm_locally_streaming attribute
+ // warn if this function returns VL-based value or pass any such argument,
+ // the streaming and non-streaming vector lengths may be different.
+ ArmStreamingType CalleeFnType = getArmStreamingFnType(FD);
+ ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
+ if (FD->hasAttr<ArmLocallyStreamingAttr>() &&
+ CallerFnType != ArmStreaming) {
+ if (AnyScalableArgs)
+ Diag(Loc, diag::warn_sme_locally_streaming_has_vl_args);
+ if (FD->getReturnType()->isSizelessVectorType())
+ Diag(Loc, diag::warn_sme_locally_streaming_returns_vl);
+ }
+ // If the caller is a non-streaming function and the callee has a
+ // streaming attribute. If it passed any VL-based arguments or return
+ // VL-based value, then warn that the streaming and non-streaming vector
+ // lengths may be different.
+ if (CallerFnType != ArmStreaming) {
+ if (CalleeFnType == ArmStreaming) {
+ if (AnyScalableArgs)
+ Diag(Loc,
+ diag::warn_sme_non_streaming_caller_pass_args_to_streaming);
+ if (FD->getReturnType()->isSizelessVectorType())
+ Diag(Loc, diag::warn_sme_non_streaming_caller_returns_to_streaming);
+ }
+ } else if (!FD->hasAttr<ArmLocallyStreamingAttr>()) {
+ // If the callee is a non-streaming function and the caller has
+ // streaming attribute. If it passed any VL-based arguments or return
+ // VL-based value, then warn that the streaming and non-streaming vector
+ // lengths may be different.
+ if (AnyScalableArgs)
+ Diag(Loc, diag::warn_sme_streaming_caller_pass_args_to_non_streaming);
+ if (FD->getReturnType()->isSizelessVectorType())
+ Diag(Loc, diag::warn_sme_non_streaming_callee_returns_to_streaming);
+ }
+ }
+
FunctionType::ArmStateValue CalleeArmZAState =
FunctionType::getArmZAState(ExtInfo.AArch64SMEAttributes);
FunctionType::ArmStateValue CalleeArmZT0State =
@@ -7979,7 +8021,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
CalleeArmZT0State != FunctionType::ARM_None) {
bool CallerHasZAState = false;
bool CallerHasZT0State = false;
- if (const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
+ if (CallerFD) {
auto *Attr = CallerFD->getAttr<ArmNewAttr>();
if (Attr && Attr->isNewZA())
CallerHasZAState = true;
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index bfc8768c3f36e1..018c2c898da164 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -1,5 +1,6 @@
-// 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
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -fsyntax-only -verify=expected-cpp -x c++ %s
+#include <arm_sme.h>
// Valid attributes
@@ -48,6 +49,9 @@ typedef void (*fptrty6) (void);
fptrty6 cast_nza_func_to_normal() { return sme_arm_new_za; }
fptrty6 cast_ls_func_to_normal() { return sme_arm_locally_streaming; }
+void sme_arm_streaming_with_vl_args(void) __arm_streaming;
+
+
// Invalid attributes
// expected-cpp-error at +4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
@@ -496,3 +500,63 @@ void fmv_caller() {
just_fine();
incompatible_locally_streaming();
}
+
+void sme_streaming_with_vl_arg(svint32x4_t a) __arm_streaming { }
+
+svint32x4_t sme_streaming_returns_vl(void) __arm_streaming { svint32x4_t r; return r; }
+
+void sme_none_streaming_with_vl_arg(svint32x4_t a) { }
+
+svint32x4_t sme_none_streaming_returns_vl(void) { svint32x4_t r; return r; }
+
+__arm_locally_streaming void sme_locally_streaming_with_vl_arg(svint32x4_t a) { }
+
+__arm_locally_streaming svint32x4_t sme_locally_streaming_returns_vl(void) { svint32x4_t r; return r; }
+
+void sme_none_streaming_calling_streaming_with_vl_args() {
+ svint32x4_t a;
+ // expected-warning at +2 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
+ sme_streaming_with_vl_arg(a);
+}
+
+void sme_none_streaming_calling_streaming_with_return_vl() {
+ // expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
+ svint32x4_t r = sme_streaming_returns_vl();
+}
+
+void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
+ svint32x4_t a;
+ // expected-warning at +2 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
+ sme_none_streaming_with_vl_arg(a);
+}
+
+void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
+ // expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
+ svint32x4_t r = sme_streaming_returns_vl();
+}
+
+void sme_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
+ svint32x4_t a;
+ // expected-1warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-1cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ sme_locally_streaming_with_vl_arg(a);
+}
+
+void sme_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
+ // expected-1warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-1cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ svint32x4_t r = sme_locally_streaming_returns_vl();
+}
+
+void sme_none_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
+ svint32x4_t a;
+ sme_locally_streaming_with_vl_arg(a);
+}
+
+void sme_none_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
+ svint32x4_t r = sme_locally_streaming_returns_vl();
+}
>From e068d2f5c53e24fb8c552b38bbe1ad9f4763cf1c Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Tue, 30 Jan 2024 08:59:36 +0000
Subject: [PATCH 02/14] Corrected diagnostics, allowed to emit warning even
when we call streaming local function from streaming function.
---
clang/lib/Sema/SemaChecking.cpp | 3 +--
clang/test/Sema/aarch64-sme-func-attrs.c | 12 ++++++++----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8d601197386b9a..0af268110678ab 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7982,8 +7982,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// the streaming and non-streaming vector lengths may be different.
ArmStreamingType CalleeFnType = getArmStreamingFnType(FD);
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- if (FD->hasAttr<ArmLocallyStreamingAttr>() &&
- CallerFnType != ArmStreaming) {
+ if (FD->hasAttr<ArmLocallyStreamingAttr>()) {
if (AnyScalableArgs)
Diag(Loc, diag::warn_sme_locally_streaming_has_vl_args);
if (FD->getReturnType()->isSizelessVectorType())
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index 018c2c898da164..5ef5ed8c83bec2 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -541,22 +541,26 @@ void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
void sme_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
svint32x4_t a;
- // expected-1warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-1cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
sme_locally_streaming_with_vl_arg(a);
}
void sme_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
- // expected-1warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-1cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
svint32x4_t r = sme_locally_streaming_returns_vl();
}
void sme_none_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
svint32x4_t a;
+ // expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
sme_locally_streaming_with_vl_arg(a);
}
void sme_none_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
+ // expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
svint32x4_t r = sme_locally_streaming_returns_vl();
}
>From 8b6352de6eef8032969c97e3ed3ae32dc862c5cb Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Thu, 8 Feb 2024 07:44:47 +0000
Subject: [PATCH 03/14] Resolved comments.
---
clang/lib/Sema/SemaChecking.cpp | 8 +--
clang/lib/Sema/SemaDecl.cpp | 16 ++++++
.../Sema/aarch64-incompat-sm-builtin-calls.c | 8 +++
clang/test/Sema/aarch64-sme-func-attrs.c | 56 +++++++------------
4 files changed, 46 insertions(+), 42 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0af268110678ab..a317e19f0cb746 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7982,12 +7982,6 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// the streaming and non-streaming vector lengths may be different.
ArmStreamingType CalleeFnType = getArmStreamingFnType(FD);
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- if (FD->hasAttr<ArmLocallyStreamingAttr>()) {
- if (AnyScalableArgs)
- Diag(Loc, diag::warn_sme_locally_streaming_has_vl_args);
- if (FD->getReturnType()->isSizelessVectorType())
- Diag(Loc, diag::warn_sme_locally_streaming_returns_vl);
- }
// If the caller is a non-streaming function and the callee has a
// streaming attribute. If it passed any VL-based arguments or return
// VL-based value, then warn that the streaming and non-streaming vector
@@ -8000,7 +7994,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
if (FD->getReturnType()->isSizelessVectorType())
Diag(Loc, diag::warn_sme_non_streaming_caller_returns_to_streaming);
}
- } else if (!FD->hasAttr<ArmLocallyStreamingAttr>()) {
+ } else if (CalleeFnType != ArmStreaming) {
// If the callee is a non-streaming function and the caller has
// streaming attribute. If it passed any VL-based arguments or return
// VL-based value, then warn that the streaming and non-streaming vector
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c790dab72dd721..fde581e8f49141 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12401,6 +12401,22 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
bool UsesZA = Attr && Attr->isNewZA();
bool UsesZT0 = Attr && Attr->isNewZT0();
+
+ if (UsesSM) {
+ if (NewFD->getReturnType()->isSizelessVectorType())
+ Diag(NewFD->getLocation(), diag::warn_sme_locally_streaming_returns_vl);
+ auto *FPT = NewFD->getType()->castAs<FunctionProtoType>();
+ bool AnyScalableArgs = false;
+ for (QualType T : FPT->param_types()) {
+ if (T->isSizelessVectorType()) {
+ AnyScalableArgs = true;
+ break;
+ }
+ }
+ if (AnyScalableArgs)
+ Diag(NewFD->getLocation(),
+ diag::warn_sme_locally_streaming_has_vl_args);
+ }
if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
UsesSM |=
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 55c97c73e8b695..83f61523927bc3 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,6 +33,8 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
+// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -48,6 +50,8 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
+// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -68,6 +72,8 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
+// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -83,6 +89,8 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
+// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index 5ef5ed8c83bec2..d41efdc2fd6ce4 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -1,6 +1,5 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -fsyntax-only -verify=expected-cpp -x c++ %s
-#include <arm_sme.h>
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify=expected-cpp -x c++ %s
// Valid attributes
@@ -501,20 +500,24 @@ void fmv_caller() {
incompatible_locally_streaming();
}
-void sme_streaming_with_vl_arg(svint32x4_t a) __arm_streaming { }
+void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { }
-svint32x4_t sme_streaming_returns_vl(void) __arm_streaming { svint32x4_t r; return r; }
+__SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; }
-void sme_none_streaming_with_vl_arg(svint32x4_t a) { }
+void sme_none_streaming_with_vl_arg(__SVInt8_t a) { }
-svint32x4_t sme_none_streaming_returns_vl(void) { svint32x4_t r; return r; }
+__SVInt8_t sme_none_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-__arm_locally_streaming void sme_locally_streaming_with_vl_arg(svint32x4_t a) { }
+// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-__arm_locally_streaming svint32x4_t sme_locally_streaming_returns_vl(void) { svint32x4_t r; return r; }
+// expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_none_streaming_calling_streaming_with_vl_args() {
- svint32x4_t a;
+ __SVInt8_t a;
// expected-warning at +2 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
// expected-cpp-warning at +1 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
sme_streaming_with_vl_arg(a);
@@ -523,11 +526,11 @@ void sme_none_streaming_calling_streaming_with_vl_args() {
void sme_none_streaming_calling_streaming_with_return_vl() {
// expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
// expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
- svint32x4_t r = sme_streaming_returns_vl();
+ __SVInt8_t r = sme_streaming_returns_vl();
}
void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
- svint32x4_t a;
+ __SVInt8_t a;
// expected-warning at +2 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
// expected-cpp-warning at +1 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
sme_none_streaming_with_vl_arg(a);
@@ -536,31 +539,14 @@ void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
// expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
// expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
- svint32x4_t r = sme_streaming_returns_vl();
-}
-
-void sme_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
- svint32x4_t a;
- // expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- sme_locally_streaming_with_vl_arg(a);
+ __SVInt8_t r = sme_none_streaming_returns_vl();
}
-void sme_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
- // expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- svint32x4_t r = sme_locally_streaming_returns_vl();
-}
-
-void sme_none_streaming_calling_locally_streaming_with_vl_args(void) __arm_streaming {
- svint32x4_t a;
- // expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- sme_locally_streaming_with_vl_arg(a);
+void sme_streaming_calling_streaming_with_vl_args(void) __arm_streaming {
+ __SVInt8_t a;
+ sme_streaming_with_vl_arg(a);
}
-void sme_none_streaming_calling_locally_streaming_with_return_vl(void) __arm_streaming {
- // expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- svint32x4_t r = sme_locally_streaming_returns_vl();
+void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming {
+ __SVInt8_t r = sme_streaming_returns_vl();
}
>From 6f6ff8a0d630d8568cf971b251c8ec9bccaf54a6 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Thu, 8 Feb 2024 11:37:26 +0000
Subject: [PATCH 04/14] Add new waring group AArch64SMEAttributes.
---
clang/include/clang/Basic/DiagnosticGroups.td | 3 +++
clang/include/clang/Basic/DiagnosticSemaKinds.td | 12 ++++++------
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 5251774ff4efd6..6b6353bcd7599b 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1412,6 +1412,9 @@ def MultiGPU: DiagGroup<"multi-gpu">;
// libc and the CRT to be skipped.
def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;
+// A warning group AArch64 related to SME function attribues.
+def AArch64SMEAttributes : DiagGroup<"aarch64-sme-attributes">;
+
// A warning group for things that will change semantics in the future.
def FutureCompat : DiagGroup<"future-compat">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 65fc3599f5170f..4aea8e57a73031 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3758,27 +3758,27 @@ def err_sme_definition_using_zt0_in_non_sme2_target : Error<
def warn_sme_streaming_caller_pass_args_to_non_streaming : Warning<
"streaming caller passes a VL-dependent argument to non-streaming callee, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def warn_sme_non_streaming_callee_returns_to_streaming : Warning<
"non-streaming callee returns a VL-dependent value to streaming caller, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def warn_sme_non_streaming_caller_pass_args_to_streaming : Warning<
"non-streaming caller passes a VL-dependent argument to streaming callee, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def warn_sme_non_streaming_caller_returns_to_streaming : Warning<
"non-streaming callee returns a VL-dependent value to streaming caller, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def warn_sme_locally_streaming_has_vl_args : Warning<
"non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def warn_sme_locally_streaming_returns_vl : Warning<
"non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, "
"the streaming and non-streaming vector lengths may be different">,
- InGroup<IgnoredAttributes>;
+ InGroup<AArch64SMEAttributes>;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
>From 4b09435c235e0dbe37851cedb422e80ce9b6b42a Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Mon, 12 Feb 2024 18:45:38 +0000
Subject: [PATCH 05/14] Resolved comments.
---
.../clang/Basic/DiagnosticSemaKinds.td | 28 ++-----
clang/lib/Sema/SemaChecking.cpp | 27 +++---
clang/lib/Sema/SemaDecl.cpp | 5 +-
.../Sema/aarch64-incompat-sm-builtin-calls.c | 16 ++--
clang/test/Sema/aarch64-sme-func-attrs.c | 83 ++++++++++++++-----
5 files changed, 95 insertions(+), 64 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4aea8e57a73031..dae703d50cc705 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3755,29 +3755,13 @@ def err_sme_definition_using_za_in_non_sme_target : Error<
"function using ZA state requires 'sme'">;
def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
-def warn_sme_streaming_caller_pass_args_to_non_streaming : Warning<
- "streaming caller passes a VL-dependent argument to non-streaming callee, "
- "the streaming and non-streaming vector lengths may be different">,
+def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
+ "passing a VL-dependent argument to/from a function that has a different"
+ " streaming-mode, is undefined behaviour">,
InGroup<AArch64SMEAttributes>;
-def warn_sme_non_streaming_callee_returns_to_streaming : Warning<
- "non-streaming callee returns a VL-dependent value to streaming caller, "
- "the streaming and non-streaming vector lengths may be different">,
- InGroup<AArch64SMEAttributes>;
-def warn_sme_non_streaming_caller_pass_args_to_streaming : Warning<
- "non-streaming caller passes a VL-dependent argument to streaming callee, "
- "the streaming and non-streaming vector lengths may be different">,
- InGroup<AArch64SMEAttributes>;
-def warn_sme_non_streaming_caller_returns_to_streaming : Warning<
- "non-streaming callee returns a VL-dependent value to streaming caller, "
- "the streaming and non-streaming vector lengths may be different">,
- InGroup<AArch64SMEAttributes>;
-def warn_sme_locally_streaming_has_vl_args : Warning<
- "non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, "
- "the streaming and non-streaming vector lengths may be different">,
- InGroup<AArch64SMEAttributes>;
-def warn_sme_locally_streaming_returns_vl : Warning<
- "non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, "
- "the streaming and non-streaming vector lengths may be different">,
+def warn_sme_locally_streaming_has_vl_args_returns : Warning<
+ "passing/returning a VL-dependent argument from a function"
+ " arm_locally_streaming attribute, is undefined behaviour">,
InGroup<AArch64SMEAttributes>;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a317e19f0cb746..94d87571b236e2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7975,34 +7975,37 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
}
const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- if (FD && CallerFD && Context.getTargetInfo().hasFeature("sme") &&
- !FD->getBuiltinID()) {
+ bool IsCalleeStreaming = ((ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMEnabledMask) ||
+ (ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMCompatibleMask));
+ bool IsBuiltin = (FD && FD->getBuiltinID());
+
+ if (CallerFD && Context.getTargetInfo().hasFeature("sme") && !IsBuiltin) {
// If the callee has an AArch64 SME __arm_locally_streaming attribute
// warn if this function returns VL-based value or pass any such argument,
// the streaming and non-streaming vector lengths may be different.
- ArmStreamingType CalleeFnType = getArmStreamingFnType(FD);
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
// If the caller is a non-streaming function and the callee has a
// streaming attribute. If it passed any VL-based arguments or return
// VL-based value, then warn that the streaming and non-streaming vector
// lengths may be different.
if (CallerFnType != ArmStreaming) {
- if (CalleeFnType == ArmStreaming) {
+ if (IsCalleeStreaming) {
if (AnyScalableArgs)
- Diag(Loc,
- diag::warn_sme_non_streaming_caller_pass_args_to_streaming);
- if (FD->getReturnType()->isSizelessVectorType())
- Diag(Loc, diag::warn_sme_non_streaming_caller_returns_to_streaming);
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+ if (Proto->getReturnType()->isSizelessVectorType())
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
- } else if (CalleeFnType != ArmStreaming) {
+ } else if (!IsCalleeStreaming) {
// If the callee is a non-streaming function and the caller has
// streaming attribute. If it passed any VL-based arguments or return
// VL-based value, then warn that the streaming and non-streaming vector
// lengths may be different.
if (AnyScalableArgs)
- Diag(Loc, diag::warn_sme_streaming_caller_pass_args_to_non_streaming);
- if (FD->getReturnType()->isSizelessVectorType())
- Diag(Loc, diag::warn_sme_non_streaming_callee_returns_to_streaming);
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+ if (Proto->getReturnType()->isSizelessVectorType())
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index fde581e8f49141..4292d743db4afa 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12404,7 +12404,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (UsesSM) {
if (NewFD->getReturnType()->isSizelessVectorType())
- Diag(NewFD->getLocation(), diag::warn_sme_locally_streaming_returns_vl);
+ Diag(NewFD->getLocation(),
+ diag::warn_sme_locally_streaming_has_vl_args_returns);
auto *FPT = NewFD->getType()->castAs<FunctionProtoType>();
bool AnyScalableArgs = false;
for (QualType T : FPT->param_types()) {
@@ -12415,7 +12416,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
if (AnyScalableArgs)
Diag(NewFD->getLocation(),
- diag::warn_sme_locally_streaming_has_vl_args);
+ diag::warn_sme_locally_streaming_has_vl_args_returns);
}
if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 83f61523927bc3..6002e9f25e2736 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,8 +33,8 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -50,8 +50,8 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -72,8 +72,8 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -89,8 +89,8 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index d41efdc2fd6ce4..bc7aa1aebbf84e 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -504,49 +504,92 @@ void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { }
__SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; }
-void sme_none_streaming_with_vl_arg(__SVInt8_t a) { }
+void sme_streaming_compatible_with_vl_arg(__SVInt8_t a) __arm_streaming_compatible { }
-__SVInt8_t sme_none_streaming_returns_vl(void) { __SVInt8_t r; return r; }
+__SVInt8_t sme_streaming_compatible_returns_vl(void) __arm_streaming_compatible { __SVInt8_t r; return r; }
-// expected-warning at +2 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee receives a VL-dependent argument and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
+
+__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
+
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value and the callee has an arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-void sme_none_streaming_calling_streaming_with_vl_args() {
+void sme_no_streaming_calling_streaming_with_vl_args() {
__SVInt8_t a;
- // expected-warning at +2 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming caller passes a VL-dependent argument to streaming callee, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
sme_streaming_with_vl_arg(a);
}
-void sme_none_streaming_calling_streaming_with_return_vl() {
- // expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
+void sme_no_streaming_calling_streaming_with_return_vl() {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
__SVInt8_t r = sme_streaming_returns_vl();
}
void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
__SVInt8_t a;
- // expected-warning at +2 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{streaming caller passes a VL-dependent argument to non-streaming callee, the streaming and non-streaming vector lengths may be different}}
- sme_none_streaming_with_vl_arg(a);
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ sme_no_streaming_with_vl_arg(a);
}
void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
- // expected-warning at +2 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{non-streaming callee returns a VL-dependent value to streaming caller, the streaming and non-streaming vector lengths may be different}}
- __SVInt8_t r = sme_none_streaming_returns_vl();
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ __SVInt8_t r = sme_no_streaming_returns_vl();
}
-void sme_streaming_calling_streaming_with_vl_args(void) __arm_streaming {
- __SVInt8_t a;
+void sme_no_streaming_calling_streaming(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ sc(arg);
+}
+
+__SVInt8_t sme_no_streaming_calling_streaming_return_vl(__SVInt8_t (*sc)(void) __arm_streaming) {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ return sc();
+}
+
+void sme_streaming_compatible_calling_streaming(__SVInt8_t arg) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ sme_streaming_with_vl_arg(arg);
+}
+
+void sme_streaming_compatible_sme_streaming_compatible_return_vl(void) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ __SVInt8_t r = sme_streaming_returns_vl();
+}
+
+void sme_streaming_calling_streaming(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) __arm_streaming {
+ sc(arg);
+}
+
+__SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*sc)(void) __arm_streaming) __arm_streaming {
+ return sc();
+}
+
+void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming {
sme_streaming_with_vl_arg(a);
}
void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming {
__SVInt8_t r = sme_streaming_returns_vl();
}
+
+void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm_streaming {
+ sme_streaming_compatible_with_vl_arg(a);
+}
+
+void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming {
+ __SVInt8_t r = sme_streaming_compatible_returns_vl();
+}
>From 00e3132c631d1e1a64641b9a18dd11c38a6c4f88 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Thu, 15 Feb 2024 11:51:54 +0000
Subject: [PATCH 06/14] Resolve comments.
---
.../clang/Basic/DiagnosticSemaKinds.td | 6 +-
clang/lib/Sema/SemaChecking.cpp | 50 +++++-----
clang/lib/Sema/SemaDecl.cpp | 16 +---
.../Sema/aarch64-incompat-sm-builtin-calls.c | 12 +--
clang/test/Sema/aarch64-sme-func-attrs.c | 96 +++++++++++++------
5 files changed, 102 insertions(+), 78 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dae703d50cc705..20c2320a9e7914 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3757,11 +3757,13 @@ def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
"passing a VL-dependent argument to/from a function that has a different"
- " streaming-mode, is undefined behaviour">,
+ " streaming-mode, the streaming and non-streaming vector lengths may be"
+ " different">,
InGroup<AArch64SMEAttributes>;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
"passing/returning a VL-dependent argument from a function"
- " arm_locally_streaming attribute, is undefined behaviour">,
+ " arm_locally_streaming attribute, the streaming and non-streaming vector"
+ " lengths may be different">,
InGroup<AArch64SMEAttributes>;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 94d87571b236e2..0e2b24e0a04a73 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7938,7 +7938,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// For variadic functions, we may have more args than parameters.
// For some K&R functions, we may have less args than parameters.
const auto N = std::min<unsigned>(Proto->getNumParams(), Args.size());
- bool AnyScalableArgs = false;
+ bool AnyScalableArgsOrRet = false;
for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
// Args[ArgIdx] can be null in malformed code.
if (const Expr *Arg = Args[ArgIdx]) {
@@ -7953,7 +7953,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
QualType ParamTy = Proto->getParamType(ArgIdx);
if (ParamTy->isSizelessVectorType())
- AnyScalableArgs = true;
+ AnyScalableArgsOrRet = true;
QualType ArgTy = Arg->getType();
CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
ArgTy, ParamTy);
@@ -7975,36 +7975,32 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
}
const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- bool IsCalleeStreaming = ((ExtInfo.AArch64SMEAttributes &
- FunctionType::SME_PStateSMEnabledMask) ||
- (ExtInfo.AArch64SMEAttributes &
- FunctionType::SME_PStateSMCompatibleMask));
+ auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
+ bool IsCalleeStreaming =
+ (ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask);
+ bool IsCalleeStreamingCompatible =
+ (ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMCompatibleMask);
bool IsBuiltin = (FD && FD->getBuiltinID());
+ AnyScalableArgsOrRet |= Proto->getReturnType()->isSizelessVectorType();
+ // If the caller is a function and the callee has a different
+ // non-compitable streaming attribute. If it passed any VL-based arguments
+ // or return VL-based value, then warn that the streaming and non-streaming
+ // vector lengths may be different.
if (CallerFD && Context.getTargetInfo().hasFeature("sme") && !IsBuiltin) {
- // If the callee has an AArch64 SME __arm_locally_streaming attribute
- // warn if this function returns VL-based value or pass any such argument,
- // the streaming and non-streaming vector lengths may be different.
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- // If the caller is a non-streaming function and the callee has a
- // streaming attribute. If it passed any VL-based arguments or return
- // VL-based value, then warn that the streaming and non-streaming vector
- // lengths may be different.
- if (CallerFnType != ArmStreaming) {
- if (IsCalleeStreaming) {
- if (AnyScalableArgs)
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- if (Proto->getReturnType()->isSizelessVectorType())
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- }
- } else if (!IsCalleeStreaming) {
- // If the callee is a non-streaming function and the caller has
- // streaming attribute. If it passed any VL-based arguments or return
- // VL-based value, then warn that the streaming and non-streaming vector
- // lengths may be different.
- if (AnyScalableArgs)
+ if (CallerFnType != ArmStreaming &&
+ CallerFnType != ArmStreamingCompatible) {
+ if (IsCalleeStreaming && AnyScalableArgsOrRet)
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+ } else if (CallerFnType == ArmStreaming && !IsCalleeStreaming &&
+ !IsCalleeStreamingCompatible) {
+ if (AnyScalableArgsOrRet)
Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- if (Proto->getReturnType()->isSizelessVectorType())
+ } else if (CallerFnType == ArmStreamingCompatible) {
+ if ((IsCalleeStreaming || !IsCalleeStreamingCompatible) &&
+ AnyScalableArgsOrRet)
Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4292d743db4afa..5590bee08cadb4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12403,18 +12403,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
bool UsesZT0 = Attr && Attr->isNewZT0();
if (UsesSM) {
- if (NewFD->getReturnType()->isSizelessVectorType())
- Diag(NewFD->getLocation(),
- diag::warn_sme_locally_streaming_has_vl_args_returns);
- auto *FPT = NewFD->getType()->castAs<FunctionProtoType>();
- bool AnyScalableArgs = false;
- for (QualType T : FPT->param_types()) {
- if (T->isSizelessVectorType()) {
- AnyScalableArgs = true;
- break;
- }
- }
- if (AnyScalableArgs)
+ if (NewFD->getReturnType()->isSizelessVectorType() ||
+ llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) {
+ return P->getOriginalType()->isSizelessVectorType();
+ }))
Diag(NewFD->getLocation(),
diag::warn_sme_locally_streaming_has_vl_args_returns);
}
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 6002e9f25e2736..52ca11b3147c9c 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,8 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -50,8 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -72,8 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -89,8 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index bc7aa1aebbf84e..04582817f2fd4e 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -512,70 +512,82 @@ void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, is undefined behaviour}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_no_streaming_calling_streaming_with_vl_args() {
__SVInt8_t a;
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
sme_streaming_with_vl_arg(a);
}
void sme_no_streaming_calling_streaming_with_return_vl() {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_streaming_returns_vl();
}
void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
__SVInt8_t a;
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
sme_no_streaming_with_vl_arg(a);
}
void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_no_streaming_returns_vl();
}
-void sme_no_streaming_calling_streaming(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+void sme_no_streaming_calling_streaming_with_vl_args_param(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
sc(arg);
}
-__SVInt8_t sme_no_streaming_calling_streaming_return_vl(__SVInt8_t (*sc)(void) __arm_streaming) {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- return sc();
+__SVInt8_t sme_no_streaming_calling_streaming_return_vl_param(__SVInt8_t (*s)(void) __arm_streaming) {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ return s();
}
-void sme_streaming_compatible_calling_streaming(__SVInt8_t arg) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
sme_streaming_with_vl_arg(arg);
}
-void sme_streaming_compatible_sme_streaming_compatible_return_vl(void) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, is undefined behaviour}}
+void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_streaming_returns_vl();
}
-void sme_streaming_calling_streaming(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) __arm_streaming {
- sc(arg);
+void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ sme_no_streaming_with_vl_arg(arg);
+}
+
+void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible {
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ __SVInt8_t r = sme_no_streaming_returns_vl();
}
-__SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*sc)(void) __arm_streaming) __arm_streaming {
- return sc();
+void sme_streaming_calling_streaming(__SVInt8_t arg, void (*s)( __SVInt8_t arg) __arm_streaming) __arm_streaming {
+ s(arg);
+}
+
+__SVInt8_t sme_streaming_calling_streaming_return_vl(__SVInt8_t (*s)(void) __arm_streaming) __arm_streaming {
+ return s();
}
void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming {
@@ -593,3 +605,29 @@ void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm
void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming {
__SVInt8_t r = sme_streaming_compatible_returns_vl();
}
+
+void sme_no_streaming_calling_streaming_compatible_with_vl_args() {
+ __SVInt8_t a;
+ sme_streaming_compatible_with_vl_arg(a);
+}
+
+void sme_no_streaming_calling_streaming_compatible_with_return_vl() {
+ __SVInt8_t r = sme_streaming_compatible_returns_vl();
+}
+
+void sme_no_streaming_calling_non_streaming_compatible_with_vl_args() {
+ __SVInt8_t a;
+ sme_no_streaming_with_vl_arg(a);
+}
+
+void sme_no_streaming_calling_non_streaming_compatible_with_return_vl() {
+ __SVInt8_t r = sme_no_streaming_returns_vl();
+}
+
+void sme_streaming_compatible_calling_streaming_compatible_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
+ sme_streaming_compatible_with_vl_arg(arg);
+}
+
+void sme_streaming_compatible_calling_streaming_compatible_with_return_vl(void) __arm_streaming_compatible {
+ __SVInt8_t r = sme_streaming_compatible_returns_vl();
+}
>From d6367d0c0db1de3003f544263452fbc461e025d4 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Thu, 15 Feb 2024 12:16:31 +0000
Subject: [PATCH 07/14] Updated comment in clang/lib/Sema/SemaDecl.cpp
---
clang/lib/Sema/SemaDecl.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5590bee08cadb4..7719b06f4e70b5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12395,7 +12395,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
// Check if the function definition uses any AArch64 SME features without
- // having the '+sme' feature enabled.
+ // having the '+sme' feature enabled and warn user if sme locally streaming
+ // function returns or uses arguments with VL-based types.
if (DeclIsDefn) {
const auto *Attr = NewFD->getAttr<ArmNewAttr>();
bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
>From c4c9155a00685fe9a362880839cdff213406df04 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Mon, 4 Mar 2024 13:36:26 +0000
Subject: [PATCH 08/14] Resolve comments.
---
.../clang/Basic/DiagnosticSemaKinds.td | 4 +-
clang/lib/Sema/SemaChecking.cpp | 22 ++++-----
clang/lib/Sema/SemaDecl.cpp | 2 +-
.../Sema/aarch64-incompat-sm-builtin-calls.c | 8 ++--
clang/test/Sema/aarch64-sme-func-attrs.c | 48 +++++++++----------
5 files changed, 40 insertions(+), 44 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 20c2320a9e7914..9a113f0632e181 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3757,12 +3757,12 @@ def err_sme_definition_using_zt0_in_non_sme2_target : Error<
"function using ZT0 state requires 'sme2'">;
def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
"passing a VL-dependent argument to/from a function that has a different"
- " streaming-mode, the streaming and non-streaming vector lengths may be"
+ " streaming-mode. The streaming and non-streaming vector lengths may be"
" different">,
InGroup<AArch64SMEAttributes>;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
"passing/returning a VL-dependent argument from a function"
- " arm_locally_streaming attribute, the streaming and non-streaming vector"
+ " arm_locally_streaming attribute. The streaming and non-streaming vector"
" lengths may be different">,
InGroup<AArch64SMEAttributes>;
def err_conflicting_attributes_arm_state : Error<
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0e2b24e0a04a73..42f4db1597900c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7990,19 +7990,15 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// vector lengths may be different.
if (CallerFD && Context.getTargetInfo().hasFeature("sme") && !IsBuiltin) {
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- if (CallerFnType != ArmStreaming &&
- CallerFnType != ArmStreamingCompatible) {
- if (IsCalleeStreaming && AnyScalableArgsOrRet)
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- } else if (CallerFnType == ArmStreaming && !IsCalleeStreaming &&
- !IsCalleeStreamingCompatible) {
- if (AnyScalableArgsOrRet)
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- } else if (CallerFnType == ArmStreamingCompatible) {
- if ((IsCalleeStreaming || !IsCalleeStreamingCompatible) &&
- AnyScalableArgsOrRet)
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- }
+ if ((CallerFnType != ArmStreaming &&
+ CallerFnType != ArmStreamingCompatible && IsCalleeStreaming &&
+ AnyScalableArgsOrRet) ||
+ (CallerFnType == ArmStreaming && !IsCalleeStreaming &&
+ !IsCalleeStreamingCompatible && AnyScalableArgsOrRet) ||
+ (CallerFnType == ArmStreamingCompatible &&
+ (IsCalleeStreaming || !IsCalleeStreamingCompatible) &&
+ AnyScalableArgsOrRet))
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
FunctionType::ArmStateValue CalleeArmZAState =
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7719b06f4e70b5..8472aaeb6bad97 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12403,7 +12403,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
bool UsesZA = Attr && Attr->isNewZA();
bool UsesZT0 = Attr && Attr->isNewZT0();
- if (UsesSM) {
+ if (NewFD->hasAttr<ArmLocallyStreamingAttr>()) {
if (NewFD->getReturnType()->isSizelessVectorType() ||
llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) {
return P->getOriginalType()->isSizelessVectorType();
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 52ca11b3147c9c..663813dfc7d930 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,7 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -49,7 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -70,7 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -86,7 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index 04582817f2fd4e..d5d8579cf287aa 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -512,73 +512,73 @@ void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute, the streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_no_streaming_calling_streaming_with_vl_args() {
__SVInt8_t a;
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
sme_streaming_with_vl_arg(a);
}
void sme_no_streaming_calling_streaming_with_return_vl() {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_streaming_returns_vl();
}
void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming {
__SVInt8_t a;
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
sme_no_streaming_with_vl_arg(a);
}
void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_no_streaming_returns_vl();
}
void sme_no_streaming_calling_streaming_with_vl_args_param(__SVInt8_t arg, void (*sc)( __SVInt8_t arg) __arm_streaming) {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
sc(arg);
}
__SVInt8_t sme_no_streaming_calling_streaming_return_vl_param(__SVInt8_t (*s)(void) __arm_streaming) {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
return s();
}
void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
sme_streaming_with_vl_arg(arg);
}
void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_streaming_returns_vl();
}
void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
sme_no_streaming_with_vl_arg(arg);
}
void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible {
- // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
- // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode, the streaming and non-streaming vector lengths may be different}}
+ // expected-warning at +2 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
+ // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a different streaming-mode. The streaming and non-streaming vector lengths may be different}}
__SVInt8_t r = sme_no_streaming_returns_vl();
}
>From 8b43957e2ef38b389e87e640bf711808364192a9 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Wed, 13 Mar 2024 16:52:08 +0000
Subject: [PATCH 09/14] Resolve remaining comments.
---
clang/lib/Sema/SemaChecking.cpp | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 42f4db1597900c..e08d7aced290db 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7988,16 +7988,14 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// non-compitable streaming attribute. If it passed any VL-based arguments
// or return VL-based value, then warn that the streaming and non-streaming
// vector lengths may be different.
- if (CallerFD && Context.getTargetInfo().hasFeature("sme") && !IsBuiltin) {
+ if (CallerFD && !IsBuiltin && AnyScalableArgsOrRet) {
ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
if ((CallerFnType != ArmStreaming &&
- CallerFnType != ArmStreamingCompatible && IsCalleeStreaming &&
- AnyScalableArgsOrRet) ||
+ CallerFnType != ArmStreamingCompatible && IsCalleeStreaming) ||
(CallerFnType == ArmStreaming && !IsCalleeStreaming &&
- !IsCalleeStreamingCompatible && AnyScalableArgsOrRet) ||
+ !IsCalleeStreamingCompatible) ||
(CallerFnType == ArmStreamingCompatible &&
- (IsCalleeStreaming || !IsCalleeStreamingCompatible) &&
- AnyScalableArgsOrRet))
+ (IsCalleeStreaming || !IsCalleeStreamingCompatible)))
Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
>From b3aa561f0286ad75cb7b32b900168617efba90d3 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Fri, 15 Mar 2024 11:35:13 +0000
Subject: [PATCH 10/14] Change all AArch64SMEAttributes warnings off by
default.
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++--
clang/test/Sema/aarch64-incompat-sm-builtin-calls.c | 2 +-
clang/test/Sema/aarch64-sme-func-attrs.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9a113f0632e181..749913f4176b7b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3759,12 +3759,12 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
"passing a VL-dependent argument to/from a function that has a different"
" streaming-mode. The streaming and non-streaming vector lengths may be"
" different">,
- InGroup<AArch64SMEAttributes>;
+ InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
"passing/returning a VL-dependent argument from a function"
" arm_locally_streaming attribute. The streaming and non-streaming vector"
" lengths may be different">,
- InGroup<AArch64SMEAttributes>;
+ InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
"conflicting attributes for state '%0'">;
def err_sme_streaming_cannot_be_multiversioned : Error<
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 663813dfc7d930..ad52b983a135cd 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -1,6 +1,6 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \
-// RUN: -target-feature +sme2 -target-feature +sve2 -target-feature +neon -fsyntax-only -verify %s
+// RUN: -target-feature +sme2 -target-feature +sve2 -target-feature +neon -Waarch64-sme-attributes -fsyntax-only -verify %s
// REQUIRES: aarch64-registered-target
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index d5d8579cf287aa..f6e607c4d972e0 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify=expected-cpp -x c++ %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s
// Valid attributes
>From d88118cc217b700f41c58f02f018bb7f9e5e2c25 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Tue, 19 Mar 2024 16:10:18 +0000
Subject: [PATCH 11/14] Resolve comments.
---
.../clang/Basic/DiagnosticSemaKinds.td | 4 +-
clang/lib/Sema/SemaChecking.cpp | 41 ++++++++-----------
.../Sema/aarch64-incompat-sm-builtin-calls.c | 8 ++--
clang/test/Sema/aarch64-sme-func-attrs.c | 8 ++--
4 files changed, 28 insertions(+), 33 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 749913f4176b7b..f8195570195cb8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3761,8 +3761,8 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
" different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
- "passing/returning a VL-dependent argument from a function"
- " arm_locally_streaming attribute. The streaming and non-streaming vector"
+ "passing/returning a VL-dependent argument from a arm_locally_streaming"
+ " function. The streaming and non-streaming vector"
" lengths may be different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def err_conflicting_attributes_arm_state : Error<
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index e08d7aced290db..c85a584fc93ce0 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7938,7 +7938,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// For variadic functions, we may have more args than parameters.
// For some K&R functions, we may have less args than parameters.
const auto N = std::min<unsigned>(Proto->getNumParams(), Args.size());
- bool AnyScalableArgsOrRet = false;
+ bool AnyScalableArgsOrRet = Proto->getReturnType()->isSizelessVectorType();
for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
// Args[ArgIdx] can be null in malformed code.
if (const Expr *Arg = Args[ArgIdx]) {
@@ -7974,29 +7974,24 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
}
}
+ // If the call requires a streaming-mode change and has scalable vector
+ // arguments or return values, then warn the user that the streaming and
+ // non-streaming vector lengths may be different.
const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- bool IsCalleeStreaming =
- (ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask);
- bool IsCalleeStreamingCompatible =
- (ExtInfo.AArch64SMEAttributes &
- FunctionType::SME_PStateSMCompatibleMask);
- bool IsBuiltin = (FD && FD->getBuiltinID());
- AnyScalableArgsOrRet |= Proto->getReturnType()->isSizelessVectorType();
-
- // If the caller is a function and the callee has a different
- // non-compitable streaming attribute. If it passed any VL-based arguments
- // or return VL-based value, then warn that the streaming and non-streaming
- // vector lengths may be different.
- if (CallerFD && !IsBuiltin && AnyScalableArgsOrRet) {
- ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- if ((CallerFnType != ArmStreaming &&
- CallerFnType != ArmStreamingCompatible && IsCalleeStreaming) ||
- (CallerFnType == ArmStreaming && !IsCalleeStreaming &&
- !IsCalleeStreamingCompatible) ||
- (CallerFnType == ArmStreamingCompatible &&
- (IsCalleeStreaming || !IsCalleeStreamingCompatible)))
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+ bool IsBuiltin = FD && FD->getBuiltinID();
+ if (CallerFD) {
+ if (!IsBuiltin && AnyScalableArgsOrRet) {
+ bool IsCalleeStreaming = ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMEnabledMask;
+ bool IsCalleeStreamingCompatible =
+ ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMCompatibleMask;
+ ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
+ if (!IsCalleeStreamingCompatible &&
+ (CallerFnType == ArmStreamingCompatible ||
+ ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming)))
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+ }
}
FunctionType::ArmStateValue CalleeArmZAState =
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index ad52b983a135cd..4b643e8e4f5f1a 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,7 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -49,7 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -70,7 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -86,7 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index f6e607c4d972e0..2a48c773363d3c 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -512,12 +512,12 @@ void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a function arm_locally_streaming attribute. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_no_streaming_calling_streaming_with_vl_args() {
>From ef679b57893b9b0954ef7c6c9a0c61f80714a618 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Tue, 19 Mar 2024 16:29:30 +0000
Subject: [PATCH 12/14] Resolve comment.
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/test/Sema/aarch64-incompat-sm-builtin-calls.c | 8 ++++----
clang/test/Sema/aarch64-sme-func-attrs.c | 8 ++++----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f8195570195cb8..622df5fccb18cc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3761,7 +3761,7 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
" different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
- "passing/returning a VL-dependent argument from a arm_locally_streaming"
+ "passing/returning a VL-dependent argument from a __arm_locally_streaming"
" function. The streaming and non-streaming vector"
" lengths may be different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index 4b643e8e4f5f1a..cda0166bc9022d 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,7 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -49,7 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -70,7 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -86,7 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index 2a48c773363d3c..7dd398b90b2008 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -512,12 +512,12 @@ void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_no_streaming_calling_streaming_with_vl_args() {
>From 2cb1c3dbd2d3049ce3dcb108aee0a57fada523bf Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Mon, 25 Mar 2024 16:08:35 +0000
Subject: [PATCH 13/14] Resolved missed comment at #7519
---
clang/lib/Sema/SemaChecking.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c85a584fc93ce0..52d151f777d1f9 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7978,9 +7978,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// arguments or return values, then warn the user that the streaming and
// non-streaming vector lengths may be different.
const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- bool IsBuiltin = FD && FD->getBuiltinID();
if (CallerFD) {
- if (!IsBuiltin && AnyScalableArgsOrRet) {
+ if ((!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) {
bool IsCalleeStreaming = ExtInfo.AArch64SMEAttributes &
FunctionType::SME_PStateSMEnabledMask;
bool IsCalleeStreamingCompatible =
>From e3c81c92737641f7914a7ed830c6c4baccb304f2 Mon Sep 17 00:00:00 2001
From: Dinar Temirbulatov <Dinar.Temirbulatov at arm.com>
Date: Thu, 28 Mar 2024 11:21:11 +0000
Subject: [PATCH 14/14] Resolve comments.
---
clang/include/clang/Basic/DiagnosticGroups.td | 2 +-
.../clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/SemaChecking.cpp | 24 +++++++++----------
.../Sema/aarch64-incompat-sm-builtin-calls.c | 8 +++----
clang/test/Sema/aarch64-sme-func-attrs.c | 15 +++++-------
5 files changed, 23 insertions(+), 28 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 6b6353bcd7599b..47747d8704b6c8 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1412,7 +1412,7 @@ def MultiGPU: DiagGroup<"multi-gpu">;
// libc and the CRT to be skipped.
def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;
-// A warning group AArch64 related to SME function attribues.
+// A warning group related to AArch64 SME function attribues.
def AArch64SMEAttributes : DiagGroup<"aarch64-sme-attributes">;
// A warning group for things that will change semantics in the future.
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 622df5fccb18cc..ff9c21191771c3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3761,7 +3761,7 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
" different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
def warn_sme_locally_streaming_has_vl_args_returns : Warning<
- "passing/returning a VL-dependent argument from a __arm_locally_streaming"
+ "passing/returning a VL-dependent argument to/from a __arm_locally_streaming"
" function. The streaming and non-streaming vector"
" lengths may be different">,
InGroup<AArch64SMEAttributes>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 52d151f777d1f9..abfd9a3031577b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7978,19 +7978,17 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
// arguments or return values, then warn the user that the streaming and
// non-streaming vector lengths may be different.
const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
- if (CallerFD) {
- if ((!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) {
- bool IsCalleeStreaming = ExtInfo.AArch64SMEAttributes &
- FunctionType::SME_PStateSMEnabledMask;
- bool IsCalleeStreamingCompatible =
- ExtInfo.AArch64SMEAttributes &
- FunctionType::SME_PStateSMCompatibleMask;
- ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
- if (!IsCalleeStreamingCompatible &&
- (CallerFnType == ArmStreamingCompatible ||
- ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming)))
- Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
- }
+ if (CallerFD && (!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) {
+ bool IsCalleeStreaming =
+ ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
+ bool IsCalleeStreamingCompatible =
+ ExtInfo.AArch64SMEAttributes &
+ FunctionType::SME_PStateSMCompatibleMask;
+ ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
+ if (!IsCalleeStreamingCompatible &&
+ (CallerFnType == ArmStreamingCompatible ||
+ ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming)))
+ Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
}
FunctionType::ArmStateValue CalleeArmZAState =
diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
index cda0166bc9022d..6a1feeb9bf5397 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,7 +33,7 @@ svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
@@ -49,7 +49,7 @@ svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streamin
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
// expected-warning at +1 {{builtin call has undefined behaviour when called from a streaming function}}
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
@@ -70,7 +70,7 @@ svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_
return svadd_n_f64_m(pg, a, b);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
// expected-no-warning
return svadd_n_f64_m(pg, a, b);
@@ -86,7 +86,7 @@ svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
return svmul_lane_s16(op1, op2, 0);
}
-// expected-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
// expected-no-warning
return svmul_lane_s16(op1, op2, 0);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs.c b/clang/test/Sema/aarch64-sme-func-attrs.c
index 7dd398b90b2008..12de16509ccb8d 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-cpp -x c++ %s
// Valid attributes
@@ -48,9 +48,6 @@ typedef void (*fptrty6) (void);
fptrty6 cast_nza_func_to_normal() { return sme_arm_new_za; }
fptrty6 cast_ls_func_to_normal() { return sme_arm_locally_streaming; }
-void sme_arm_streaming_with_vl_args(void) __arm_streaming;
-
-
// Invalid attributes
// expected-cpp-error at +4 {{'__arm_streaming_compatible' and '__arm_streaming' are not compatible}}
@@ -512,12 +509,12 @@ void sme_no_streaming_with_vl_arg(__SVInt8_t a) { }
__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
-// expected-warning at +2 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
-// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-warning at +2 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
+// expected-cpp-warning at +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be different}}
__arm_locally_streaming __SVInt8_t sme_locally_streaming_returns_vl(void) { __SVInt8_t r; return r; }
void sme_no_streaming_calling_streaming_with_vl_args() {
More information about the cfe-commits
mailing list