Skip to content
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

[flang][openacc] Correctly lower acc routine in interface block #71451

Merged
merged 1 commit into from
Nov 7, 2023

Conversation

clementval
Copy link
Contributor

When the acc routine directive was in an interface block in a subroutine, the routine information was attached to the wrong subroutine. This patch fixes this be retrieving the subroutine name in the interface.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir openacc labels Nov 6, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 6, 2023

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

Author: Valentin Clement (バレンタイン クレメン) (clementval)

Changes

When the acc routine directive was in an interface block in a subroutine, the routine information was attached to the wrong subroutine. This patch fixes this be retrieving the subroutine name in the interface.


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

2 Files Affected:

  • (modified) flang/lib/Lower/OpenACC.cpp (+15-2)
  • (added) flang/test/Lower/OpenACC/acc-routine03.f90 (+36)
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 809fd3b3be7cfdf..bc90dc2ab724590 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3201,8 +3201,21 @@ void Fortran::lower::genOpenACCRoutineConstruct(
     funcName = converter.mangleName(*name->symbol);
     funcOp = builder.getNamedFunction(mod, funcName);
   } else {
-    funcOp = builder.getFunction();
-    funcName = funcOp.getName();
+    Fortran::semantics::Scope &scope =
+        semanticsContext.FindScope(routineConstruct.source);
+    const Fortran::semantics::Scope &progUnit{GetProgramUnitContaining(scope)};
+    const auto *subpDetails{
+        progUnit.symbol()
+            ? progUnit.symbol()
+                  ->detailsIf<Fortran::semantics::SubprogramDetails>()
+            : nullptr};
+    if (subpDetails && subpDetails->isInterface()) {
+      funcName = converter.mangleName(*progUnit.symbol());
+      funcOp = builder.getNamedFunction(mod, funcName);
+    } else {
+      funcOp = builder.getFunction();
+      funcName = funcOp.getName();
+    }
   }
   bool hasSeq = false, hasGang = false, hasWorker = false, hasVector = false,
        hasNohost = false;
diff --git a/flang/test/Lower/OpenACC/acc-routine03.f90 b/flang/test/Lower/OpenACC/acc-routine03.f90
new file mode 100644
index 000000000000000..9b64482e312a2d3
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-routine03.f90
@@ -0,0 +1,36 @@
+! This test checks lowering of OpenACC routine directive in interfaces.
+
+! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+
+
+subroutine sub1(a)
+  !$acc routine worker bind(sub2)
+  real :: a(:)
+end subroutine
+
+subroutine sub2(a)
+  !$acc routine worker nohost
+  real :: a(:)
+end subroutine
+
+subroutine test
+
+interface
+  subroutine sub1(a)
+    !$acc routine worker bind(sub2)
+    real :: a(:)
+  end subroutine
+ 
+  subroutine sub2(a)
+    !$acc routine worker nohost
+    real :: a(:)
+  end subroutine
+end interface
+
+end subroutine
+
+! CHECK: acc.routine @acc_routine_1 func(@_QPsub2) worker nohost
+! CHECK: acc.routine @acc_routine_0 func(@_QPsub1) bind("_QPsub2") worker
+! CHECK: func.func @_QPsub1(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_0]>}
+! CHECK: func.func @_QPsub2(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_1]>}

@llvmbot
Copy link
Collaborator

llvmbot commented Nov 6, 2023

@llvm/pr-subscribers-openacc

Author: Valentin Clement (バレンタイン クレメン) (clementval)

Changes

When the acc routine directive was in an interface block in a subroutine, the routine information was attached to the wrong subroutine. This patch fixes this be retrieving the subroutine name in the interface.


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

2 Files Affected:

  • (modified) flang/lib/Lower/OpenACC.cpp (+15-2)
  • (added) flang/test/Lower/OpenACC/acc-routine03.f90 (+36)
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 809fd3b3be7cfdf..bc90dc2ab724590 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -3201,8 +3201,21 @@ void Fortran::lower::genOpenACCRoutineConstruct(
     funcName = converter.mangleName(*name->symbol);
     funcOp = builder.getNamedFunction(mod, funcName);
   } else {
-    funcOp = builder.getFunction();
-    funcName = funcOp.getName();
+    Fortran::semantics::Scope &scope =
+        semanticsContext.FindScope(routineConstruct.source);
+    const Fortran::semantics::Scope &progUnit{GetProgramUnitContaining(scope)};
+    const auto *subpDetails{
+        progUnit.symbol()
+            ? progUnit.symbol()
+                  ->detailsIf<Fortran::semantics::SubprogramDetails>()
+            : nullptr};
+    if (subpDetails && subpDetails->isInterface()) {
+      funcName = converter.mangleName(*progUnit.symbol());
+      funcOp = builder.getNamedFunction(mod, funcName);
+    } else {
+      funcOp = builder.getFunction();
+      funcName = funcOp.getName();
+    }
   }
   bool hasSeq = false, hasGang = false, hasWorker = false, hasVector = false,
        hasNohost = false;
diff --git a/flang/test/Lower/OpenACC/acc-routine03.f90 b/flang/test/Lower/OpenACC/acc-routine03.f90
new file mode 100644
index 000000000000000..9b64482e312a2d3
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-routine03.f90
@@ -0,0 +1,36 @@
+! This test checks lowering of OpenACC routine directive in interfaces.
+
+! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+
+
+subroutine sub1(a)
+  !$acc routine worker bind(sub2)
+  real :: a(:)
+end subroutine
+
+subroutine sub2(a)
+  !$acc routine worker nohost
+  real :: a(:)
+end subroutine
+
+subroutine test
+
+interface
+  subroutine sub1(a)
+    !$acc routine worker bind(sub2)
+    real :: a(:)
+  end subroutine
+ 
+  subroutine sub2(a)
+    !$acc routine worker nohost
+    real :: a(:)
+  end subroutine
+end interface
+
+end subroutine
+
+! CHECK: acc.routine @acc_routine_1 func(@_QPsub2) worker nohost
+! CHECK: acc.routine @acc_routine_0 func(@_QPsub1) bind("_QPsub2") worker
+! CHECK: func.func @_QPsub1(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_0]>}
+! CHECK: func.func @_QPsub2(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"}) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_1]>}

Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

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

Thank you!

@clementval clementval merged commit edfaae8 into llvm:main Nov 7, 2023
6 checks passed
@clementval clementval deleted the acc_routine_in_interface branch November 7, 2023 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category openacc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants