[flang-commits] [flang] [Flang] [Semantics] [OpenMP] Added missing semantic check with nested target region. (PR #115344)

Raghu Maddhipatla via flang-commits flang-commits at lists.llvm.org
Wed Nov 20 08:51:09 PST 2024


https://github.com/raghavendhra updated https://github.com/llvm/llvm-project/pull/115344

>From 17944a983b11d79871403d08ed7b80c4a2c3064d Mon Sep 17 00:00:00 2001
From: Raghu Maddhipatla <Raghu.Maddhipatla at amd.com>
Date: Thu, 7 Nov 2024 10:50:42 -0600
Subject: [PATCH 1/2] [Flang] [Semantics] [OpenMP] Added missing semantic check
 with nested target region.

---
 flang/lib/Semantics/check-omp-structure.cpp   | 17 ++++++++++++++++-
 flang/test/Semantics/OpenMP/nested-simd.f90   |  1 +
 flang/test/Semantics/OpenMP/nested-target.f90 | 15 ++++++++++++++-
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 0b64a4a9801ccd..fbacd60ff64693 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -824,7 +824,8 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
                 std::get<parser::OmpBeginBlockDirective>(c.t)};
             const auto &beginDir{
                 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-            if (beginDir.v == llvm::omp::Directive::OMPD_target_data) {
+            if (beginDir.v == llvm::omp::Directive::OMPD_target_data ||
+                llvm::omp::allTargetSet.test(beginDir.v)) {
               eligibleTarget = false;
               ineligibleTargetDir = beginDir.v;
             }
@@ -1074,6 +1075,20 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     if (llvm::omp::topTeamsSet.test(GetContextParent().directive)) {
       HasInvalidTeamsNesting(beginDir.v, beginDir.source);
     }
+    if ((llvm::omp::allTargetSet.test(GetContext().directive) ||
+            (GetContext().directive ==
+                llvm::omp::Directive::OMPD_target_data)) &&
+        (llvm::omp::allTargetSet.test(GetContextParent().directive) ||
+            (GetContextParent().directive ==
+                llvm::omp::Directive::OMPD_target_data))) {
+      context_.Warn(common::UsageWarning::OpenMPUsage,
+          parser::FindSourceLocation(x),
+          "If %s directive is nested inside %s region, the behaviour is unspecified"_port_en_US,
+          parser::ToUpperCaseLetters(
+              getDirectiveName(GetContext().directive).str()),
+          parser::ToUpperCaseLetters(
+              getDirectiveName(GetContextParent().directive).str()));
+    }
     if (GetContext().directive == llvm::omp::Directive::OMPD_master) {
       CheckMasterNesting(x);
     }
diff --git a/flang/test/Semantics/OpenMP/nested-simd.f90 b/flang/test/Semantics/OpenMP/nested-simd.f90
index c9fb90cdeceb25..b182f961b877f2 100644
--- a/flang/test/Semantics/OpenMP/nested-simd.f90
+++ b/flang/test/Semantics/OpenMP/nested-simd.f90
@@ -166,6 +166,7 @@ SUBROUTINE NESTED_BAD(N)
       end do
       !$omp end task
       !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
+      !ERROR: If TARGET directive is nested inside TARGET SIMD region, the behaviour is unspecified
       !$omp target 
       do J = 1, N
         K = 2
diff --git a/flang/test/Semantics/OpenMP/nested-target.f90 b/flang/test/Semantics/OpenMP/nested-target.f90
index 2267f70715d3ed..b054292ef54d58 100644
--- a/flang/test/Semantics/OpenMP/nested-target.f90
+++ b/flang/test/Semantics/OpenMP/nested-target.f90
@@ -5,7 +5,7 @@
 ! 2.12.5 Target Construct
 
 program main
-  integer :: i, j, N = 10
+  integer :: i, j, N = 10, n1, n2, res(100)
   real :: a, arrayA(512), arrayB(512), ai(10)
   real, allocatable :: B(:)
 
@@ -50,4 +50,17 @@ program main
   !$omp end target
   deallocate(B)
 
+  n1 = 10
+  n2 = 10
+  !$omp target teams map(to:a)
+  !PORTABILITY: If TARGET DATA directive is nested inside TARGET TEAMS region, the behaviour is unspecified
+  !$omp target data map(n1,n2)
+  do i=1, n1
+     do j=1, n2
+      res((i-1)*10+j) = i*j
+     end do
+  end do
+  !$omp end target data
+  !$omp end target teams
+
 end program main

>From 9ad3e839980f7e93330279fcec3648aa9bb81160 Mon Sep 17 00:00:00 2001
From: Raghu Maddhipatla <Raghu.Maddhipatla at amd.com>
Date: Wed, 20 Nov 2024 10:41:19 -0600
Subject: [PATCH 2/2] Address review comments and rebase.

---
 flang/lib/Semantics/check-omp-structure.cpp   | 33 ++++++++-----------
 flang/test/Semantics/OpenMP/nested-simd.f90   |  1 -
 flang/test/Semantics/OpenMP/nested-target.f90 |  2 +-
 3 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index fbacd60ff64693..10a56e932681b8 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -824,8 +824,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
                 std::get<parser::OmpBeginBlockDirective>(c.t)};
             const auto &beginDir{
                 std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
-            if (beginDir.v == llvm::omp::Directive::OMPD_target_data ||
-                llvm::omp::allTargetSet.test(beginDir.v)) {
+            if (beginDir.v == llvm::omp::Directive::OMPD_target_data) {
               eligibleTarget = false;
               ineligibleTargetDir = beginDir.v;
             }
@@ -849,11 +848,21 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
                 },
                 c.u);
           },
