Skip to content

[Flang][OpenMP] Skip threadprivate HostAssoc symbols for default privatization #127754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

Thirumalai-Shaktivel
Copy link
Member

Issue: Compilation abnormally terminates in parallel default(private)

Documentation reference:
A threadprivate variable must not appear as the base variable of a list item in any clause except for the copyin and copyprivate clauses

Explanation:
From the reference, the threadprivate symbols cannot be used in the DSA clauses, which in turn means, the symbol can be skipped for privatization

Fixes #123535

Issue: Compilation abnormally terminates in parallel default(private)

Documentation reference:
A threadprivate variable must not appear as the base variable of a
list item in any clause except for the copyin and copyprivate clauses

Explanation:
From the reference, the threadprivate symbols cannot be used in the
DSA clauses, which in turn means, the symbol can be skipped for
privatization

Fixes llvm#123535
@llvmbot
Copy link
Member

llvmbot commented Feb 19, 2025

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-fir-hlfir

Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)

Changes

Issue: Compilation abnormally terminates in parallel default(private)

Documentation reference:
A threadprivate variable must not appear as the base variable of a list item in any clause except for the copyin and copyprivate clauses

Explanation:
From the reference, the threadprivate symbols cannot be used in the DSA clauses, which in turn means, the symbol can be skipped for privatization

Fixes #123535


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

2 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+1-1)
  • (modified) flang/test/Lower/OpenMP/threadprivate-hlfir.f90 (+52-2)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 91a1b3061e1f9..7a1dfe003e8c2 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2309,7 +2309,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
     }
 
     if (Symbol * found{currScope().FindSymbol(name.source)}) {
-      if (found->test(semantics::Symbol::Flag::OmpThreadprivate))
+      if (found->GetUltimate().test(semantics::Symbol::Flag::OmpThreadprivate))
         return;
     }
 
diff --git a/flang/test/Lower/OpenMP/threadprivate-hlfir.f90 b/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
index 7d02987c5eade..6201459bc42ca 100644
--- a/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
+++ b/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
@@ -15,8 +15,6 @@
 !CHECK:      %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[TP_VAL]]) fastmath<contract> : (!fir.ref<i8>, i32) -> i1
 !CHECK:      omp.terminator
 
-!CHECK:  fir.global internal @_QFsubEa : i32
-
 subroutine sub()
   integer, save:: a
   !$omp threadprivate(a)
@@ -25,3 +23,55 @@ subroutine sub()
   !$omp end parallel
 end subroutine
 
