[flang-commits] [flang] [flang][acc] Accept component reference in non-global `acc declare` (PR #192563)
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 16 15:51:33 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-openacc
Author: Razvan Lupusoru (razvanlupusoru)
<details>
<summary>Changes</summary>
The current TODO was being issued for all cases of `acc declare` including ones which are treated as a subroutine-scope lifetime. Since the latter use normal data mapping clauses without the need for ctors/dtors, accept them. However, still emit TODO for the cases where component references are `acc declare`d in global context.
---
Full diff: https://github.com/llvm/llvm-project/pull/192563.diff
3 Files Affected:
- (modified) flang/lib/Lower/OpenACC.cpp (+17-8)
- (added) flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90 (+50)
- (modified) flang/test/Lower/OpenACC/acc-declare.f90 (+17)
``````````diff
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 5a7fe899b372f..f2caef9e90365 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -970,14 +970,6 @@ static void genDeclareDataOperandOperations(
Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
[&](auto &&s) { return ea.Analyze(s); }, accObject.u);
- if (designator) {
- Fortran::semantics::SomeExpr someExpr = *designator;
- if (Fortran::lower::detail::getRef<Fortran::evaluate::Component>(
- someExpr)) {
- TODO(operandLocation,
- "OpenACC declare with component reference not yet supported");
- }
- }
fir::factory::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -3822,6 +3814,23 @@ static void genGlobalCtors(Fortran::lower::AbstractConverter &converter,
if (const auto *name =
Fortran::parser::GetDesignatorNameIfDataRef(designator)) {
genCtors(operandLocation, *name->symbol);
+ } else if (const auto *dr = std::get_if<Fortran::parser::DataRef>(
+ &designator.u);
+ dr &&
+ std::holds_alternative<Fortran::common::Indirection<
+ Fortran::parser::StructureComponent>>(dr->u)) {
+ const Fortran::semantics::Scope &scope =
+ converter.getCurrentScope();
+ if (scope.IsModule() || scope.IsSubmodule()) {
+ TODO(operandLocation,
+ "OpenACC declare does not support a component reference "
+ "in a module; `acc declare` the whole variable instead");
+ } else {
+ TODO(operandLocation,
+ "OpenACC declare does not support a component reference "
+ "in this declaration context; `acc declare` the whole "
+ "variable instead");
+ }
}
},
[&](const Fortran::parser::Name &name) {
diff --git a/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90 b/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90
new file mode 100644
index 0000000000000..7285e18726629
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-declare-global-component-not-supported.f90
@@ -0,0 +1,50 @@
+! Lowering of !$acc declare rejects a component reference in a module
+! declaration section
+
+! RUN: split-file %s %t
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_create_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-MOD
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_copyin_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-MOD
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_device_resident_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-MOD
+! RUN: not bbc -fopenacc -emit-hlfir %t/declare_module_link_component_only.f90 -o - 2>&1 | FileCheck %s --check-prefixes=ERR-MOD
+
+! ERR-MOD: not yet implemented: OpenACC declare does not support a component reference in a module; `acc declare` the whole variable instead
+
+//--- declare_module_create_component_only.f90
+
+module test_decl_mod_create
+ type :: record_with_array
+ real :: vals(8)
+ end type
+ type(record_with_array) :: obj
+ !$acc declare create(obj%vals)
+end module
+
+//--- declare_module_copyin_component_only.f90
+
+module test_decl_mod_copyin
+ type :: record_with_array
+ real :: vals(8)
+ end type
+ type(record_with_array) :: obj
+ !$acc declare copyin(obj%vals)
+end module
+
+//--- declare_module_device_resident_component_only.f90
+
+module test_decl_mod_device_resident
+ type :: record_with_array
+ real :: vals(8)
+ end type
+ type(record_with_array) :: obj
+ !$acc declare device_resident(obj%vals)
+end module
+
+//--- declare_module_link_component_only.f90
+
+module test_decl_mod_link
+ type :: record_with_array
+ real :: vals(8)
+ end type
+ type(record_with_array) :: obj
+ !$acc declare link(obj%vals)
+end module
diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90
index b0d987255076b..206a690e3c951 100644
--- a/flang/test/Lower/OpenACC/acc-declare.f90
+++ b/flang/test/Lower/OpenACC/acc-declare.f90
@@ -64,6 +64,23 @@ subroutine acc_declare_present(a)
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[PRESENT]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.delete accPtr(%[[PRESENT]] : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_present>, name = "a"}
+ subroutine acc_declare_present_host_and_comp(host, coeffs)
+ type :: dt_box
+ real :: buf(10, 2)
+ end type
+ type(dt_box), intent(in) :: host
+ real, intent(in) :: coeffs(10)
+ !$acc declare present(host, host%buf, coeffs)
+ end subroutine
+
+! CHECK-LABEL: func.func @_QMacc_declarePacc_declare_present_host_and_comp(
+! CHECK-SAME: %[[ARGHOST:.*]]: !fir.ref<!fir.type<_QMacc_declare{{.*}}Tdt_box{{.*}}>> {fir.bindc_name = "host"},
+! CHECK-SAME: %[[ARGCOEFF:.*]]: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "coeffs"})
+! CHECK-DAG: acc.present{{.*}}name = "host"
+! CHECK-DAG: acc.present{{.*}}name = "host%buf"
+! CHECK-DAG: acc.present{{.*}}name = "coeffs"
+! CHECK: acc.declare_enter dataOperands(%{{.*}}, %{{.*}}, %{{.*}} :
+
subroutine acc_declare_copyin()
integer :: a(100), b(10), i
!$acc declare copyin(a) copyin(readonly: b)
``````````
</details>
https://github.com/llvm/llvm-project/pull/192563
More information about the flang-commits
mailing list