Index: flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp =================================================================== --- flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp +++ flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -312,12 +312,20 @@ if (auto attrs = declareOp.getFortranAttrs()) fortranAttrs = fir::FortranVariableFlagsAttr::get(rewriter.getContext(), *attrs); - auto firBase = rewriter - .create( - loc, memref.getType(), memref, declareOp.getShape(), - declareOp.getTypeparams(), declareOp.getUniqName(), - fortranAttrs) - .getResult(); + auto firDeclareOp = rewriter.create( + loc, memref.getType(), memref, declareOp.getShape(), + declareOp.getTypeparams(), declareOp.getUniqName(), fortranAttrs); + + // Propagate other attributes from hlfir.declare to fir.declare. + // OpenACC's acc.declare is one example. Right now, the propagation + // is verbatim. + mlir::NamedAttrList elidedAttrs = + mlir::NamedAttrList{firDeclareOp->getAttrs()}; + for (const mlir::NamedAttribute &attr : declareOp->getAttrs()) + if (!elidedAttrs.get(attr.getName())) + firDeclareOp->setAttr(attr.getName(), attr.getValue()); + + auto firBase = firDeclareOp.getResult(); mlir::Value hlfirBase; mlir::Type hlfirBaseType = declareOp.getBase().getType(); if (hlfirBaseType.isa()) { Index: flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 =================================================================== --- /dev/null +++ flang/test/Lower/OpenACC/HLFIR/acc-declare.f90 @@ -0,0 +1,332 @@ +! This test checks lowering of OpenACC declare directive. + +! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=HLFIR,ALL +! RUN: bbc -fopenacc -emit-fir -hlfir %s -o - | FileCheck %s --check-prefixes=FIR,ALL + +module acc_declare_test + integer, parameter :: n = 100000 + real, dimension(n) :: data1 + !$acc declare create(data1) +end module + +! ALL-LABEL: fir.global @_QMacc_declare_testEdata1 {acc.declare = #acc.declare} : !fir.array<100000xf32> + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_testEdata1_acc_ctor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_testEdata1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[GLOBAL_ADDR]] : !fir.ref>) -> !fir.ref> {name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) +! ALL: acc.terminator +! ALL: } + +! ALL-LABEL: acc.global_dtor @_QMacc_declare_testEdata1_acc_dtor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_testEdata1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[GLOBAL_ADDR]] : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "data1", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref>) {dataClause = #acc, name = "data1", structured = false} +! ALL: acc.terminator +! ALL: } + +module acc_declare_copyin_test + integer, parameter :: n = 100000 + real, dimension(n) :: data1 + !$acc declare copyin(data1) +end module + + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_copyin_testEdata1_acc_ctor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_copyin_testEdata1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[COPYIN:.*]] = acc.copyin varPtr(%[[GLOBAL_ADDR]] : !fir.ref>) -> !fir.ref> {name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref>) +! ALL: acc.terminator +! ALL: } + +module acc_declare_device_resident_test + integer, parameter :: n = 5000 + integer, dimension(n) :: data1 + !$acc declare device_resident(data1) +end module + +! ALL-LABEL: fir.global @_QMacc_declare_device_resident_testEdata1 {acc.declare = #acc.declare} : !fir.array<5000xi32> + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_device_resident_testEdata1_acc_ctor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_device_resident_testEdata1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[DEVICERESIDENT:.*]] = acc.declare_device_resident varPtr(%0 : !fir.ref>) -> !fir.ref> {name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[DEVICERESIDENT]] : !fir.ref>) +! ALL: acc.terminator +! ALL: } + +module acc_declare_device_link_test + integer, parameter :: n = 5000 + integer, dimension(n) :: data1 + !$acc declare link(data1) +end module + +! ALL-LABEL: fir.global @_QMacc_declare_device_link_testEdata1 {acc.declare = #acc.declare} : !fir.array<5000xi32> { + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_device_link_testEdata1_acc_ctor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_device_link_testEdata1) {acc.declare = #acc.declare} : !fir.ref> +! ALL: %[[LINK:.*]] = acc.declare_link varPtr(%[[GLOBAL_ADDR]] : !fir.ref>) -> !fir.ref> {name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! ALL: acc.terminator +! ALL: } + +module acc_declare + contains + + subroutine acc_declare_copy() + integer :: a(100), i + !$acc declare copy(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_copy() +! ALL-DAG: %[[C1:.*]] = arith.constant 1 : index +! ALL-DAG: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyEa"} +! FIR-DAG: %[[DECL:.*]] = fir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR-DAG: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) +! FIR: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "a"} +! HLFIR: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "a"} +! ALL: acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref>) + +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { +! ALL: } + +! ALL: acc.declare_exit dataOperands(%[[COPYIN]] : !fir.ref>) +! FIR: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[DECL]] : !fir.ref>) {dataClause = #acc, name = "a"} +! HLFIR: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[DECL]]#1 : !fir.ref>) {dataClause = #acc, name = "a"} + +! ALL: return + + subroutine acc_declare_create() + integer :: a(100), i + !$acc declare create(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_create() { +! ALL-DAG: %[[C1:.*]] = arith.constant 1 : index +! ALL-DAG: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_createEa"} +! FIR-DAG: %[[DECL:.*]] = fir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_createEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR-DAG: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_createEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) +! FIR: %[[CREATE:.*]] = acc.create varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! HLFIR: %[[CREATE:.*]] = acc.create varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) + +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index, i32) { +! ALL: } + +! ALL: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[CREATE]] : !fir.ref>) bounds(%[[BOUND]]) {dataClause = #acc, name = "a"} +! ALL: return + + subroutine acc_declare_present(a) + integer :: a(100), i + !$acc declare present(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_present( +! ALL-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) +! ALL-DAG: %[[C1:.*]] = arith.constant 1 : index +! FIR-DAG: %[[DECL:.*]] = fir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_presentEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR-DAG: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_presentEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%[[C1]] : index) +! FIR: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! HLFIR: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! ALL: acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[PRESENT]] : !fir.ref>) + + subroutine acc_declare_copyin() + integer :: a(100), b(10), i + !$acc declare copyin(a) copyin(readonly: b) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_copyin() +! ALL: %[[A:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyinEa"} +! FIR: %[[ADECL:.*]] = fir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyinEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[ADECL:.*]]:2 = hlfir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyinEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! ALL: %[[B:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "b", uniq_name = "_QMacc_declareFacc_declare_copyinEb"} +! FIR: %[[BDECL:.*]] = fir.declare %[[B]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyinEb"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[BDECL:.*]]:2 = hlfir.declare %[[B]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyinEb"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) +! FIR: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ADECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! HLFIR: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ADECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} +! ALL: %[[BOUND:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index) +! FIR: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[BDECL]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} +! HLFIR: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[BDECL]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = #acc, name = "b"} +! ALL: acc.declare_enter dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref>, !fir.ref>) + + subroutine acc_declare_copyout() + integer :: a(100), i + !$acc declare copyout(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_copyout() +! ALL: %[[A:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "a", uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} +! FIR: %[[ADECL:.*]] = fir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[ADECL:.*]]:2 = hlfir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[CREATE:.*]] = acc.create varPtr(%[[ADECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} +! HLFIR: %[[CREATE:.*]] = acc.create varPtr(%[[ADECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {dataClause = #acc, name = "a"} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[CREATE]] : !fir.ref>) +! FIR: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ADECL]] : !fir.ref>) {name = "a"} +! HLFIR: acc.copyout accPtr(%[[CREATE]] : !fir.ref>) bounds(%{{.*}}) to varPtr(%[[ADECL]]#1 : !fir.ref>) {name = "a"} +! ALL: return + + subroutine acc_declare_deviceptr(a) + integer :: a(100), i + !$acc declare deviceptr(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_deviceptr( +! ALL-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) { +! FIR: %[[DECL:.*]] = fir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptrEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptrEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! HLFIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! ALL: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>) + + subroutine acc_declare_link(a) + integer :: a(100), i + !$acc declare link(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_link( +! ALL-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) +! FIR: %[[DECL:.*]] = fir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_linkEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_linkEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! HLFIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! ALL: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[LINK]] : !fir.ref>) + + subroutine acc_declare_device_resident(a) + integer :: a(100), i + !$acc declare device_resident(a) + + do i = 1, 100 + a(i) = i + end do + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_device_resident( +! ALL-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "a"}) +! FIR: %[[DECL:.*]] = fir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_residentEa"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_residentEa"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! HLFIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "a"} +! ALL: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: %{{.*}}:2 = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (index, i32) +! ALL: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "a"} + + subroutine acc_declare_device_resident2() + integer, parameter :: n = 100 + real, dimension(n) :: dataparam + !$acc declare device_resident(dataparam) + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_device_resident2() +! ALL: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_device_resident2Edataparam"} +! FIR: %[[DECL:.*]] = fir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_resident2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_device_resident2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! HLFIR: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! ALL: acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: acc.declare_exit dataOperands(%[[DEVICERES]] : !fir.ref>) +! ALL: acc.delete accPtr(%[[DEVICERES]] : !fir.ref>) bounds(%{{.*}}) {dataClause = #acc, name = "dataparam"} + + subroutine acc_declare_link2() + integer, parameter :: n = 100 + real, dimension(n) :: dataparam + !$acc declare link(dataparam) + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_link2() +! ALL: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_link2Edataparam"} +! FIR: %[[DECL:.*]] = fir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_link2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_link2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! HLFIR: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! ALL: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref>) + + subroutine acc_declare_deviceptr2() + integer, parameter :: n = 100 + real, dimension(n) :: dataparam + !$acc declare deviceptr(dataparam) + end subroutine + +! ALL-LABEL: func.func @_QMacc_declarePacc_declare_deviceptr2() +! ALL: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "dataparam", uniq_name = "_QMacc_declareFacc_declare_deviceptr2Edataparam"} +! FIR: %[[DECL:.*]] = fir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptr2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare, uniq_name = "_QMacc_declareFacc_declare_deviceptr2Edataparam"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! FIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! HLFIR: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]]#1 : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "dataparam"} +! ALL: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref>) + +end module + +module acc_declare_allocatable_test + integer, allocatable :: data1(:) + !$acc declare create(data1) +end module + +! ALL-LABEL: acc.global_ctor @_QMacc_declare_allocatable_testEdata1_acc_ctor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_allocatable_testEdata1) {acc.declare = #acc.declare} : !fir.ref>>> +! ALL: %[[COPYIN:.*]] = acc.copyin varPtr(%[[GLOBAL_ADDR]] : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, implicit = true, name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref>>>) +! ALL: acc.terminator +! ALL: } + +! ALL-LABEL: func.func private @_QMacc_declare_allocatable_testEdata1_acc_declare_update_desc_post_alloc() { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_allocatable_testEdata1) : !fir.ref>>> +! ALL: %[[LOAD:.*]] = fir.load %[[GLOBAL_ADDR]] : !fir.ref>>> +! ALL: %[[BOXADDR:.*]] = fir.box_addr %[[LOAD]] {acc.declare = #acc.declare} : (!fir.box>>) -> !fir.heap> +! ALL: %[[CREATE:.*]] = acc.create varPtr(%[[BOXADDR]] : !fir.heap>) -> !fir.heap> {name = "data1", structured = false} +! ALL: acc.declare_enter dataOperands(%[[CREATE]] : !fir.heap>) +! ALL: %[[UPDATE:.*]] = acc.update_device varPtr(%[[GLOBAL_ADDR]] : !fir.ref>>>) -> !fir.ref>>> {implicit = true, name = "data1_desc", structured = false} +! ALL: acc.update dataOperands(%[[UPDATE]] : !fir.ref>>>) +! ALL: return +! ALL: } + +! ALL-LABEL: acc.global_dtor @_QMacc_declare_allocatable_testEdata1_acc_dtor { +! ALL: %[[GLOBAL_ADDR:.*]] = fir.address_of(@_QMacc_declare_allocatable_testEdata1) {acc.declare = #acc.declare} : !fir.ref>>> +! ALL: %[[DEVICEPTR:.*]] = acc.getdeviceptr varPtr(%[[GLOBAL_ADDR]] : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, name = "data1", structured = false} +! ALL: acc.declare_exit dataOperands(%[[DEVICEPTR]] : !fir.ref>>>) +! ALL: acc.delete accPtr(%[[DEVICEPTR]] : !fir.ref>>>) {dataClause = #acc, name = "data1", structured = false} +! ALL: acc.terminator +! ALL: }