diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 535ec1c03b54db..ed44598bc92521 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -879,8 +879,17 @@ mlir::Value gatherDataOperandAddrAndBounds( builder, operandLocation, converter, compExv, baseAddr); asFortran << (*expr).AsFortran(); + if (auto loadOp = mlir::dyn_cast_or_null( + baseAddr.getDefiningOp())) { + if (fir::isAllocatableType(loadOp.getType()) || + fir::isPointerType(loadOp.getType())) + baseAddr = builder.create(operandLocation, + baseAddr); + } + // If the component is an allocatable or pointer the result of - // genExprAddr will be the result of a fir.box_addr operation. + // genExprAddr will be the result of a fir.box_addr operation or + // a fir.box_addr has been inserted just before. // Retrieve the box so we handle it like other descriptor. if (auto boxAddrOp = mlir::dyn_cast_or_null( baseAddr.getDefiningOp())) { diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90 new file mode 100644 index 00000000000000..c63c9aacf5c2c1 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-bounds.f90 @@ -0,0 +1,89 @@ +! This test checks lowering of OpenACC data bounds operation. + +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefixes=CHECK,FIR +! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK,HLFIR + +module openacc_bounds + +type t1 + integer, pointer, dimension(:) :: array_comp +end type + +type t2 + integer, dimension(10) :: array_comp +end type + +type t3 + integer, allocatable, dimension(:) :: array_comp +end type + +contains + subroutine acc_derived_type_component_pointer_array() + type(t1) :: d + !$acc enter data create(d%array_comp) + end subroutine + +! CHECK-LABEL: func.func @_QMopenacc_boundsPacc_derived_type_component_pointer_array() { +! CHECK: %[[D:.*]] = fir.alloca !fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box>>}> {bindc_name = "d", uniq_name = "_QMopenacc_boundsFacc_derived_type_component_pointer_arrayEd"} +! HLFIR: %[[DECL_D:.*]]:2 = hlfir.declare %[[D]] {uniq_name = "_QMopenacc_boundsFacc_derived_type_component_pointer_arrayEd"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) +! FIR: %[[FIELD:.*]] = fir.field_index array_comp, !fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box>>}> +! FIR: %[[COORD:.*]] = fir.coordinate_of %[[D]], %[[FIELD]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> +! HLFIR: %[[COORD:.*]] = hlfir.designate %[[DECL_D]]#0{"array_comp"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> +! CHECK: %[[LOAD:.*]] = fir.load %[[COORD]] : !fir.ref>>> +! CHECK: %[[BOX_DIMS0:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS1:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[UB:.*]] = arith.subi %[[BOX_DIMS1]]#1, %[[C1]] : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%[[UB]] : index) stride(%[[BOX_DIMS1]]#2 : index) startIdx(%[[BOX_DIMS0]]#0 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ptr>) bounds(%[[BOUND]]) -> !fir.ptr> {name = "d%array_comp", structured = false} +! CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ptr>) +! CHECK: return +! CHECK: } + + subroutine acc_derived_type_component_array() + type(t2) :: d + !$acc enter data create(d%array_comp) + end subroutine + +! CHECK-LABEL: func.func @_QMopenacc_boundsPacc_derived_type_component_array() +! CHECK: %[[D:.*]] = fir.alloca !fir.type<_QMopenacc_boundsTt2{array_comp:!fir.array<10xi32>}> {bindc_name = "d", uniq_name = "_QMopenacc_boundsFacc_derived_type_component_arrayEd"} +! HLFIR: %[[DECL_D:.*]]:2 = hlfir.declare %[[D]] {uniq_name = "_QMopenacc_boundsFacc_derived_type_component_arrayEd"} : (!fir.ref}>>) -> (!fir.ref}>>, !fir.ref}>>) +! FIR: %[[FIELD:.*]] = fir.field_index array_comp, !fir.type<_QMopenacc_boundsTt2{array_comp:!fir.array<10xi32>}> +! FIR: %[[COORD:.*]] = fir.coordinate_of %[[D]], %[[FIELD]] : (!fir.ref}>>, !fir.field) -> !fir.ref> +! CHECK: %[[C10:.*]] = arith.constant 10 : index +! HLFIR: %[[SHAPE:.*]] = fir.shape %[[C10]] : (index) -> !fir.shape<1> +! HLFIR: %[[COORD:.*]] = hlfir.designate %[[DECL_D]]#0{"array_comp"} shape %[[SHAPE]] : (!fir.ref}>>, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[UB:.*]] = arith.subi %[[C10]], %[[C1]] : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[C0]] : index) upperbound(%[[UB]] : index) extent(%[[C10]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[COORD]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "d%array_comp", structured = false} +! CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref>) +! CHECK: return +! CHECK: } + + subroutine acc_derived_type_component_allocatable_array() + type(t3) :: d + !$acc enter data create(d%array_comp) + end subroutine + +! CHECK-LABEL: func.func @_QMopenacc_boundsPacc_derived_type_component_allocatable_array() { +! CHECK: %[[D:.*]] = fir.alloca !fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box>>}> {bindc_name = "d", uniq_name = "_QMopenacc_boundsFacc_derived_type_component_allocatable_arrayEd"} +! HLFIR: %[[DECL_D:.*]]:2 = hlfir.declare %[[D]] {uniq_name = "_QMopenacc_boundsFacc_derived_type_component_allocatable_arrayEd"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) +! FIR: %[[FIELD:.*]] = fir.field_index array_comp, !fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box>>}> +! FIR: %[[COORD:.*]] = fir.coordinate_of %[[D]], %[[FIELD]] : (!fir.ref>>}>>, !fir.field) -> !fir.ref>>> +! HLFIR: %[[COORD:.*]] = hlfir.designate %[[DECL_D]]#0{"array_comp"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> +! CHECK: %[[LOAD:.*]] = fir.load %[[COORD]] : !fir.ref>>> +! CHECK: %[[BOX_DIMS0:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS1:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[UB:.*]] = arith.subi %[[BOX_DIMS1]]#1, %[[C1]] : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%[[UB]] : index) stride(%[[BOX_DIMS1]]#2 : index) startIdx(%[[BOX_DIMS0]]#0 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.heap>) bounds(%[[BOUND]]) -> !fir.heap> {name = "d%array_comp", structured = false} +! CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.heap>) +! CHECK: return +! CHECK: } + +end module