Skip to content

[flang][OpenMP] Use function symbol on DECLARE TARGET #134107

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
merged 5 commits into from
Apr 2, 2025

Conversation

kparzysz
Copy link
Contributor

@kparzysz kparzysz commented Apr 2, 2025

Consider:

function foo()
  !$omp declare target(foo) ! This `foo` was a function-result symbol
  ...
end

When resolving symbols, for this case use the symbol corresponding to the function instead of the symbol corresponding to the function result.

Currently, this will result in an error:

error: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly

Consider:
```
function foo()
  !$omp declare target(foo) ! This `foo` was a function-return symbol
  ...
end
```
When resolving symbols, for this case use the symbol corresponding to
the function instead of the symbol corresponding to the function result.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp flang:semantics labels Apr 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 2, 2025

@llvm/pr-subscribers-flang-semantics

@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)

Changes

Consider:

function foo()
  !$omp declare target(foo) ! This `foo` was a function-return symbol
  ...
end

When resolving symbols, for this case use the symbol corresponding to the function instead of the symbol corresponding to the function result.

Currently, this will result in an error:

error: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly

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

4 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+10)
  • (modified) flang/lib/Semantics/unparse-with-symbols.cpp (+8)
  • (modified) flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 (+7)
  • (added) flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 (+34)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index f905da0a7239d..4ce43e32f4447 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2514,6 +2514,16 @@ void OmpAttributeVisitor::ResolveOmpObject(
                         name->ToString());
                   }
                 }
+                if (ompFlag == Symbol::Flag::OmpDeclareTarget) {
+                  if (symbol->IsFuncResult()) {
+                    if (Scope *container{&currScope()}) {
+                      if (Symbol *func{container->symbol()}) {
+                        func->set(ompFlag);
+                        name->symbol = func;
+                      }
+                    }
+                  }
+                }
                 if (GetContext().directive ==
                     llvm::omp::Directive::OMPD_target_data) {
                   checkExclusivelists(symbol, Symbol::Flag::OmpUseDevicePtr,
diff --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp
index 02afb89ae57fa..2716d88efb9fb 100644
--- a/flang/lib/Semantics/unparse-with-symbols.cpp
+++ b/flang/lib/Semantics/unparse-with-symbols.cpp
@@ -61,6 +61,14 @@ class SymbolDumpVisitor {
     currStmt_ = std::nullopt;
   }
 
+  bool Pre(const parser::OpenMPDeclareTargetConstruct &x) {
+    currStmt_ = x.source;
+    return true;
+  }
+  void Post(const parser::OpenMPDeclareTargetConstruct &) {
+    currStmt_ = std::nullopt;
+  }
+
 private:
   std::optional<SourceName> currStmt_; // current statement we are processing
   std::multimap<const char *, const Symbol *> symbols_; // location to symbol
diff --git a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
index db8320a598052..1c43f1d09eddb 100644
--- a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
+++ b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
@@ -85,6 +85,13 @@ FUNCTION FUNC_DEFAULT_EXTENDEDLIST() RESULT(I)
     I = 1
 END FUNCTION FUNC_DEFAULT_EXTENDEDLIST
 
+! ALL-LABEL: func.func @_QPfunc_name_as_result()
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
+FUNCTION FUNC_NAME_AS_RESULT()
+!$omp declare target(FUNC_NAME_AS_RESULT)
+  FUNC_NAME_AS_RESULT = 1.0
+END FUNCTION FUNC_NAME_AS_RESULT
+
 !! -----
 
 ! Check specification valid forms of declare target with subroutines 
diff --git a/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
new file mode 100644
index 0000000000000..9a0acdb3dd100
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
@@ -0,0 +1,34 @@
+!RUN: %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s
+
+! This used to crash.
+
+module test
+  contains
+  function ex(a, b, c)
+    !$omp declare target(ex)
+    integer :: a, b, c
+    ex = a + b + c
+  end function ex
+end module test
+
+!CHECK: !DEF: /test Module
+!CHECK: module test
+!CHECK: contains
+!CHECK:  !DEF: /test/ex PUBLIC (Function, OmpDeclareTarget) Subprogram REAL(4)
+!CHECK:  !DEF: /test/ex/a ObjectEntity INTEGER(4)
+!CHECK:  !DEF: /test/ex/b ObjectEntity INTEGER(4)
+!CHECK:  !DEF: /test/ex/c ObjectEntity INTEGER(4)
+!CHECK:  function ex(a, b, c)
+!CHECK: !$omp declare target (ex)
+!CHECK:   !REF: /test/ex/a
+!CHECK:   !REF: /test/ex/b
+!CHECK:   !REF: /test/ex/c
+!CHECK:   integer a, b, c
+!CHECK:   !DEF: /test/ex/ex (Implicit, OmpDeclareTarget) ObjectEntity REAL(4)
+!CHECK:   !REF: /test/ex/a
+!CHECK:   !REF: /test/ex/b
+!CHECK:   !REF: /test/ex/c
+!CHECK:   ex = a+b+c
+!CHECK:  end function ex
+!CHECK: end module test
+

@llvmbot
Copy link
Member

llvmbot commented Apr 2, 2025

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

Author: Krzysztof Parzyszek (kparzysz)

Changes

Consider:

function foo()
  !$omp declare target(foo) ! This `foo` was a function-return symbol
  ...
end

When resolving symbols, for this case use the symbol corresponding to the function instead of the symbol corresponding to the function result.

Currently, this will result in an error:

error: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly

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

4 Files Affected:

  • (modified) flang/lib/Semantics/resolve-directives.cpp (+10)
  • (modified) flang/lib/Semantics/unparse-with-symbols.cpp (+8)
  • (modified) flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 (+7)
  • (added) flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 (+34)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index f905da0a7239d..4ce43e32f4447 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2514,6 +2514,16 @@ void OmpAttributeVisitor::ResolveOmpObject(
                         name->ToString());
                   }
                 }