+          [&](const parser::OpenMPLoopConstruct &c) {
+            const auto &beginLoopDir{
+                std::get<parser::OmpBeginLoopDirective>(c.t)};
+            const auto &beginDir{
+                std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
+            if (llvm::omp::allTargetSet.test(beginDir.v)) {
+              eligibleTarget = false;
+              ineligibleTargetDir = beginDir.v;
+            }
+          },
           [&](const auto &c) {},
       },
       c.u);
   if (!eligibleTarget) {
-    context_.Warn(common::UsageWarning::Portability,
+    context_.Warn(common::UsageWarning::OpenMPUsage,
         parser::FindSourceLocation(c),
         "If %s directive is nested inside TARGET region, the behaviour is unspecified"_port_en_US,
         parser::ToUpperCaseLetters(
@@ -1067,7 +1076,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
   CheckMatching<parser::OmpBlockDirective>(beginDir, endDir);
 
   PushContextAndClauseSets(beginDir.source, beginDir.v);
-  if (GetContext().directive == llvm::omp::Directive::OMPD_target) {
+  if (llvm::omp::allTargetSet.test(GetContext().directive)) {
     EnterDirectiveNest(TargetNest);
   }
 
@@ -1075,20 +1084,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
     if (llvm::omp::topTeamsSet.test(GetContextParent().directive)) {
       HasInvalidTeamsNesting(beginDir.v, beginDir.source);
     }
-    if ((llvm::omp::allTargetSet.test(GetContext().directive) ||
-            (GetContext().directive ==
-                llvm::omp::Directive::OMPD_target_data)) &&
-        (llvm::omp::allTargetSet.test(GetContextParent().directive) ||
-            (GetContextParent().directive ==
-                llvm::omp::Directive::OMPD_target_data))) {
-      context_.Warn(common::UsageWarning::OpenMPUsage,
-          parser::FindSourceLocation(x),
-          "If %s directive is nested inside %s region, the behaviour is unspecified"_port_en_US,
-          parser::ToUpperCaseLetters(
-              getDirectiveName(GetContext().directive).str()),
-          parser::ToUpperCaseLetters(
-              getDirectiveName(GetContextParent().directive).str()));
-    }
     if (GetContext().directive == llvm::omp::Directive::OMPD_master) {
       CheckMasterNesting(x);
     }
@@ -1164,7 +1159,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
   if (GetDirectiveNest(TargetBlockOnlyTeams)) {
     ExitDirectiveNest(TargetBlockOnlyTeams);
   }
-  if (GetContext().directive == llvm::omp::Directive::OMPD_target) {
+  if (llvm::omp::allTargetSet.test(GetContext().directive)) {
     ExitDirectiveNest(TargetNest);
   }
   dirContext_.pop_back();
diff --git a/flang/test/Semantics/OpenMP/nested-simd.f90 b/flang/test/Semantics/OpenMP/nested-simd.f90
index b182f961b877f2..c9fb90cdeceb25 100644
--- a/flang/test/Semantics/OpenMP/nested-simd.f90
+++ b/flang/test/Semantics/OpenMP/nested-simd.f90
@@ -166,7 +166,6 @@ SUBROUTINE NESTED_BAD(N)
       end do
       !$omp end task
       !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct, the `SCAN` construct and the `ORDERED` construct with the `SIMD` clause.
-      !ERROR: If TARGET directive is nested inside TARGET SIMD region, the behaviour is unspecified
       !$omp target 
       do J = 1, N
         K = 2
diff --git a/flang/test/Semantics/OpenMP/nested-target.f90 b/flang/test/Semantics/OpenMP/nested-target.f90
index b054292ef54d58..18986b7196e33a 100644
--- a/flang/test/Semantics/OpenMP/nested-target.f90
+++ b/flang/test/Semantics/OpenMP/nested-target.f90
@@ -53,7 +53,7 @@ program main
   n1 = 10
   n2 = 10
   !$omp target teams map(to:a)
-  !PORTABILITY: If TARGET DATA directive is nested inside TARGET TEAMS region, the behaviour is unspecified
+  !PORTABILITY: If TARGET DATA directive is nested inside TARGET region, the behaviour is unspecified
   !$omp target data map(n1,n2)
   do i=1, n1
      do j=1, n2



More information about the flang-commits mailing list