Skip to content

Commit 1a6b041

Browse files
[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.
1 parent d3d35ad commit 1a6b041

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -831,9 +831,9 @@ fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy,
831831

832832
template <typename RecipeOp>
833833
static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
834-
mlir::Type ty, mlir::Location loc) {
834+
mlir::Type argTy, mlir::Location loc) {
835835
mlir::Value retVal = recipe.getInitRegion().front().getArgument(0);
836-
ty = fir::unwrapRefType(ty);
836+
mlir::Type unwrappedTy = fir::unwrapRefType(argTy);
837837

838838
auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp {
839839
auto alloca = builder.create<fir::AllocaOp>(loc, ty);
@@ -843,9 +843,10 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
843843
fir::FortranVariableFlagsAttr{});
844844
};
845845

846-
if (fir::isa_trivial(ty)) {
847-
retVal = getDeclareOpForType(ty).getBase();
848-
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
846+
if (fir::isa_trivial(unwrappedTy)) {
847+
retVal = getDeclareOpForType(unwrappedTy).getBase();
848+
} else if (auto seqTy =
849+
mlir::dyn_cast_or_null<fir::SequenceType>(unwrappedTy)) {
849850
if (fir::isa_trivial(seqTy.getEleTy())) {
850851
mlir::Value shape;
851852
llvm::SmallVector<mlir::Value> extents;
@@ -866,15 +867,33 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
866867
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
867868
retVal = declareOp.getBase();
868869
}
869-
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) {
870+
} else if (auto boxTy =
871+
mlir::dyn_cast_or_null<fir::BaseBoxType>(unwrappedTy)) {
870872
mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
871873
if (fir::isa_trivial(innerTy)) {
872-
retVal = getDeclareOpForType(ty).getBase();
874+
retVal = getDeclareOpForType(unwrappedTy).getBase();
873875
} else if (mlir::isa<fir::SequenceType>(innerTy)) {
874876
fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
875877
hlfir::Entity source = hlfir::Entity{retVal};
876878
auto [temp, cleanup] = hlfir::createTempFromMold(loc, firBuilder, source);
877-
retVal = temp;
879+
if (fir::isa_ref_type(argTy)) {
880+
// When the temp is created - it is not a reference - thus we can
881+
// end up with a type inconsistency. Therefore ensure storage is created
882+
// for it.
883+
retVal = getDeclareOpForType(unwrappedTy).getBase();
884+
mlir::Value storeDst = retVal;
885+
if (fir::unwrapRefType(retVal.getType()) != temp.getType()) {
886+
// `createTempFromMold` makes the unfortunate choice to lose the
887+
// `fir.heap` and `fir.ptr` types when wrapping with a box. Namely,
888+
// when wrapping a `fir.heap<fir.array>`, it will create instead a
889+
// `fir.box<fir.array>`. Cast here to deal with this inconsistency.
890+
storeDst = firBuilder.createConvert(
891+
loc, firBuilder.getRefType(temp.getType()), retVal);
892+
}
893+
builder.create<fir::StoreOp>(loc, temp, storeDst);
894+
} else {
895+
retVal = temp;
896+
}
878897
} else {
879898
TODO(loc, "Unsupported boxed type in OpenACC privatization");
880899
}

flang/test/Lower/OpenACC/acc-private.f90

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@
8484
! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
8585
! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
8686
! 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>>)
87-
! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
87+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>>
88+
! 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>>>>)
89+
! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
90+
! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
91+
! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
8892
! CHECK: }
8993

9094
! CHECK-LABEL: @privatization_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> init {
@@ -102,7 +106,11 @@
102106
! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
103107
! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
104108
! 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>>)
105-
! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box<!fir.array<?xi32>>
109+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
110+
! 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>>>>)
111+
! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
112+
! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
113+
! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
106114
! CHECK: }
107115

108116
! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {

0 commit comments

Comments
 (0)