[flang-commits] [flang] [flang][OpenACC] do not load pointer and allocatables component in data clauses (PR #171445)
via flang-commits
flang-commits at lists.llvm.org
Tue Dec 9 06:20:08 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: None (jeanPerier)
<details>
<summary>Changes</summary>
`gatherDataOperandAddrAndBounds` did not handle pointers and allocatable pointer components (`obj%p`) in the same way as pointer and allocatable whole objects (`p`).
The difference is that whole object are kept as a descriptor address (`fir.ref<fir.box>`) in the acc data operation while components were dereferenced (`fir.box<>`).
I do not think this was intentional, and is mainly a side effect of the `genExprAddr` for components that generate a dereference for pointer/allocatables.
In the work that I am doing on remapping components, this is an issue because the data operation must return a fir.ref<fir.box> so that I can remap any appearance to the component to it (which could be in a pointer association statement for instance, requiring access to a descriptor address as opposed to a value).
---
Full diff: https://github.com/llvm/llvm-project/pull/171445.diff
4 Files Affected:
- (modified) flang/include/flang/Lower/DirectivesCommon.h (+14-5)
- (modified) flang/lib/Lower/OpenACC.cpp (+8-4)
- (modified) flang/test/Lower/OpenACC/acc-bounds.f90 (+4-11)
- (modified) flang/test/Lower/OpenACC/acc-enter-data.f90 (+25-17)
``````````diff
diff --git a/flang/include/flang/Lower/DirectivesCommon.h b/flang/include/flang/Lower/DirectivesCommon.h
index b564ee1f64423..8d90b525aefce 100644
--- a/flang/include/flang/Lower/DirectivesCommon.h
+++ b/flang/include/flang/Lower/DirectivesCommon.h
@@ -384,7 +384,8 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
mlir::Location operandLocation, std::stringstream &asFortran,
llvm::SmallVector<mlir::Value> &bounds, bool treatIndexAsSection = false,
bool unwrapFirBox = true, bool genDefaultBounds = true,
- bool strideIncludeLowerExtent = false) {
+ bool strideIncludeLowerExtent = false,
+ bool loadAllocatableAndPointerComponent = true) {
using namespace Fortran;
fir::factory::AddrAndBoundsInfo info;
@@ -426,8 +427,12 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
auto arrayBase = toMaybeExpr(arrayRef->base());
assert(arrayBase);
- if (detail::getRef<evaluate::Component>(*arrayBase)) {
- dataExv = converter.genExprAddr(operandLocation, *arrayBase, stmtCtx);
+ if (auto comp = detail::getRef<evaluate::Component>(*arrayBase)) {
+ if (!loadAllocatableAndPointerComponent &&
+ semantics::IsAllocatableOrPointer(comp->symbol()))
+ dataExv = converter.genExprMutableBox(operandLocation, *arrayBase);
+ else
+ dataExv = converter.genExprAddr(operandLocation, *arrayBase, stmtCtx);
info.addr = fir::getBase(dataExv);
info.rawInput = info.addr;
asFortran << arrayBase->AsFortran();
@@ -450,8 +455,12 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
}
asFortran << ')';
} else if (auto compRef = detail::getRef<evaluate::Component>(designator)) {
- fir::ExtendedValue compExv =
- converter.genExprAddr(operandLocation, designator, stmtCtx);
+ fir::ExtendedValue compExv;
+ if (!loadAllocatableAndPointerComponent &&
+ semantics::IsAllocatableOrPointer(compRef->symbol()))
+ compExv = converter.genExprMutableBox(operandLocation, designator);
+ else
+ compExv = converter.genExprAddr(operandLocation, designator, stmtCtx);
info.addr = fir::getBase(compExv);
info.rawInput = info.addr;
if (genDefaultBounds &&
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 50b08cea12004..b586ea3ac627b 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -674,7 +674,8 @@ static void genDataOperandOperations(
operandLocation, asFortran, bounds,
/*treatIndexAsSection=*/true, /*unwrapFirBox=*/false,
/*genDefaultBounds=*/generateDefaultBounds,
- /*strideIncludeLowerExtent=*/strideIncludeLowerExtent);
+ /*strideIncludeLowerExtent=*/strideIncludeLowerExtent,
+ /*loadAllocatableAndPointerComponent=*/false);
LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
bool isWholeSymbol =
@@ -853,7 +854,8 @@ static void genDeclareDataOperandOperations(
operandLocation, asFortran, bounds,
/*treatIndexAsSection=*/true, /*unwrapFirBox=*/false,
/*genDefaultBounds=*/generateDefaultBounds,
- /*strideIncludeLowerExtent=*/strideIncludeLowerExtent);
+ /*strideIncludeLowerExtent=*/strideIncludeLowerExtent,
+ /*loadAllocatableAndPointerComponent=*/false);
LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
EntryOp op = createDataEntryOp<EntryOp>(
builder, operandLocation, info.addr, asFortran, bounds, structured,
@@ -1410,7 +1412,8 @@ static void genPrivatizationRecipes(
operandLocation, asFortran, bounds,
/*treatIndexAsSection=*/true, /*unwrapFirBox=*/false,
/*genDefaultBounds=*/generateDefaultBounds,
- /*strideIncludeLowerExtent=*/strideIncludeLowerExtent);
+ /*strideIncludeLowerExtent=*/strideIncludeLowerExtent,
+ /*loadAllocatableAndPointerComponent=*/false);
LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
bool isWholeSymbol =
@@ -1655,7 +1658,8 @@ static void genReductions(
operandLocation, asFortran, bounds,
/*treatIndexAsSection=*/true, /*unwrapFirBox=*/false,
/*genDefaultBounds=*/generateDefaultBounds,
- /*strideIncludeLowerExtent=*/strideIncludeLowerExtent);
+ /*strideIncludeLowerExtent=*/strideIncludeLowerExtent,
+ /*loadAllocatableAndPointerComponent=*/false);
LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
mlir::Type reductionTy = fir::unwrapRefType(info.addr.getType());
diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90
index 03779ac0cfe51..d4ec019cab23f 100644
--- a/flang/test/Lower/OpenACC/acc-bounds.f90
+++ b/flang/test/Lower/OpenACC/acc-bounds.f90
@@ -26,9 +26,8 @@ subroutine acc_derived_type_component_pointer_array()
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box<!fir.ptr<!fir.array<?xi32>>>}> {bindc_name = "d", uniq_name = "_QMopenacc_boundsFacc_derived_type_component_pointer_arrayEd"}
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QMopenacc_boundsFacc_derived_type_component_pointer_arrayEd"} : (!fir.ref<!fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>)
! CHECK: %[[VAL_4:.*]] = hlfir.designate %[[VAL_2]]#0{"array_comp"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMopenacc_boundsTt1{array_comp:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[VAL_6:.*]] = acc.create var(%[[VAL_5]] : !fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> {name = "d%[[VAL_7:.*]]", structured = false}
-! CHECK: acc.enter_data dataOperands(%[[VAL_6]] : !fir.box<!fir.ptr<!fir.array<?xi32>>>)
+! CHECK: %[[VAL_6:.*]] = acc.create varPtr(%[[VAL_4]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {name = "d%array_comp", structured = false}
+! CHECK: acc.enter_data dataOperands(%[[VAL_6]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
! CHECK: return
! CHECK: }
@@ -61,14 +60,8 @@ subroutine acc_derived_type_component_allocatable_array()
! CHECK: %[[D:.*]] = fir.alloca !fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box<!fir.heap<!fir.array<?xi32>>>}> {bindc_name = "d", uniq_name = "_QMopenacc_boundsFacc_derived_type_component_allocatable_arrayEd"}
! CHECK: %[[DECL_D:.*]]:2 = hlfir.declare %[[D]] {uniq_name = "_QMopenacc_boundsFacc_derived_type_component_allocatable_arrayEd"} : (!fir.ref<!fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
! CHECK: %[[COORD:.*]] = hlfir.designate %[[DECL_D]]#0{"array_comp"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMopenacc_boundsTt3{array_comp:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[LOAD:.*]] = fir.load %[[COORD]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[BOX_DIMS0:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[BOX_DIMS1:.*]]:3 = fir.box_dims %[[LOAD]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK: %[[UB:.*]] = arith.subi %[[BOX_DIMS1]]#1, %[[C1]] : index
-! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%[[UB]] : index) extent(%[[BOX_DIMS1]]#1 : index) stride(%[[BOX_DIMS1]]#2 : index) startIdx(%[[BOX_DIMS0]]#0 : index) {strideInBytes = true}
-! CHECK: %[[CREATE:.*]] = acc.create var(%[[LOAD]] : !fir.box<!fir.heap<!fir.array<?xi32>>>) bounds(%[[BOUND]]) -> !fir.box<!fir.heap<!fir.array<?xi32>>> {name = "d%[[VAL_15:.*]]", structured = false}
-! CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.box<!fir.heap<!fir.array<?xi32>>>)
+! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[COORD]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "d%[[VAL_15:.*]]", structured = false}
+! CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
! CHECK: return
! CHECK: }
diff --git a/flang/test/Lower/OpenACC/acc-enter-data.f90 b/flang/test/Lower/OpenACC/acc-enter-data.f90
index 1e20bdc238573..11c5cdaeb6057 100644
--- a/flang/test/Lower/OpenACC/acc-enter-data.f90
+++ b/flang/test/Lower/OpenACC/acc-enter-data.f90
@@ -619,9 +619,8 @@ subroutine acc_enter_data_derived_type()
!CHECK: %[[DATA_COORD:.*]] = hlfir.designate %[[DECLC]]#0{"data"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFacc_enter_data_derived_typeTz{data:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-!CHECK: %[[DATA_BOX:.*]] = fir.load %[[DATA_COORD]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-!CHECK: %[[CREATE:.*]] = acc.create var(%[[DATA_BOX]] : !fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.box<!fir.heap<!fir.array<?xi32>>> {name = "c%data", structured = false}
-!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.box<!fir.heap<!fir.array<?xi32>>>)
+!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[DATA_COORD]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {name = "c%data", structured = false}
+!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
!$acc enter data create (d%d(1)%array)
@@ -643,20 +642,29 @@ subroutine acc_enter_data_single_array_element()
!$acc enter data create(e(2)%a(1,2))
!CHECK-LABEL: func.func @_QPacc_enter_data_single_array_element() {
-!CHECK-DAG: %[[VAL_38:.*]]:3 = fir.box_dims %[[BOX:.*]], %[[VAL_37:.*]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
-!CHECK-DAG: %[[VAL_37]] = arith.constant 0 : index
-!CHECK-DAG: %[[VAL_40:.*]]:3 = fir.box_dims %[[BOX]], %[[VAL_39:.*]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
-!CHECK-DAG: %[[VAL_39]] = arith.constant 1 : index
-!CHECK-DAG: %[[VAL_41:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.heap<!fir.array<?x?xf32>>
-!CHECK: %[[VAL_42:.*]] = arith.constant 1 : index
-!CHECK: %[[VAL_43:.*]] = arith.constant 1 : index
-!CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_43]], %[[VAL_38]]#0 : index
-!CHECK: %[[VAL_45:.*]] = acc.bounds lowerbound(%[[VAL_44]] : index) upperbound(%[[VAL_44]] : index) extent(%[[VAL_42]] : index) stride(%[[VAL_42]] : index) startIdx(%[[VAL_38]]#0 : index)
-!CHECK: %[[VAL_46:.*]] = arith.constant 2 : index
-!CHECK: %[[VAL_47:.*]] = arith.subi %[[VAL_46]], %[[VAL_40]]#0 : index
-!CHECK: %[[VAL_48:.*]] = acc.bounds lowerbound(%[[VAL_47]] : index) upperbound(%[[VAL_47]] : index) extent(%[[VAL_42]] : index) stride(%[[VAL_42]] : index) startIdx(%[[VAL_40]]#0 : index)
-!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[VAL_41]] : !fir.heap<!fir.array<?x?xf32>>) bounds(%[[VAL_45]], %[[VAL_48]]) -> !fir.heap<!fir.array<?x?xf32>> {name = "e(2_8)%a(1,2)", structured = false}
-!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.heap<!fir.array<?x?xf32>>)
+! CHECK: fir.allocmem
+! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %{{.*}}{"a"} {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QFacc_enter_data_single_array_elementTt1{a:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
+! CHECK-DAG: %[[CONSTANT_11:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[LOAD_2:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
+! CHECK-DAG: %[[CONSTANT_12:.*]] = arith.constant 0 : index
+! CHECK-DAG: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_2]], %[[CONSTANT_12]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
+! CHECK-DAG: %[[LOAD_3:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
+! CHECK-DAG: %[[CONSTANT_13:.*]] = arith.constant 0 : index
+! CHECK-DAG: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_3]], %[[CONSTANT_13]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
+! CHECK-DAG: %[[CONSTANT_14:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_14]], %[[BOX_DIMS_0]]#0 : index
+! CHECK-DAG: %[[BOUNDS_0:.*]] = acc.bounds lowerbound(%[[SUBI_0]] : index) upperbound(%[[SUBI_0]] : index) extent(%[[CONSTANT_11]] : index) stride(%[[BOX_DIMS_1]]#2 : index) startIdx(%[[BOX_DIMS_0]]#0 : index) {strideInBytes = true}
+! CHECK-DAG: %[[LOAD_4:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
+! CHECK-DAG: %[[CONSTANT_15:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_4]], %[[CONSTANT_15]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
+! CHECK-DAG: %[[LOAD_5:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>
+! CHECK-DAG: %[[CONSTANT_16:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_5]], %[[CONSTANT_16]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, index) -> (index, index, index)
+! CHECK-DAG: %[[CONSTANT_17:.*]] = arith.constant 2 : index
+! CHECK-DAG: %[[SUBI_1:.*]] = arith.subi %[[CONSTANT_17]], %[[BOX_DIMS_2]]#0 : index
+! CHECK-DAG: %[[BOUNDS_1:.*]] = acc.bounds lowerbound(%[[SUBI_1]] : index) upperbound(%[[SUBI_1]] : index) extent(%[[CONSTANT_11]] : index) stride(%[[BOX_DIMS_3]]#2 : index) startIdx(%[[BOX_DIMS_2]]#0 : index) {strideInBytes = true}
+! CHECK: %[[CREATE_0:.*]] = acc.create varPtr(%[[DESIGNATE_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>) bounds(%[[BOUNDS_0]], %[[BOUNDS_1]]) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>> {name = "e(2_8)%[[VAL_0:.*]](1,2)", structured = false}
+! CHECK: acc.enter_data dataOperands(%[[CREATE_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf32>>>>)
end subroutine
``````````
</details>
https://github.com/llvm/llvm-project/pull/171445
More information about the flang-commits
mailing list