Skip to content

Conversation

@MacDue
Copy link
Member

@MacDue MacDue commented Jan 27, 2025

Currently, these generate incorrect code, as streaming/SME 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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 27, 2025

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-clang

Author: Benjamin Maxwell (MacDue)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/124590.diff

3 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+17)
  • (added) clang/test/Sema/aarch64-sme-streaming-openmp-captured-region.c (+46)
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@+2 {{OpenMP captured regions are not yet supported in streaming functions}}
+  // expected-cpp-error@+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@+2 {{OpenMP captured regions are not yet supported in streaming functions}}
+  // expected-cpp-error@+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);
+  }
+}

Currently, these generate incorrect code, as streaming/SME 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.
@MacDue MacDue force-pushed the sme_openmp_regions branch from 232e34b to f3083be Compare January 27, 2025 17:37
@MacDue MacDue changed the title [clang][SME] Emit error for OpemMP captured regions in streaming functions [clang][SME] Emit error for OpemMP captured regions in SME functions Jan 27, 2025
@MacDue MacDue changed the title [clang][SME] Emit error for OpemMP captured regions in SME functions [clang][SME] Emit error for OpenMP captured regions in SME functions Jan 27, 2025
Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

In theory, handling streaming mode doesn't seem too challenging here: you mark the outlined functions locally_streaming, and you're done, I think. That said, I'm not sure how you define the semantics for ZA, so maybe better to just forbid everything SME-related.

Copy link
Collaborator

@sdesmalen-arm sdesmalen-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With added test the patch looks good to me.

@MacDue MacDue merged commit a7f4044 into llvm:main Jan 28, 2025
8 checks passed
@MacDue MacDue deleted the sme_openmp_regions branch January 28, 2025 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:AArch64 backend:ARM clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants