Skip to content

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
Member

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
Member

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
@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