diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 3dd35ed9ae481..c83e277b996f3 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -522,13 +522,17 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe, mlir::Type ty, mlir::Location loc) { mlir::Value retVal = recipe.getInitRegion().front().getArgument(0); ty = fir::unwrapRefType(ty); - if (fir::isa_trivial(ty)) { + + auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp { auto alloca = builder.create(loc, ty); - auto declareOp = builder.create( + return builder.create( loc, alloca, accPrivateInitName, /*shape=*/nullptr, llvm::ArrayRef{}, /*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{}); - retVal = declareOp.getBase(); + }; + + if (fir::isa_trivial(ty)) { + retVal = getDeclareOpForType(ty).getBase(); } else if (auto seqTy = mlir::dyn_cast_or_null(ty)) { if (fir::isa_trivial(seqTy.getEleTy())) { mlir::Value shape; @@ -552,12 +556,16 @@ static void genPrivateLikeInitRegion(mlir::OpBuilder &builder, RecipeOp recipe, } } else if (auto boxTy = mlir::dyn_cast_or_null(ty)) { mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy()); - if (!fir::isa_trivial(innerTy) && !mlir::isa(innerTy)) + if (fir::isa_trivial(innerTy)) { + retVal = getDeclareOpForType(ty).getBase(); + } else if (mlir::isa(innerTy)) { + fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; + hlfir::Entity source = hlfir::Entity{retVal}; + auto [temp, cleanup] = hlfir::createTempFromMold(loc, firBuilder, source); + retVal = temp; + } else { TODO(loc, "Unsupported boxed type in OpenACC privatization"); - fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; - hlfir::Entity source = hlfir::Entity{retVal}; - auto [temp, cleanup] = hlfir::createTempFromMold(loc, firBuilder, source); - retVal = temp; + } } builder.create(loc, retVal); } diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90 index 50c7a258bb567..356bb9d825d8e 100644 --- a/flang/test/Lower/OpenACC/acc-private.f90 +++ b/flang/test/Lower/OpenACC/acc-private.f90 @@ -87,6 +87,13 @@ ! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box> ! CHECK: } +! CHECK-LABEL: @privatization_ref_box_heap_i32 : !fir.ref>> init { +! CHECK: ^bb0(%arg0: !fir.ref>>): +! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box> +! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref>> +! CHECK: } + ! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_Uxi32 : !fir.ref>>> init { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>): ! CHECK: %[[LOADBOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> @@ -292,6 +299,29 @@ subroutine acc_private_allocatable_array(a, n) ! CHECK: acc.loop {{.*}} private({{.*}}@privatization_ref_box_heap_Uxi32 -> %[[PRIVATE]] : !fir.ref>>>) ! CHECK: acc.serial private(@privatization_ref_box_heap_Uxi32 -> %{{.*}} : !fir.ref>>>) +subroutine acc_private_allocatable_scalar(b, a, n) + integer :: a(n) + integer, allocatable :: b + integer :: i, n + + !$acc parallel loop private(b) + do i = 1, n + a(i) = b + end do + + !$acc serial private(b) + a(i) = b + !$acc end serial +end subroutine + +! CHECK-LABEL: func.func @_QPacc_private_allocatable_scalar( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>> {fir.bindc_name = "b"} +! CHECK: %[[DECLA_B:.*]]:2 = hlfir.declare %arg0 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFacc_private_allocatable_scalarEb"} : (!fir.ref>>, !fir.dscope) -> (!fir.ref>>, !fir.ref>>) +! CHECK: acc.parallel {{.*}} { +! CHECK: %[[PRIVATE:.*]] = acc.private varPtr(%[[DECLA_B]]#0 : !fir.ref>>) -> !fir.ref>> {name = "b"} +! CHECK: acc.loop {{.*}} private({{.*}}@privatization_ref_box_heap_i32 -> %[[PRIVATE]] : !fir.ref>>) +! CHECK: acc.serial private(@privatization_ref_box_heap_i32 -> %{{.*}} : !fir.ref>>) { + subroutine acc_private_pointer_array(a, n) integer, pointer :: a(:) integer :: i, n