@@ -831,9 +831,9 @@ fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy,
831
831
832
832
template <typename RecipeOp>
833
833
static void genPrivateLikeInitRegion (mlir::OpBuilder &builder, RecipeOp recipe,
834
- mlir::Type ty , mlir::Location loc) {
834
+ mlir::Type argTy , mlir::Location loc) {
835
835
mlir::Value retVal = recipe.getInitRegion ().front ().getArgument (0 );
836
- ty = fir::unwrapRefType (ty );
836
+ mlir::Type unwrappedTy = fir::unwrapRefType (argTy );
837
837
838
838
auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp {
839
839
auto alloca = builder.create <fir::AllocaOp>(loc, ty);
@@ -843,9 +843,10 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
843
843
fir::FortranVariableFlagsAttr{});
844
844
};
845
845
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)) {
849
850
if (fir::isa_trivial (seqTy.getEleTy ())) {
850
851
mlir::Value shape;
851
852
llvm::SmallVector<mlir::Value> extents;
@@ -866,15 +867,33 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe,
866
867
/* dummy_scope=*/ nullptr , fir::FortranVariableFlagsAttr{});
867
868
retVal = declareOp.getBase ();
868
869
}
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)) {
870
872
mlir::Type innerTy = fir::unwrapRefType (boxTy.getEleTy ());
871
873
if (fir::isa_trivial (innerTy)) {
872
- retVal = getDeclareOpForType (ty ).getBase ();
874
+ retVal = getDeclareOpForType (unwrappedTy ).getBase ();
873
875
} else if (mlir::isa<fir::SequenceType>(innerTy)) {
874
876
fir::FirOpBuilder firBuilder{builder, recipe.getOperation ()};
875
877
hlfir::Entity source = hlfir::Entity{retVal};
876
878
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
+ }
878
897
} else {
879
898
TODO (loc, " Unsupported boxed type in OpenACC privatization" );
880
899
}
0 commit comments