+!CHECK-LABEL: func.func @_QPsub_02()
+subroutine sub_02()
+  integer, save :: a
+  !$omp threadprivate(a)
+  !CHECK:   %[[ADDR_02:.*]] = fir.address_of(@_QFsub_02Ea) : !fir.ref<i32>
+  !CHECK:   %[[DECL_02:.*]]:2 = hlfir.declare %[[ADDR_02]] {{{.*}} uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  !CHECK:   %[[TP_02:.*]] = omp.threadprivate %[[DECL_02]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+  !CHECK:   %[[TP_DECL_02:.*]]:2 = hlfir.declare %[[TP_02]] {{{.*}} uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  call sub_03
+  !CHECK:   fir.call @_QFsub_02Psub_03() fastmath<contract> : () -> ()
+  !CHECK:   return
+
+contains
+
+  !CHECK-LABEL: func.func private @_QFsub_02Psub_03()
+  subroutine sub_03()
+    !CHECK:   %[[ADDR_03:.*]] = fir.address_of(@_QFsub_02Ea) : !fir.ref<i32>
+    !CHECK:   %[[DECL_03:.*]]:2 = hlfir.declare %[[ADDR_03]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    !CHECK:   %[[TP_03:.*]] = omp.threadprivate %[[DECL_03]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+    !CHECK:   %[[TP_DECL_03:.*]]:2 = hlfir.declare %[[TP_03]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    !$omp parallel default(private)
+      !CHECK:   omp.parallel
+      !CHECK:     %[[TP_04:.*]] = omp.threadprivate %[[DECL_03]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+      !CHECK:     %[[TP_DECL_04:.*]]:2 = hlfir.declare %[[TP_04]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+      print *, a
+      !CHECK:     omp.terminator
+    !$omp end parallel
+  end subroutine
+end subroutine
+
+module mod_01
+  integer, save :: a
+  !CHECK: fir.global @_QMmod_01Ea : i32
+  !$omp threadprivate(a)
+end module
+
+!CHECK-LABEL: func.func @_QPsub_05()
+subroutine sub_05()
+  use mod_01, only: a
+  !$omp parallel default(private)
+    !CHECK:   omp.parallel {
+    !CHECK:     %[[TP_05:.*]] = omp.threadprivate %{{.*}} : !fir.ref<i32> -> !fir.ref<i32>
+    !CHECK:     %{{.*}} = hlfir.declare %[[TP_05]] {uniq_name = "_QMmod_01Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+      print *, a
+    !CHECK:     omp.terminator
+  !$omp end parallel
+end subroutine
+
+
+!CHECK:  fir.global internal @_QFsubEa : i32
+
+!CHECK: fir.global internal @_QFsub_02Ea : i32

@llvmbot
Copy link
Member

llvmbot commented Feb 19, 2025

@llvm/pr-subscribers-flang-openmp

Author: Thirumalai Shaktivel (Thirumalai-Shaktivel)

Changes

Issue: Compilation abnormally terminates in parallel default(private)

Documentation reference:
A threadprivate variable must not appear as the base variable of a list item in any clause except for the copyin and copyprivate clauses

Explanation:
From the reference, the threadprivate symbols cannot be used in the DSA clauses, which in turn means, the symbol can be skipped for privatization

Fixes #123535


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

2 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+1-1)
  • (modified) flang/test/Lower/OpenMP/threadprivate-hlfir.f90 (+52-2)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 91a1b3061e1f9..7a1dfe003e8c2 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2309,7 +2309,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
     }
 
     if (Symbol * found{currScope().FindSymbol(name.source)}) {
-      if (found->test(semantics::Symbol::Flag::OmpThreadprivate))
+      if (found->GetUltimate().test(semantics::Symbol::Flag::OmpThreadprivate))
         return;
     }
 
diff --git a/flang/test/Lower/OpenMP/threadprivate-hlfir.f90 b/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
index 7d02987c5eade..6201459bc42ca 100644
--- a/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
+++ b/flang/test/Lower/OpenMP/threadprivate-hlfir.f90
@@ -15,8 +15,6 @@
 !CHECK:      %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[TP_VAL]]) fastmath<contract> : (!fir.ref<i8>, i32) -> i1
 !CHECK:      omp.terminator
 
-!CHECK:  fir.global internal @_QFsubEa : i32
-
 subroutine sub()
   integer, save:: a
   !$omp threadprivate(a)
@@ -25,3 +23,55 @@ subroutine sub()
   !$omp end parallel
 end subroutine
 
+!CHECK-LABEL: func.func @_QPsub_02()
+subroutine sub_02()
+  integer, save :: a
+  !$omp threadprivate(a)
+  !CHECK:   %[[ADDR_02:.*]] = fir.address_of(@_QFsub_02Ea) : !fir.ref<i32>
+  !CHECK:   %[[DECL_02:.*]]:2 = hlfir.declare %[[ADDR_02]] {{{.*}} uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  !CHECK:   %[[TP_02:.*]] = omp.threadprivate %[[DECL_02]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+  !CHECK:   %[[TP_DECL_02:.*]]:2 = hlfir.declare %[[TP_02]] {{{.*}} uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  call sub_03
+  !CHECK:   fir.call @_QFsub_02Psub_03() fastmath<contract> : () -> ()
+  !CHECK:   return
+
+contains
+
+  !CHECK-LABEL: func.func private @_QFsub_02Psub_03()
+  subroutine sub_03()
+    !CHECK:   %[[ADDR_03:.*]] = fir.address_of(@_QFsub_02Ea) : !fir.ref<i32>
+    !CHECK:   %[[DECL_03:.*]]:2 = hlfir.declare %[[ADDR_03]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    !CHECK:   %[[TP_03:.*]] = omp.threadprivate %[[DECL_03]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+    !CHECK:   %[[TP_DECL_03:.*]]:2 = hlfir.declare %[[TP_03]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    !$omp parallel default(private)
+      !CHECK:   omp.parallel
+      !CHECK:     %[[TP_04:.*]] = omp.threadprivate %[[DECL_03]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+      !CHECK:     %[[TP_DECL_04:.*]]:2 = hlfir.declare %[[TP_04]] {uniq_name = "_QFsub_02Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+      print *, a
+      !CHECK:     omp.terminator
+    !$omp end parallel
+  end subroutine
+end subroutine
+
+module mod_01
+  integer, save :: a
+  !CHECK: fir.global @_QMmod_01Ea : i32
+  !$omp threadprivate(a)
+end module
+
+!CHECK-LABEL: func.func @_QPsub_05()
+subroutine sub_05()
+  use mod_01, only: a
+  !$omp parallel default(private)
+    !CHECK:   omp.parallel {
+    !CHECK:     %[[TP_05:.*]] = omp.threadprivate %{{.*}} : !fir.ref<i32> -> !fir.ref<i32>
+    !CHECK:     %{{.*}} = hlfir.declare %[[TP_05]] {uniq_name = "_QMmod_01Ea"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+      print *, a
+    !CHECK:     omp.terminator
+  !$omp end parallel
+end subroutine
+
+
+!CHECK:  fir.global internal @_QFsubEa : i32
+
+!CHECK: fir.global internal @_QFsub_02Ea : i32

@kiranchandramohan
Copy link
Contributor

From the reference, the threadprivate symbols cannot be used in the DSA clauses, which in turn means, the symbol can be skipped for privatization

You mean default privatization right? It might be good to clarify that. Do we emit an error if it occurs in a private clause?

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

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

LG

@Thirumalai-Shaktivel
Copy link
Member Author

Do we emit an error if it occurs in a private clause?

Yes, see: https://godbolt.org/z/8G8joeGe7

@Thirumalai-Shaktivel Thirumalai-Shaktivel merged commit 99aea21 into llvm:main Feb 19, 2025
13 checks passed
@Thirumalai-Shaktivel Thirumalai-Shaktivel deleted the llvm/issue_123535 branch February 19, 2025 08:47
@Thirumalai-Shaktivel Thirumalai-Shaktivel changed the title [Flang][OpenMP] Skip threadprivate HostAssoc symbols for privatization [Flang][OpenMP] Skip threadprivate HostAssoc symbols for default privatization Feb 19, 2025
@Thirumalai-Shaktivel
Copy link
Member Author

Thanks for the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:openmp flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang][OpenMP] Compilation abnormally terminates when pointer (first argument) of cray pointer is specified in threadprivate directive
3 participants