diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -427,8 +427,20 @@ builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(), {ty}, {loc}); builder.setInsertionPointToEnd(&recipe.getInitRegion().back()); - builder.create( - loc, recipe.getInitRegion().front().getArgument(0)); + + mlir::Value retVal = recipe.getInitRegion().front().getArgument(0); + if (auto refTy = mlir::dyn_cast_or_null(ty)) { + if (fir::isa_trivial(refTy.getEleTy())) + retVal = builder.create(loc, refTy.getEleTy()); + else if (auto seqTy = + mlir::dyn_cast_or_null(refTy.getEleTy())) { + if (seqTy.hasDynamicExtents()) + TODO(loc, "private recipe of array with dynamic extents"); + if (fir::isa_trivial(seqTy.getEleTy())) + retVal = builder.create(loc, seqTy); + } + } + builder.create(loc, retVal); builder.restoreInsertionPoint(crtPos); return recipe; } diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-private.f90 @@ -0,0 +1,48 @@ +! This test checks lowering of OpenACC loop directive. + +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref> init { +! CHECK: ^bb0(%{{.*}}: !fir.ref>): +! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref init { +! CHECK: ^bb0(%{{.*}}: !fir.ref): +! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref +! CHECK: } + +program acc_private + integer :: i, c + integer, parameter :: n = 100 + real, dimension(n) :: a, b + +! CHECK: %[[B:.*]] = fir.address_of(@_QFEb) : !fir.ref> +! CHECK: %[[C:.*]] = fir.alloca i32 {bindc_name = "c", uniq_name = "_QFEc"} + + !$acc loop private(c) + DO i = 1, n + c = i + a(i) = b(i) + c + END DO + +! CHECK: %[[C_PRIVATE:.*]] = acc.private varPtr(%[[C]] : !fir.ref) -> !fir.ref {name = "c"} +! CHECK: acc.loop private(@privatization_ref_i32 -> %[[C_PRIVATE]] : !fir.ref) +! CHECK: acc.yield + + !$acc loop private(b) + DO i = 1, n + c = i + a(i) = b(i) + c + END DO + +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.constant 0 : index +! CHECK: %[[UB:.*]] = arith.subi %{{.*}}, %[[C1]] : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index) +! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "b"} +! CHECK: acc.loop private(@privatization_ref_100xf32 -> %[[B_PRIVATE]] : !fir.ref>) { + +end program