[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