-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
[flang][OpenMP] Use function symbol on DECLARE TARGET #134107
Conversation
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.
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-openmp Author: Krzysztof Parzyszek (kparzysz) ChangesConsider:
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:
Full diff: https://github.com/llvm/llvm-project/pull/134107.diff 4 Files Affected:
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
+
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Krzysztof Parzyszek (kparzysz) ChangesConsider:
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:
Full diff: https://github.com/llvm/llvm-project/pull/134107.diff 4 Files Affected:
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
+
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG.
assert( | ||
func->IsSubprogram() && "Expecting function scope"); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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:
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: