[flang-commits] [flang] 1a6b041 - [flang][acc] Fix issue with privatization recipe for box ref (#137869)
via flang-commits
flang-commits at lists.llvm.org
Tue Apr 29 13:13:32 PDT 2025
Author: Razvan Lupusoru
Date: 2025-04-29T13:13:29-07:00
New Revision: 1a6b0413e047a390dc7759b2ea558bad83e7f1cf
URL: https://github.com/llvm/llvm-project/commit/1a6b0413e047a390dc7759b2ea558bad83e7f1cf
DIFF: https://github.com/llvm/llvm-project/commit/1a6b0413e047a390dc7759b2ea558bad83e7f1cf.diff
LOG: [flang][acc] Fix issue with privatization recipe for box ref (#137869)
When privatizing allocatable/pointer arrays, the code was creating a
temporary but this was a box type. This led to inconsistency between the
input and output of recipe.
The updated logic now creates storage when a box ref is requested.
Added:
Modified:
flang/lib/Lower/OpenACC.cpp
flang/test/Lower/OpenACC/acc-private.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 06697b2dbc1d5..82daa05c165cb 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -831,9 +831,9 @@ fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy,
template <typename RecipeOp>
static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
- mlir::Type ty, mlir::Location loc) {
+ mlir::Type argTy, mlir::Location loc) {
mlir::Value retVal = recipe.getInitRegion().front().getArgument(0);
- ty = fir::unwrapRefType(ty);
+ mlir::Type unwrappedTy = fir::unwrapRefType(argTy);
auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp {
auto alloca = builder.create<fir::AllocaOp>(loc, ty);
@@ -843,9 +843,10 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
fir::FortranVariableFlagsAttr{});
};
- if (fir::isa_trivial(ty)) {
- retVal = getDeclareOpForType(ty).getBase();
- } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
+ if (fir::isa_trivial(unwrappedTy)) {
+ retVal = getDeclareOpForType(unwrappedTy).getBase();
+ } else if (auto seqTy =
+ mlir::dyn_cast_or_null<fir::SequenceType>(unwrappedTy)) {
if (fir::isa_trivial(seqTy.getEleTy())) {
mlir::Value shape;
llvm::SmallVector<mlir::Value> extents;
@@ -866,15 +867,33 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
retVal = declareOp.getBase();
}
- } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) {
+ } else if (auto boxTy =
+ mlir::dyn_cast_or_null<fir::BaseBoxType>(unwrappedTy)) {
mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
if (fir::isa_trivial(innerTy)) {
- retVal = getDeclareOpForType(ty).getBase();
+ retVal = getDeclareOpForType(unwrappedTy).getBase();
} else if (mlir::isa<fir::SequenceType>(innerTy)) {
fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
hlfir::Entity source = hlfir::Entity{retVal};
auto [temp, cleanup] = hlfir::createTempFromMold(loc, firBuilder, source);
- retVal = temp;
+ if (fir::isa_ref_type(argTy)) {
+ // When the temp is created - it is not a reference - thus we can
+ // end up with a type inconsistency. Therefore ensure storage is created
+ // for it.
+ retVal = getDeclareOpForType(unwrappedTy).getBase();
+ mlir::Value storeDst = retVal;
+ if (fir::unwrapRefType(retVal.getType()) != temp.getType()) {
+ // `createTempFromMold` makes the unfortunate choice to lose the
+ // `fir.heap` and `fir.ptr` types when wrapping with a box. Namely,
+ // when wrapping a `fir.heap<fir.array>`, it will create instead a
+ // `fir.box<fir.array>`. Cast here to deal with this inconsistency.
+ storeDst = firBuilder.createConvert(
+ loc, firBuilder.getRefType(temp.getType()), retVal);
+ }
+ builder.create<fir::StoreOp>(loc, temp, storeDst);
+ } else {
+ retVal = temp;
+ }
} else {
TODO(loc, "Unsupported boxed type in OpenACC privatization");
}
diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90
index 76e23b8915e92..b1bfb02439f03 100644
--- a/flang/test/Lower/OpenACC/acc-private.f90
+++ b/flang/test/Lower/OpenACC/acc-private.f90
@@ -84,7 +84,11 @@
! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
! CHECK: }
! CHECK-LABEL: @privatization_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> init {
@@ -102,7 +106,11 @@
! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
+! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
! CHECK: }
! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
More information about the flang-commits
mailing list