[clang] [clang][SME] Emit error for OpemMP captured regions in streaming functions (PR #124590)

Benjamin Maxwell via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 27 09:05:01 PST 2025


https://github.com/MacDue created https://github.com/llvm/llvm-project/pull/124590

Currently, these generate incorrect code, as streaming attributes are not propagated to the outlined function. As we've yet to work on mixing OpenMP and streaming functions (and determine how they should interact with OpenMP's runtime), we think it is best to disallow this for now.

>From 3e2194f9c171ba5b4ef6f4f1dff5443b3a9b1a33 Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Mon, 27 Jan 2025 16:43:58 +0000
Subject: [PATCH] [clang][SME] Emit error for OpemMP captured regions in
 streaming functions

Currently, these generate incorrect code, as streaming attributes are
not propagated to the outlined function. As we've yet to work on mixing
OpenMP and streaming functions (and determine how they should interact
with OpenMP's runtime), we think it is best to disallow this for now.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +
 clang/lib/Sema/SemaStmt.cpp                   | 17 +++++++
 ...h64-sme-streaming-openmp-captured-region.c | 46 +++++++++++++++++++
 3 files changed, 65 insertions(+)
 create mode 100644 clang/test/Sema/aarch64-sme-streaming-openmp-captured-region.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 774e5484cfa0e7..7f15206418e2df 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3864,6 +3864,8 @@ 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 err_sme_openmp_captured_region : Error<
+  "OpenMP captured regions are not yet supported in streaming functions">;
 def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning<
   "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different"
   " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">,
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 25a07d0315eac1..a7f9b70c91d92e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4568,9 +4568,23 @@ buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
   return false;
 }
 
+static bool
+isOpenMPCapturedRegionInArmStreamingFunction(Sema const &S,
+                                             CapturedRegionKind Kind) {
+  if (!S.getLangOpts().OpenMP || Kind != CR_OpenMP)
+    return false;
+  FunctionDecl *FD = S.getCurFunctionDecl(/*AllowLambda=*/true);
+  if (!FD)
+    return false;
+  return IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true);
+}
+
 void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                     CapturedRegionKind Kind,
                                     unsigned NumParams) {
+  if (isOpenMPCapturedRegionInArmStreamingFunction(*this, Kind))
+    Diag(Loc, diag::err_sme_openmp_captured_region);
+
   CapturedDecl *CD = nullptr;
   RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
 
@@ -4602,6 +4616,9 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                     CapturedRegionKind Kind,
                                     ArrayRef<CapturedParamNameType> Params,
                                     unsigned OpenMPCaptureLevel) {
+  if (isOpenMPCapturedRegionInArmStreamingFunction(*this, Kind))
+    Diag(Loc, diag::err_sme_openmp_captured_region);
+
   CapturedDecl *CD = nullptr;
   RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size());
 
diff --git a/clang/test/Sema/aarch64-sme-streaming-openmp-captured-region.c b/clang/test/Sema/aarch64-sme-streaming-openmp-captured-region.c
new file mode 100644
index 00000000000000..a5f5ba36a22aa8
--- /dev/null
+++ b/clang/test/Sema/aarch64-sme-streaming-openmp-captured-region.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -fopenmp -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -fopenmp -fsyntax-only -verify=expected-cpp -x c++ %s
+
+int compute(int);
+
+void streaming_openmp_captured_region(int* out) __arm_streaming
+{
+  // expected-error at +2 {{OpenMP captured regions are not yet supported in streaming functions}}
+  // expected-cpp-error at +1 {{OpenMP captured regions are not yet supported in streaming functions}}
+  #pragma omp parallel for num_threads(32)
+  for(int ci =0;ci< 8;ci++)
+  {
+    out[ci] =compute(ci);
+  }
+}
+
+__arm_locally_streaming void locally_streaming_openmp_captured_region(int* out)
+{
+  // expected-error at +2 {{OpenMP captured regions are not yet supported in streaming functions}}
+  // expected-cpp-error at +1 {{OpenMP captured regions are not yet supported in streaming functions}}
+  #pragma omp parallel for num_threads(32)
+  for(int ci =0;ci< 8;ci++)
+  {
+    out[ci] = compute(ci);
+  }
+}
+
+/// OpenMP directives that don't create a captured region are okay:
+
+void streaming_function_openmp(int* out) __arm_streaming
+{
+  #pragma omp unroll full
+  for(int ci =0;ci< 8;ci++)
+  {
+    out[ci] =compute(ci);
+  }
+}
+
+__arm_locally_streaming void locally_streaming_openmp(int* out)
+{
+  #pragma omp unroll full
+  for(int ci =0;ci< 8;ci++)
+  {
+    out[ci] = compute(ci);
+  }
+}



More information about the cfe-commits mailing list