[clang] bd34bc6 - [Clang][AArch64] Extend diagnostics when warning non/streaming about vector size difference (#88380)

via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 24 06:13:54 PDT 2024


Author: Dinar Temirbulatov
Date: 2024-04-24T14:13:47+01:00
New Revision: bd34bc6dc2e4e60813ddea31bfb4ca46d3a96013

URL: https://github.com/llvm/llvm-project/commit/bd34bc6dc2e4e60813ddea31bfb4ca46d3a96013
DIFF: https://github.com/llvm/llvm-project/commit/bd34bc6dc2e4e60813ddea31bfb4ca46d3a96013.diff

LOG: [Clang][AArch64] Extend diagnostics when warning non/streaming about vector size difference (#88380)

Add separate messages about passing arguments or returning parameters
with scalable types.

---------

Co-authored-by: Sander de Smalen <sander.desmalen at arm.com>

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaChecking.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
    clang/test/Sema/aarch64-sme-func-attrs.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 63e951daec7477..6732a1a98452ad 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3755,14 +3755,12 @@ def err_sme_definition_using_za_in_non_sme_target : Error<
 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 
diff erent"
-  " streaming-mode. The streaming and non-streaming vector lengths may be"
-  " 
diff erent">,
+  "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a 
diff erent"
+  " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime">,
   InGroup<AArch64SMEAttributes>, DefaultIgnore;
 def warn_sme_locally_streaming_has_vl_args_returns : Warning<
-  "passing/returning a VL-dependent argument to/from a __arm_locally_streaming"
-  " function. The streaming and non-streaming vector"
-  " lengths may be 
diff erent">,
+  "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined"
+  " behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime">,
   InGroup<AArch64SMEAttributes>, DefaultIgnore;
 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 51757f4cf727d6..67132701b41cfd 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7953,7 +7953,8 @@ 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 = Proto->getReturnType()->isSizelessVectorType();
+    bool IsScalableRet = Proto->getReturnType()->isSizelessVectorType();
+    bool IsScalableArg = false;
     for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
       // Args[ArgIdx] can be null in malformed code.
       if (const Expr *Arg = Args[ArgIdx]) {
@@ -7968,7 +7969,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
 
         QualType ParamTy = Proto->getParamType(ArgIdx);
         if (ParamTy->isSizelessVectorType())
-          AnyScalableArgsOrRet = true;
+          IsScalableArg = true;
         QualType ArgTy = Arg->getType();
         CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
                           ArgTy, ParamTy);
@@ -7993,7 +7994,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 
diff erent.
     const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
-    if (CallerFD && (!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) {
+    if (CallerFD && (!FD || !FD->getBuiltinID()) &&
+        (IsScalableArg || IsScalableRet)) {
       bool IsCalleeStreaming =
           ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
       bool IsCalleeStreamingCompatible =
@@ -8002,8 +8004,14 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
       ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
       if (!IsCalleeStreamingCompatible &&
           (CallerFnType == ArmStreamingCompatible ||
-           ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming)))
-        Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming);
+           ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming))) {
+        if (IsScalableArg)
+          Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
+              << /*IsArg=*/true;
+        if (IsScalableRet)
+          Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
+              << /*IsArg=*/false;
+      }
     }
 
     FunctionType::ArmStateValue CalleeArmZAState =

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 452e00fa32b102..378615497b13cf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12417,12 +12417,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     bool UsesZT0 = Attr && Attr->isNewZT0();
 
     if (NewFD->hasAttr<ArmLocallyStreamingAttr>()) {
-      if (NewFD->getReturnType()->isSizelessVectorType() ||
-          llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) {
+      if (NewFD->getReturnType()->isSizelessVectorType())
+        Diag(NewFD->getLocation(),
+             diag::warn_sme_locally_streaming_has_vl_args_returns)
+            << /*IsArg=*/false;
+      if (llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) {
             return P->getOriginalType()->isSizelessVectorType();
           }))
         Diag(NewFD->getLocation(),
-             diag::warn_sme_locally_streaming_has_vl_args_returns);
+             diag::warn_sme_locally_streaming_has_vl_args_returns)
+            << /*IsArg=*/true;
     }
     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 6a1feeb9bf5397..e55e84a61034fa 100644
--- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
+++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c
@@ -33,7 +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 +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be 
diff erent}}
+// expected-warning at +2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-warning at +1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __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 +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 +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be 
diff erent}}
+// expected-warning at +2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-warning at +1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __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 +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 +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be 
diff erent}}
+// expected-warning at +2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-warning at +1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __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 +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 +1 {{passing/returning a VL-dependent argument to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be 
diff erent}}
+// expected-warning at +2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-warning at +1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __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 12de16509ccb8d..3d90723d32f1e7 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs.c
+++ b/clang/test/Sema/aarch64-sme-func-attrs.c
@@ -509,73 +509,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 to/from a __arm_locally_streaming function. The streaming and non-streaming vector lengths may be 
diff erent}}
-// 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 
diff erent}}
+// expected-warning at +2 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-cpp-warning at +1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __arm_locally_streaming void sme_locally_streaming_with_vl_arg(__SVInt8_t a) { }
 
-// 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 
diff erent}}
-// 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 
diff erent}}
+// expected-warning at +2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+// expected-cpp-warning at +1 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
 __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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   __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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   __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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   __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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{passing a VL-dependent argument to a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   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 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
-  // expected-cpp-warning at +1 {{passing a VL-dependent argument to/from a function that has a 
diff erent streaming-mode. The streaming and non-streaming vector lengths may be 
diff erent}}
+  // expected-warning at +2 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
+  // expected-cpp-warning at +1 {{returning a VL-dependent argument from a function with a 
diff erent streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are 
diff erent at runtime}}
   __SVInt8_t r = sme_no_streaming_returns_vl();
 }
 


        


More information about the cfe-commits mailing list