[flang-commits] [flang] [flang][OpenMP] don't privatise loop index marked shared (PR #108176)

Mats Petersson via flang-commits flang-commits at lists.llvm.org
Thu Sep 12 09:34:34 PDT 2024


https://github.com/Leporacanthicus updated https://github.com/llvm/llvm-project/pull/108176

>From 688bef8d46c2a28a12edb8164de0849bd9bfa767 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 10 Sep 2024 15:50:49 +0000
Subject: [PATCH 1/4] [flang][OpenMP] don't privatise loop index marked shared

Mark the symbol with OmpShared, and then check that later in
lowering to avoid making a local loop index.

Tests updated to match the extra OmpShared attribute.

Add regression test for lowering to hlfir.

Closes #102961
---
 flang/lib/Lower/Bridge.cpp                    |  3 +-
 flang/lib/Semantics/resolve-directives.cpp    | 29 +++++++++-------
 flang/test/Lower/OpenMP/shared-loop.f90       | 33 +++++++++++++++++++
 .../Semantics/OpenMP/do05-positivecase.f90    |  2 +-
 flang/test/Semantics/OpenMP/do20.f90          |  2 +-
 flang/test/Semantics/OpenMP/implicit-dsa.f90  | 10 +++---
 flang/test/Semantics/OpenMP/symbol01.f90      |  2 +-
 flang/test/Semantics/OpenMP/symbol02.f90      |  4 +--
 flang/test/Semantics/OpenMP/symbol03.f90      |  4 +--
 flang/test/Semantics/OpenMP/symbol07.f90      |  2 +-
 flang/test/Semantics/OpenMP/symbol09.f90      |  2 +-
 11 files changed, 66 insertions(+), 27 deletions(-)
 create mode 100644 flang/test/Lower/OpenMP/shared-loop.f90

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 1f2724290b8852..4c3ce79b52048b 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1326,7 +1326,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
                                      bool isUnordered) {
     if (isUnordered || sym.has<Fortran::semantics::HostAssocDetails>() ||
         sym.has<Fortran::semantics::UseDetails>()) {
-      if (!shallowLookupSymbol(sym)) {
+      if (!shallowLookupSymbol(sym) &&
+          !sym.test(Fortran::semantics::Symbol::Flag::OmpShared)) {
         // Do concurrent loop variables are not mapped yet since they are local
         // to the Do concurrent scope (same for OpenMP loops).
         mlir::OpBuilder::InsertPoint insPt = builder->saveInsertionPoint();
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 17567a555db326..f6fef0f963c699 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2121,15 +2121,18 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       }
       return lastDeclSymbol;
     };
-    auto makeSharedSymbol = [&]() {
+    auto makeSharedSymbol = [&](bool setFlag) {
       const Symbol *hostSymbol =
           lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
-      MakeAssocSymbol(symbol->name(), *hostSymbol,
+      Symbol &assocSymbol = MakeAssocSymbol(symbol->name(), *hostSymbol,
           context_.FindScope(dirContext.directiveSource));
+      if (setFlag) {
+        assocSymbol.set(Symbol::Flag::OmpShared);
+      }
     };
-    auto useLastDeclSymbol = [&]() {
+    auto useLastDeclSymbol = [&](bool setFlag) {
       if (lastDeclSymbol) {
-        makeSharedSymbol();
+        makeSharedSymbol(setFlag);
       }
     };
 
@@ -2140,8 +2143,9 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
 
     if (dsa.has_value()) {
       if (dsa.value() == Symbol::Flag::OmpShared &&
-          (parallelDir || taskGenDir || teamsDir))
-        makeSharedSymbol();
+          (parallelDir || taskGenDir || teamsDir)) {
+        makeSharedSymbol(/*setFlag=*/true);
+      }
       // Private symbols will have been declared already.
       prevDSA = dsa;
       continue;
@@ -2153,18 +2157,19 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       // 1) default
       // Allowed only with parallel, teams and task generating constructs.
       assert(parallelDir || taskGenDir || teamsDir);
-      if (dirContext.defaultDSA != Symbol::Flag::OmpShared)
+      if (dirContext.defaultDSA != Symbol::Flag::OmpShared) {
         makePrivateSymbol(dirContext.defaultDSA);
-      else
-        makeSharedSymbol();
+      } else {
+        makeSharedSymbol(/*setFlag=*/true);
+      }
       dsa = dirContext.defaultDSA;
     } else if (parallelDir) {
       // 2) parallel -> shared
-      makeSharedSymbol();
+      makeSharedSymbol(/*setFlag=*/false);
       dsa = Symbol::Flag::OmpShared;
     } else if (!taskGenDir && !targetDir) {
       // 3) enclosing context
-      useLastDeclSymbol();
+      useLastDeclSymbol(/*setFlag=*/false);
       dsa = prevDSA;
     } else if (targetDir) {
       // TODO 4) not mapped target variable -> firstprivate
@@ -2173,7 +2178,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       // TODO 5) dummy arg in orphaned taskgen construct -> firstprivate
       if (prevDSA == Symbol::Flag::OmpShared) {
         // 6) shared in enclosing context -> shared
-        makeSharedSymbol();
+        makeSharedSymbol(/*setFlag=*/false);
         dsa = Symbol::Flag::OmpShared;
       } else {
         // 7) firstprivate
diff --git a/flang/test/Lower/OpenMP/shared-loop.f90 b/flang/test/Lower/OpenMP/shared-loop.f90
new file mode 100644
index 00000000000000..6ae37a896a3371
--- /dev/null
+++ b/flang/test/Lower/OpenMP/shared-loop.f90
@@ -0,0 +1,33 @@
+! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+! CHECK:  func.func @_QQmain() attributes
+! CHECK:    %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
+! CHECK:    %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFEi"} :
+! CHECK:    omp.parallel {
+! CHECK:      omp.sections {
+! CHECK:        omp.section {
+! CHECK:          %[[RES:.*]]:2 = fir.do_loop {{.*}} iter_args(%[[ARG:.*]] =
+! CHECK:            fir.store %[[ARG]] to %[[DECL_I]]#1
+! CHECK:            fir.result
+! CHECK:          }
+! CHECK:          fir.store %[[RES]]#1 to %[[DECL_I]]#1
+! CHECK:          omp.terminator
+! CHECK:        }
+! CHECK:        omp.terminator
+! CHECK:      }
+! CHECK:      return
+! CHECK:    }
+program omploop
+  implicit none
+  integer :: i, j
+  i = 1
+  j = 0
+  !$omp parallel shared(i)
+    !$omp sections
+      do i=1,10
+         j = j + i
+      end do
+    !$omp end sections
+  !$omp end parallel
+end program
diff --git a/flang/test/Semantics/OpenMP/do05-positivecase.f90 b/flang/test/Semantics/OpenMP/do05-positivecase.f90
index 3b512a5b4f25eb..f81140ddaf9fd9 100644
--- a/flang/test/Semantics/OpenMP/do05-positivecase.f90
+++ b/flang/test/Semantics/OpenMP/do05-positivecase.f90
@@ -20,7 +20,7 @@ program omp_do
   !$omp parallel  default(shared)
   !$omp do
   !DEF: /omp_do/OtherConstruct2/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
-  !DEF: /omp_do/OtherConstruct2/n HostAssoc INTEGER(4)
+  !DEF: /omp_do/OtherConstruct2/n (OmpShared) HostAssoc INTEGER(4)
   do i=1,n
     !$omp parallel
     !$omp single
diff --git a/flang/test/Semantics/OpenMP/do20.f90 b/flang/test/Semantics/OpenMP/do20.f90
index 0cafae76b86b00..040a82079590f0 100644
--- a/flang/test/Semantics/OpenMP/do20.f90
+++ b/flang/test/Semantics/OpenMP/do20.f90
@@ -10,7 +10,7 @@ subroutine shared_iv
 
   !$omp parallel shared(i)
     !$omp single
-      !DEF: /shared_iv/OtherConstruct1/i HostAssoc INTEGER(4)
+      !DEF: /shared_iv/OtherConstruct1/i (OmpShared) HostAssoc INTEGER(4)
       do i = 0, 1
       end do
     !$omp end single
diff --git a/flang/test/Semantics/OpenMP/implicit-dsa.f90 b/flang/test/Semantics/OpenMP/implicit-dsa.f90
index 2abe3a0e16d624..f73c19dbc61955 100644
--- a/flang/test/Semantics/OpenMP/implicit-dsa.f90
+++ b/flang/test/Semantics/OpenMP/implicit-dsa.f90
@@ -15,14 +15,14 @@ subroutine implicit_dsa_test1
   !$omp task private(y) shared(z)
     !DEF: /implicit_dsa_test1/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
     !DEF: /implicit_dsa_test1/OtherConstruct1/y (OmpPrivate) HostAssoc INTEGER(4)
-    !DEF: /implicit_dsa_test1/OtherConstruct1/z HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct1/z (OmpShared) HostAssoc INTEGER(4)
     x = y + z
   !$omp end task
 
   !$omp task default(shared)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/x HostAssoc INTEGER(4)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/y HostAssoc INTEGER(4)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/z HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/x (OmpShared) HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/y (OmpShared) HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/z (OmpShared) HostAssoc INTEGER(4)
     x = y + z
   !$omp end task
 
@@ -133,7 +133,7 @@ subroutine implicit_dsa_test6
     !$omp end parallel
 
     !$omp parallel default(firstprivate) shared(y)
-      !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/y HostAssoc INTEGER(4)
+      !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/y (OmpShared) HostAssoc INTEGER(4)
       !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/x (OmpFirstPrivate) HostAssocINTEGER(4)
       !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/z (OmpFirstPrivate) HostAssocINTEGER(4)
       y = x + z
diff --git a/flang/test/Semantics/OpenMP/symbol01.f90 b/flang/test/Semantics/OpenMP/symbol01.f90
index ecfb8622f81794..a40a8563fde1f8 100644
--- a/flang/test/Semantics/OpenMP/symbol01.f90
+++ b/flang/test/Semantics/OpenMP/symbol01.f90
@@ -62,7 +62,7 @@ program mm
   !REF: /mm/OtherConstruct1/i
   !REF: /mm/OtherConstruct1/y
   x = a+i+y
-  !DEF: /mm/OtherConstruct1/c HostAssoc REAL(4)
+  !DEF: /mm/OtherConstruct1/c (OmpShared) HostAssoc REAL(4)
   c = 3.0
  end do
 end program
diff --git a/flang/test/Semantics/OpenMP/symbol02.f90 b/flang/test/Semantics/OpenMP/symbol02.f90
index c199c526e1fa8c..31d9cb2e46ba8a 100644
--- a/flang/test/Semantics/OpenMP/symbol02.f90
+++ b/flang/test/Semantics/OpenMP/symbol02.f90
@@ -15,9 +15,9 @@
   a = 3.
   !DEF: /MainProgram1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4)
   b = 4
-  !DEF: /MainProgram1/OtherConstruct1/c HostAssoc REAL(4)
+  !DEF: /MainProgram1/OtherConstruct1/c (OmpShared) HostAssoc REAL(4)
   c = 5
-  !DEF: /MainProgram1/OtherConstruct1/d HostAssoc REAL(4)
+  !DEF: /MainProgram1/OtherConstruct1/d (OmpShared) HostAssoc REAL(4)
   d = 6
   !$omp end parallel
   !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
diff --git a/flang/test/Semantics/OpenMP/symbol03.f90 b/flang/test/Semantics/OpenMP/symbol03.f90
index ba941b9c9e7c4e..08defb40e56a71 100644
--- a/flang/test/Semantics/OpenMP/symbol03.f90
+++ b/flang/test/Semantics/OpenMP/symbol03.f90
@@ -9,10 +9,10 @@
   !$omp parallel  private(a) shared(b)
   !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
   a = 3.
-  !DEF: /MainProgram1/OtherConstruct1/b HostAssoc REAL(4)
+  !DEF: /MainProgram1/OtherConstruct1/b (OmpShared) HostAssoc REAL(4)
   b = 4
   !$omp parallel  private(b) shared(a)
-  !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/a HostAssoc REAL(4)
+  !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/a (OmpShared) HostAssoc REAL(4)
   a = 5.
   !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4)
   b = 6
diff --git a/flang/test/Semantics/OpenMP/symbol07.f90 b/flang/test/Semantics/OpenMP/symbol07.f90
index 8b4716999820b1..a375942ebb1d9a 100644
--- a/flang/test/Semantics/OpenMP/symbol07.f90
+++ b/flang/test/Semantics/OpenMP/symbol07.f90
@@ -23,7 +23,7 @@ subroutine function_call_in_region
   !$omp parallel  default(none) private(a) shared(b)
   !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
   !REF: /function_call_in_region/foo
-  !DEF: /function_call_in_region/OtherConstruct1/b HostAssoc REAL(4)
+  !DEF: /function_call_in_region/OtherConstruct1/b (OmpShared) HostAssoc REAL(4)
   a = foo(b)
   !$omp end parallel
   !REF: /function_call_in_region/a
diff --git a/flang/test/Semantics/OpenMP/symbol09.f90 b/flang/test/Semantics/OpenMP/symbol09.f90
index 8b4716999820b1..a375942ebb1d9a 100644
--- a/flang/test/Semantics/OpenMP/symbol09.f90
+++ b/flang/test/Semantics/OpenMP/symbol09.f90
@@ -23,7 +23,7 @@ subroutine function_call_in_region
   !$omp parallel  default(none) private(a) shared(b)
   !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
   !REF: /function_call_in_region/foo
-  !DEF: /function_call_in_region/OtherConstruct1/b HostAssoc REAL(4)
+  !DEF: /function_call_in_region/OtherConstruct1/b (OmpShared) HostAssoc REAL(4)
   a = foo(b)
   !$omp end parallel
   !REF: /function_call_in_region/a

>From 3695da1aecbeabc957739b5d5a017afe621c1aa2 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Wed, 11 Sep 2024 11:53:15 +0100
Subject: [PATCH 2/4] Add more test-lines

---
 flang/test/Lower/OpenMP/shared-loop.f90 | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/flang/test/Lower/OpenMP/shared-loop.f90 b/flang/test/Lower/OpenMP/shared-loop.f90
index 6ae37a896a3371..ebe368b53b5b95 100644
--- a/flang/test/Lower/OpenMP/shared-loop.f90
+++ b/flang/test/Lower/OpenMP/shared-loop.f90
@@ -9,7 +9,9 @@
 ! CHECK:        omp.section {
 ! CHECK:          %[[RES:.*]]:2 = fir.do_loop {{.*}} iter_args(%[[ARG:.*]] =
 ! CHECK:            fir.store %[[ARG]] to %[[DECL_I]]#1
-! CHECK:            fir.result
+! CHECK:            %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#1
+! CHECK:            %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
+! CHECK:            fir.result {{.*}}, %[[RES_I]]
 ! CHECK:          }
 ! CHECK:          fir.store %[[RES]]#1 to %[[DECL_I]]#1
 ! CHECK:          omp.terminator

>From 1e10c00813ce9f359f8e36afd2f77afdab03b61e Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Wed, 11 Sep 2024 14:10:01 +0100
Subject: [PATCH 3/4] Another few test-lines

---
 flang/test/Lower/OpenMP/shared-loop.f90 | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/flang/test/Lower/OpenMP/shared-loop.f90 b/flang/test/Lower/OpenMP/shared-loop.f90
index ebe368b53b5b95..aa6fac437151cb 100644
--- a/flang/test/Lower/OpenMP/shared-loop.f90
+++ b/flang/test/Lower/OpenMP/shared-loop.f90
@@ -7,11 +7,12 @@
 ! CHECK:    omp.parallel {
 ! CHECK:      omp.sections {
 ! CHECK:        omp.section {
-! CHECK:          %[[RES:.*]]:2 = fir.do_loop {{.*}} iter_args(%[[ARG:.*]] =
-! CHECK:            fir.store %[[ARG]] to %[[DECL_I]]#1
+! CHECK:          %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] = 
+! CHECK:            fir.store %[[ARG1]] to %[[DECL_I]]#1
+! CHECK:            %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
 ! CHECK:            %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#1
 ! CHECK:            %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
-! CHECK:            fir.result {{.*}}, %[[RES_I]]
+! CHECK:            fir.result %[[UPDATE_ITER]], %[[RES_I]]
 ! CHECK:          }
 ! CHECK:          fir.store %[[RES]]#1 to %[[DECL_I]]#1
 ! CHECK:          omp.terminator

>From 82ce4fdd2c541ad69a962b8ef192d224880fcbc9 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Thu, 12 Sep 2024 17:29:57 +0100
Subject: [PATCH 4/4] Update based on code-review

---
 flang/lib/Semantics/resolve-directives.cpp    | 20 ++--
 flang/test/Lower/OpenMP/shared-loop.f90       | 94 ++++++++++++++++++-
 .../Semantics/OpenMP/do05-positivecase.f90    |  2 +-
 flang/test/Semantics/OpenMP/implicit-dsa.f90  |  6 +-
 4 files changed, 103 insertions(+), 19 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index f6fef0f963c699..6ec6c2ea8da7fd 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2121,18 +2121,18 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       }
       return lastDeclSymbol;
     };
-    auto makeSharedSymbol = [&](bool setFlag) {
+    auto makeSharedSymbol = [&](std::optional<Symbol::Flag> flag = {}) {
       const Symbol *hostSymbol =
           lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
       Symbol &assocSymbol = MakeAssocSymbol(symbol->name(), *hostSymbol,
           context_.FindScope(dirContext.directiveSource));
-      if (setFlag) {
-        assocSymbol.set(Symbol::Flag::OmpShared);
+      if (flag) {
+        assocSymbol.set(*flag);
       }
     };
-    auto useLastDeclSymbol = [&](bool setFlag) {
+    auto useLastDeclSymbol = [&]() {
       if (lastDeclSymbol) {
-        makeSharedSymbol(setFlag);
+        makeSharedSymbol();
       }
     };
 
@@ -2144,7 +2144,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
     if (dsa.has_value()) {
       if (dsa.value() == Symbol::Flag::OmpShared &&
           (parallelDir || taskGenDir || teamsDir)) {
-        makeSharedSymbol(/*setFlag=*/true);
+        makeSharedSymbol(Symbol::Flag::OmpShared);
       }
       // Private symbols will have been declared already.
       prevDSA = dsa;
@@ -2160,16 +2160,16 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       if (dirContext.defaultDSA != Symbol::Flag::OmpShared) {
         makePrivateSymbol(dirContext.defaultDSA);
       } else {
-        makeSharedSymbol(/*setFlag=*/true);
+        makeSharedSymbol();
       }
       dsa = dirContext.defaultDSA;
     } else if (parallelDir) {
       // 2) parallel -> shared
-      makeSharedSymbol(/*setFlag=*/false);
+      makeSharedSymbol();
       dsa = Symbol::Flag::OmpShared;
     } else if (!taskGenDir && !targetDir) {
       // 3) enclosing context
-      useLastDeclSymbol(/*setFlag=*/false);
+      useLastDeclSymbol();
       dsa = prevDSA;
     } else if (targetDir) {
       // TODO 4) not mapped target variable -> firstprivate
@@ -2178,7 +2178,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       // TODO 5) dummy arg in orphaned taskgen construct -> firstprivate
       if (prevDSA == Symbol::Flag::OmpShared) {
         // 6) shared in enclosing context -> shared
-        makeSharedSymbol(/*setFlag=*/false);
+        makeSharedSymbol();
         dsa = Symbol::Flag::OmpShared;
       } else {
         // 7) firstprivate
diff --git a/flang/test/Lower/OpenMP/shared-loop.f90 b/flang/test/Lower/OpenMP/shared-loop.f90
index aa6fac437151cb..ac24db8c14c9e8 100644
--- a/flang/test/Lower/OpenMP/shared-loop.f90
+++ b/flang/test/Lower/OpenMP/shared-loop.f90
@@ -1,9 +1,11 @@
 ! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
 ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
 
-! CHECK:  func.func @_QQmain() attributes
-! CHECK:    %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
-! CHECK:    %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFEi"} :
+! --- Check that with shared(i) the variable outside the parallel section
+! --- is updated. 
+! CHECK:  func.func @_QPomploop()
+! CHECK:    %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploopEi"}
+! CHECK:    %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploopEi"} :
 ! CHECK:    omp.parallel {
 ! CHECK:      omp.sections {
 ! CHECK:        omp.section {
@@ -21,7 +23,7 @@
 ! CHECK:      }
 ! CHECK:      return
 ! CHECK:    }
-program omploop
+subroutine omploop
   implicit none
   integer :: i, j
   i = 1
@@ -33,4 +35,86 @@ program omploop
       end do
     !$omp end sections
   !$omp end parallel
-end program
+end subroutine
+
+! --- Check that with default(shared) the variable outside the parallel section
+! --- is NOT updated (i is private to the omp.parallel code)
+! CHECK:  func.func @_QPomploop2()
+! CHECK:    %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop2Ei"}
+! CHECK:    %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop2Ei"} :
+! CHECK:    omp.parallel {
+! CHECK:      %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
+! CHECK:      %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
+! CHECK:      omp.sections {
+! CHECK:        omp.section {
+! CHECK:          %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] = 
+! CHECK-NOT:            fir.store %[[ARG1]] to %[[DECL_I]]#1
+! CHECK:            fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#1
+! CHECK:            %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
+! CHECK:            %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#1
+! CHECK:            %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
+! CHECK:            fir.result %[[UPDATE_ITER]], %[[RES_I]]
+! CHECK:          }
+! CHECK:          fir.store %[[RES]]#1 to %[[DECL_PRIV_I]]#1
+! CHECK:          omp.terminator
+! CHECK:        }
+! CHECK:        omp.terminator
+! CHECK:      }
+! CHECK:      return
+! CHECK:    }
+subroutine omploop2
+  implicit none
+  integer :: i, j
+  i = 1
+  j = 0
+  !$omp parallel default(shared)
+    !$omp sections
+      do i=1,10
+         j = j + i
+      end do
+    !$omp end sections
+  !$omp end parallel
+end subroutine
+
+
+! --- Check that with no data-sharing the variable outside the parallel section
+! --- is NOT updated (i is private to the omp.parallel code)
+! CHECK:  func.func @_QPomploop3()
+! CHECK:    %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop3Ei"}
+! CHECK:    %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop3Ei"} :
+! CHECK:    omp.parallel {
+! CHECK:      %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
+! CHECK:      %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
+! CHECK:      omp.sections {
+! CHECK:        omp.section {
+! CHECK:          %[[RES:.*]]:2 = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] = 
+! CHECK-NOT:            fir.store %[[ARG1]] to %[[DECL_I]]#1
+! CHECK:            fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#1
+! CHECK:            %[[UPDATE_ITER:.*]] = arith.addi %[[ARG0]], %{{.*}}
+! CHECK:            %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#1
+! CHECK:            %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
+! CHECK:            fir.result %[[UPDATE_ITER]], %[[RES_I]]
+! CHECK:          }
+! CHECK:          fir.store %[[RES]]#1 to %[[DECL_PRIV_I]]#1
+! CHECK:          omp.terminator
+! CHECK:        }
+! CHECK:        omp.terminator
+! CHECK:      }
+! CHECK:      return
+! CHECK:    }
+subroutine omploop3
+  implicit none
+  integer :: i, j
+  i = 1
+  j = 0
+  !$omp parallel
+    !$omp sections
+      do i=1,10
+         j = j + i
+      end do
+    !$omp end sections
+  !$omp end parallel
+end subroutine
+
+
+ 
diff --git a/flang/test/Semantics/OpenMP/do05-positivecase.f90 b/flang/test/Semantics/OpenMP/do05-positivecase.f90
index f81140ddaf9fd9..3b512a5b4f25eb 100644
--- a/flang/test/Semantics/OpenMP/do05-positivecase.f90
+++ b/flang/test/Semantics/OpenMP/do05-positivecase.f90
@@ -20,7 +20,7 @@ program omp_do
   !$omp parallel  default(shared)
   !$omp do
   !DEF: /omp_do/OtherConstruct2/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
-  !DEF: /omp_do/OtherConstruct2/n (OmpShared) HostAssoc INTEGER(4)
+  !DEF: /omp_do/OtherConstruct2/n HostAssoc INTEGER(4)
   do i=1,n
     !$omp parallel
     !$omp single
diff --git a/flang/test/Semantics/OpenMP/implicit-dsa.f90 b/flang/test/Semantics/OpenMP/implicit-dsa.f90
index f73c19dbc61955..a7ed834b0f1c60 100644
--- a/flang/test/Semantics/OpenMP/implicit-dsa.f90
+++ b/flang/test/Semantics/OpenMP/implicit-dsa.f90
@@ -20,9 +20,9 @@ subroutine implicit_dsa_test1
   !$omp end task
 
   !$omp task default(shared)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/x (OmpShared) HostAssoc INTEGER(4)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/y (OmpShared) HostAssoc INTEGER(4)
-    !DEF: /implicit_dsa_test1/OtherConstruct2/z (OmpShared) HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/x HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/y HostAssoc INTEGER(4)
+    !DEF: /implicit_dsa_test1/OtherConstruct2/z HostAssoc INTEGER(4)
     x = y + z
   !$omp end task
 



More information about the flang-commits mailing list