+                if (ompFlag == Symbol::Flag::OmpDeclareTarget) {
+                  if (symbol->IsFuncResult()) {
+                    if (Scope *container{&currScope()}) {
+                      if (Symbol *func{container->symbol()}) {
+                        func->set(ompFlag);
+                        name->symbol = func;
+                      }
+                    }
+                  }
+                }
                 if (GetContext().directive ==
                     llvm::omp::Directive::OMPD_target_data) {
                   checkExclusivelists(symbol, Symbol::Flag::OmpUseDevicePtr,
diff --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp
index 02afb89ae57fa..2716d88efb9fb 100644
--- a/flang/lib/Semantics/unparse-with-symbols.cpp
+++ b/flang/lib/Semantics/unparse-with-symbols.cpp
@@ -61,6 +61,14 @@ class SymbolDumpVisitor {
     currStmt_ = std::nullopt;
   }
 
+  bool Pre(const parser::OpenMPDeclareTargetConstruct &x) {
+    currStmt_ = x.source;
+    return true;
+  }
+  void Post(const parser::OpenMPDeclareTargetConstruct &) {
+    currStmt_ = std::nullopt;
+  }
+
 private:
   std::optional<SourceName> currStmt_; // current statement we are processing
   std::multimap<const char *, const Symbol *> symbols_; // location to symbol
diff --git a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
index db8320a598052..1c43f1d09eddb 100644
--- a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
+++ b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
@@ -85,6 +85,13 @@ FUNCTION FUNC_DEFAULT_EXTENDEDLIST() RESULT(I)
     I = 1
 END FUNCTION FUNC_DEFAULT_EXTENDEDLIST
 
+! ALL-LABEL: func.func @_QPfunc_name_as_result()
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
+FUNCTION FUNC_NAME_AS_RESULT()
+!$omp declare target(FUNC_NAME_AS_RESULT)
+  FUNC_NAME_AS_RESULT = 1.0
+END FUNCTION FUNC_NAME_AS_RESULT
+
 !! -----
 
 ! Check specification valid forms of declare target with subroutines 
diff --git a/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
new file mode 100644
index 0000000000000..9a0acdb3dd100
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90
@@ -0,0 +1,34 @@
+!RUN: %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s
+
+! This used to crash.
+
+module test
+  contains
+  function ex(a, b, c)
+    !$omp declare target(ex)
+    integer :: a, b, c
+    ex = a + b + c
+  end function ex
+end module test
+
+!CHECK: !DEF: /test Module
+!CHECK: module test
+!CHECK: contains
+!CHECK:  !DEF: /test/ex PUBLIC (Function, OmpDeclareTarget) Subprogram REAL(4)
+!CHECK:  !DEF: /test/ex/a ObjectEntity INTEGER(4)
+!CHECK:  !DEF: /test/ex/b ObjectEntity INTEGER(4)
+!CHECK:  !DEF: /test/ex/c ObjectEntity INTEGER(4)
+!CHECK:  function ex(a, b, c)
+!CHECK: !$omp declare target (ex)
+!CHECK:   !REF: /test/ex/a
+!CHECK:   !REF: /test/ex/b
+!CHECK:   !REF: /test/ex/c
+!CHECK:   integer a, b, c
+!CHECK:   !DEF: /test/ex/ex (Implicit, OmpDeclareTarget) ObjectEntity REAL(4)
+!CHECK:   !REF: /test/ex/a
+!CHECK:   !REF: /test/ex/b
+!CHECK:   !REF: /test/ex/c
+!CHECK:   ex = a+b+c
+!CHECK:  end function ex
+!CHECK: end module test
+

Copy link

github-actions bot commented Apr 2, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

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.

Comment on lines 2520 to 2521
assert(
func->IsSubprogram() && "Expecting function scope");
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: There is a CHECK macro that is commonly used in frontend code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

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

LGTM

@kparzysz kparzysz merged commit 564e04b into llvm:main Apr 2, 2025
11 checks passed
@kparzysz kparzysz deleted the users/kparzysz/declare-target-function branch April 2, 2025 20:16
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Jun 12, 2025
Consider:
```
function foo()
  !$omp declare target(foo) ! This `foo` was a function-result symbol
  ...
end
```
When resolving symbols, for this case use the symbol corresponding to
the function instead of the symbol corresponding to the function result.

Currently, this will result in an error:
```
error: A variable that appears in a DECLARE TARGET directive must be
declared in the scope of a module or have the SAVE attribute, either
explicitly or implicitly
```
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Jun 12, 2025
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.

4 participants