-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[flang][openacc] Support assumed shape array in firstprivate recipe #68640
[flang][openacc] Support assumed shape array in firstprivate recipe #68640
Conversation
@llvm/pr-subscribers-mlir-openacc @llvm/pr-subscribers-mlir ChangesAdd support for assumed shape arrays in lowering of the copy region of the firstprivate recipe. Information is passed in block arguments as it is done for the reduction recipe. Patch is 33.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/68640.diff 8 Files Affected:
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index b342e4a4704dab1..c73af0a6eb0f874 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -90,10 +90,10 @@ createOrGetReductionRecipe(fir::FirOpBuilder &, llvm::StringRef, mlir::Location,
/// Get a acc.firstprivate.recipe op for the given type or create it if it does
/// not exist yet.
-mlir::acc::FirstprivateRecipeOp createOrGetFirstprivateRecipe(mlir::OpBuilder &,
- llvm::StringRef,
- mlir::Location,
- mlir::Type);
+mlir::acc::FirstprivateRecipeOp
+createOrGetFirstprivateRecipe(mlir::OpBuilder &, llvm::StringRef,
+ mlir::Location, mlir::Type,
+ llvm::SmallVector<mlir::Value> &);
void attachDeclarePostAllocAction(AbstractConverter &, fir::FirOpBuilder &,
const Fortran::semantics::Symbol &);
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 3d3fcce44c529fe..de551c36c9dc9d5 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -427,9 +427,78 @@ Fortran::lower::createOrGetPrivateRecipe(mlir::OpBuilder &builder,
return recipe;
}
+/// Check if the DataBoundsOp is a constant bound (lb and ub are constants or
+/// extent is a constant).
+bool isConstantBound(mlir::acc::DataBoundsOp &op) {
+ if (op.getLowerbound() && fir::getIntIfConstant(op.getLowerbound()) &&
+ op.getUpperbound() && fir::getIntIfConstant(op.getUpperbound()))
+ return true;
+ if (op.getExtent() && fir::getIntIfConstant(op.getExtent()))
+ return true;
+ return false;
+}
+
+/// Return true iff all the bounds are expressed with constant values.
+bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
+ for (auto bound : bounds) {
+ auto dataBound =
+ mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
+ assert(dataBound && "Must be DataBoundOp operation");
+ if (!isConstantBound(dataBound))
+ return false;
+ }
+ return true;
+}
+
+static fir::ShapeOp
+genShapeFromBounds(mlir::Location loc, fir::FirOpBuilder &builder,
+ const llvm::SmallVector<mlir::Value> &args) {
+ assert(args.size() % 3 == 0 && "Triplets must be a multiple of 3");
+ llvm::SmallVector<mlir::Value> extents;
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
+ mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
+ for (unsigned i = 0; i < args.size(); i += 3) {
+ mlir::Value s1 =
+ builder.create<mlir::arith::SubIOp>(loc, args[i + 1], args[0]);
+ mlir::Value s2 = builder.create<mlir::arith::AddIOp>(loc, s1, one);
+ mlir::Value s3 = builder.create<mlir::arith::DivSIOp>(loc, s2, args[i + 2]);
+ mlir::Value cmp = builder.create<mlir::arith::CmpIOp>(
+ loc, mlir::arith::CmpIPredicate::sgt, s3, zero);
+ mlir::Value ext = builder.create<mlir::arith::SelectOp>(loc, cmp, s3, zero);
+ extents.push_back(ext);
+ }
+ return builder.create<fir::ShapeOp>(loc, extents);
+}
+
+static llvm::SmallVector<mlir::Value>
+genConstantBounds(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::acc::DataBoundsOp &dataBound) {
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Value lb, ub, step;
+ if (dataBound.getLowerbound() &&
+ fir::getIntIfConstant(dataBound.getLowerbound()) &&
+ dataBound.getUpperbound() &&
+ fir::getIntIfConstant(dataBound.getUpperbound())) {
+ lb = builder.createIntegerConstant(
+ loc, idxTy, *fir::getIntIfConstant(dataBound.getLowerbound()));
+ ub = builder.createIntegerConstant(
+ loc, idxTy, *fir::getIntIfConstant(dataBound.getUpperbound()));
+ step = builder.createIntegerConstant(loc, idxTy, 1);
+ } else if (dataBound.getExtent()) {
+ lb = builder.createIntegerConstant(loc, idxTy, 0);
+ ub = builder.createIntegerConstant(
+ loc, idxTy, *fir::getIntIfConstant(dataBound.getExtent()) - 1);
+ step = builder.createIntegerConstant(loc, idxTy, 1);
+ } else {
+ llvm::report_fatal_error("Expect constant lb/ub or extent");
+ }
+ return {lb, ub, step};
+}
+
mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
mlir::OpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
- mlir::Type ty) {
+ mlir::Type ty, llvm::SmallVector<mlir::Value> &bounds) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
if (auto recipe =
@@ -446,47 +515,111 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
genPrivateLikeInitRegion<mlir::acc::FirstprivateRecipeOp>(builder, recipe, ty,
loc);
- // Add empty copy region for firstprivate. TODO add copy sequence.
+ bool allConstantBound = areAllBoundConstant(bounds);
+ llvm::SmallVector<mlir::Type> argsTy{ty, ty};
+ llvm::SmallVector<mlir::Location> argsLoc{loc, loc};
+ if (!allConstantBound) {
+ for (mlir::Value bound : llvm::reverse(bounds)) {
+ auto dataBound =
+ mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
+ argsTy.push_back(dataBound.getLowerbound().getType());
+ argsLoc.push_back(dataBound.getLowerbound().getLoc());
+ argsTy.push_back(dataBound.getUpperbound().getType());
+ argsLoc.push_back(dataBound.getUpperbound().getLoc());
+ argsTy.push_back(dataBound.getStartIdx().getType());
+ argsLoc.push_back(dataBound.getStartIdx().getLoc());
+ }
+ }
builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(),
- {ty, ty}, {loc, loc});
+ argsTy, argsLoc);
builder.setInsertionPointToEnd(&recipe.getCopyRegion().back());
- if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
- if (fir::isa_trivial(refTy.getEleTy())) {
- mlir::Value initValue = builder.create<fir::LoadOp>(
- loc, recipe.getCopyRegion().front().getArgument(0));
- builder.create<fir::StoreOp>(
- loc, initValue, recipe.getCopyRegion().front().getArgument(1));
- } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(
- refTy.getEleTy())) {
- if (seqTy.hasDynamicExtents())
- TODO(loc, "private recipe of array with dynamic extents");
- mlir::Type idxTy = builder.getIndexType();
- mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
- mlir::Value arraySrc = recipe.getCopyRegion().front().getArgument(0);
- mlir::Value arrayDst = recipe.getCopyRegion().front().getArgument(1);
- llvm::SmallVector<fir::DoLoopOp> loops;
- llvm::SmallVector<mlir::Value> ivs;
- for (auto ext : llvm::reverse(seqTy.getShape())) {
- auto lb = builder.create<mlir::arith::ConstantOp>(
- loc, idxTy, builder.getIntegerAttr(idxTy, 0));
- auto ub = builder.create<mlir::arith::ConstantOp>(
- loc, idxTy, builder.getIntegerAttr(idxTy, ext - 1));
- auto step = builder.create<mlir::arith::ConstantOp>(
- loc, idxTy, builder.getIntegerAttr(idxTy, 1));
- auto loop = builder.create<fir::DoLoopOp>(loc, lb, ub, step,
- /*unordered=*/false);
- builder.setInsertionPointToStart(loop.getBody());
- loops.push_back(loop);
- ivs.push_back(loop.getInductionVar());
+ ty = fir::unwrapRefType(ty);
+ if (fir::isa_trivial(ty)) {
+ mlir::Value initValue = builder.create<fir::LoadOp>(
+ loc, recipe.getCopyRegion().front().getArgument(0));
+ builder.create<fir::StoreOp>(loc, initValue,
+ recipe.getCopyRegion().front().getArgument(1));
+ } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(ty)) {
+ if (seqTy.hasDynamicExtents())
+ TODO(loc, "private recipe of array with dynamic extents");
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
+ mlir::Value arraySrc = recipe.getCopyRegion().front().getArgument(0);
+ mlir::Value arrayDst = recipe.getCopyRegion().front().getArgument(1);
+ llvm::SmallVector<fir::DoLoopOp> loops;
+ llvm::SmallVector<mlir::Value> ivs;
+ for (auto ext : llvm::reverse(seqTy.getShape())) {
+ auto lb = builder.create<mlir::arith::ConstantOp>(
+ loc, idxTy, builder.getIntegerAttr(idxTy, 0));
+ auto ub = builder.create<mlir::arith::ConstantOp>(
+ loc, idxTy, builder.getIntegerAttr(idxTy, ext - 1));
+ auto step = builder.create<mlir::arith::ConstantOp>(
+ loc, idxTy, builder.getIntegerAttr(idxTy, 1));
+ auto loop = builder.create<fir::DoLoopOp>(loc, lb, ub, step,
+ /*unordered=*/false);
+ builder.setInsertionPointToStart(loop.getBody());
+ loops.push_back(loop);
+ ivs.push_back(loop.getInductionVar());
+ }
+ auto addr1 = builder.create<fir::CoordinateOp>(loc, refTy, arraySrc, ivs);
+ auto addr2 = builder.create<fir::CoordinateOp>(loc, refTy, arrayDst, ivs);
+ auto loadedValue = builder.create<fir::LoadOp>(loc, addr1);
+ builder.create<fir::StoreOp>(loc, loadedValue, addr2);
+ builder.setInsertionPointAfter(loops[0]);
+ } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) {
+ fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
+ llvm::SmallVector<mlir::Value> tripletArgs;
+ mlir::Type innerTy = extractSequenceType(boxTy);
+ fir::SequenceType seqTy =
+ mlir::dyn_cast_or_null<fir::SequenceType>(innerTy);
+ if (!seqTy)
+ TODO(loc, "Unsupported boxed type in OpenACC reduction");
+
+ if (allConstantBound) {
+ for (auto bound : llvm::reverse(bounds)) {
+ auto dataBound =
+ mlir::cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
+ tripletArgs.append(genConstantBounds(firBuilder, loc, dataBound));
}
- auto addr1 = builder.create<fir::CoordinateOp>(loc, refTy, arraySrc, ivs);
- auto addr2 = builder.create<fir::CoordinateOp>(loc, refTy, arrayDst, ivs);
- auto loadedValue = builder.create<fir::LoadOp>(loc, addr1);
- builder.create<fir::StoreOp>(loc, loadedValue, addr2);
- builder.setInsertionPointAfter(loops[0]);
+ } else {
+ assert(((recipe.getCopyRegion().getArguments().size() - 2) / 3 ==
+ seqTy.getDimension()) &&
+ "Expect 3 block arguments per dimension");
+ for (auto arg : recipe.getCopyRegion().getArguments().drop_front(2))
+ tripletArgs.push_back(arg);
}
+ auto shape = genShapeFromBounds(loc, firBuilder, tripletArgs);
+ hlfir::DesignateOp::Subscripts triplets;
+ for (unsigned i = 2; i < recipe.getCopyRegion().getArguments().size();
+ i += 3)
+ triplets.emplace_back(hlfir::DesignateOp::Triplet{
+ recipe.getCopyRegion().getArgument(i),
+ recipe.getCopyRegion().getArgument(i + 1),
+ recipe.getCopyRegion().getArgument(i + 2)});
+
+ llvm::SmallVector<mlir::Value> lenParamsLeft;
+ auto leftEntity = hlfir::Entity{recipe.getCopyRegion().getArgument(0)};
+ hlfir::genLengthParameters(loc, firBuilder, leftEntity, lenParamsLeft);
+ auto leftDesignate = firBuilder.create<hlfir::DesignateOp>(
+ loc, leftEntity.getBase().getType(), leftEntity, /*component=*/"",
+ /*componentShape=*/mlir::Value{}, triplets,
+ /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt,
+ shape, lenParamsLeft);
+ auto left = hlfir::Entity{leftDesignate.getResult()};
+
+ llvm::SmallVector<mlir::Value> lenParamsRight;
+ auto rightEntity = hlfir::Entity{recipe.getCopyRegion().getArgument(1)};
+ hlfir::genLengthParameters(loc, firBuilder, rightEntity, lenParamsRight);
+ auto rightDesignate = firBuilder.create<hlfir::DesignateOp>(
+ loc, rightEntity.getBase().getType(), rightEntity, /*component=*/"",
+ /*componentShape=*/mlir::Value{}, triplets,
+ /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt,
+ shape, lenParamsRight);
+ auto right = hlfir::Entity{rightDesignate.getResult()};
+ firBuilder.create<hlfir::AssignOp>(loc, left, right);
}
+
builder.create<mlir::acc::TerminatorOp>(loc);
builder.restoreInsertionPoint(crtPos);
return recipe;
@@ -584,10 +717,12 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
/*implicit=*/false, mlir::acc::DataClause::acc_private, retTy);
dataOperands.push_back(op.getAccPtr());
} else {
+ std::string suffix =
+ areAllBoundConstant(bounds) ? getBoundsString(bounds) : "";
std::string recipeName = fir::getTypeAsString(
- retTy, converter.getKindMap(), "firstprivatization");
+ retTy, converter.getKindMap(), "firstprivatization" + suffix);
recipe = Fortran::lower::createOrGetFirstprivateRecipe(
- builder, recipeName, operandLocation, retTy);
+ builder, recipeName, operandLocation, retTy, bounds);
auto op = createDataEntryOp<mlir::acc::FirstprivateOp>(
builder, operandLocation, baseAddr, asFortran, bounds, true,
/*implicit=*/false, mlir::acc::DataClause::acc_firstprivate, retTy);
@@ -683,29 +818,6 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
llvm_unreachable("OpenACC reduction unsupported type");
}
-/// Check if the DataBoundsOp is a constant bound (lb and ub are constants or
-/// extent is a constant).
-bool isConstantBound(mlir::acc::DataBoundsOp &op) {
- if (op.getLowerbound() && fir::getIntIfConstant(op.getLowerbound()) &&
- op.getUpperbound() && fir::getIntIfConstant(op.getUpperbound()))
- return true;
- if (op.getExtent() && fir::getIntIfConstant(op.getExtent()))
- return true;
- return false;
-}
-
-/// Return true iff all the bounds are expressed with constant values.
-bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
- for (auto bound : bounds) {
- auto dataBound =
- mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
- assert(dataBound && "Must be DataBoundOp operation");
- if (!isConstantBound(dataBound))
- return false;
- }
- return true;
-}
-
/// Return a constant with the initial value for the reduction operator and
/// type combination.
static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
@@ -911,52 +1023,6 @@ static mlir::Value genScalarCombiner(fir::FirOpBuilder &builder,
TODO(loc, "reduction operator");
}
-static fir::ShapeOp
-genShapeFromBounds(mlir::Location loc, fir::FirOpBuilder &builder,
- const llvm::SmallVector<mlir::Value> &args) {
- assert(args.size() % 3 == 0 && "Triplets must be a multiple of 3");
- llvm::SmallVector<mlir::Value> extents;
- mlir::Type idxTy = builder.getIndexType();
- mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
- mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0);
- for (unsigned i = 0; i < args.size(); i += 3) {
- mlir::Value s1 =
- builder.create<mlir::arith::SubIOp>(loc, args[i + 1], args[0]);
- mlir::Value s2 = builder.create<mlir::arith::AddIOp>(loc, s1, one);
- mlir::Value s3 = builder.create<mlir::arith::DivSIOp>(loc, s2, args[i + 2]);
- mlir::Value cmp = builder.create<mlir::arith::CmpIOp>(
- loc, mlir::arith::CmpIPredicate::sgt, s3, zero);
- mlir::Value ext = builder.create<mlir::arith::SelectOp>(loc, cmp, s3, zero);
- extents.push_back(ext);
- }
- return builder.create<fir::ShapeOp>(loc, extents);
-}
-
-static llvm::SmallVector<mlir::Value>
-genConstantBounds(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::acc::DataBoundsOp &dataBound) {
- mlir::Type idxTy = builder.getIndexType();
- mlir::Value lb, ub, step;
- if (dataBound.getLowerbound() &&
- fir::getIntIfConstant(dataBound.getLowerbound()) &&
- dataBound.getUpperbound() &&
- fir::getIntIfConstant(dataBound.getUpperbound())) {
- lb = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getLowerbound()));
- ub = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getUpperbound()));
- step = builder.createIntegerConstant(loc, idxTy, 1);
- } else if (dataBound.getExtent()) {
- lb = builder.createIntegerConstant(loc, idxTy, 0);
- ub = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getExtent()) - 1);
- step = builder.createIntegerConstant(loc, idxTy, 1);
- } else {
- llvm::report_fatal_error("Expect constant lb/ub or extent");
- }
- return {lb, ub, step};
-}
-
static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::acc::ReductionOperator op, mlir::Type ty,
mlir::Value value1, mlir::Value value2,
diff --git a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
index 22726b0f4909414..ac028fcf877b4a3 100644
--- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
@@ -3,7 +3,7 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK,HLFIR
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_ext10_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
@@ -514,7 +514,7 @@ subroutine acc_parallel_loop
! HLFIR: %[[ACC_PRIVATE_A:.*]] = acc.private varPtr(%[[DECLA]]#1 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
! FIR: %[[ACC_PRIVATE_B:.*]] = acc.firstprivate varPtr(%[[B]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
! HLFIR: %[[ACC_PRIVATE_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#1 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
-! CHECK: acc.parallel firstprivate(@firstprivatization_ref_10xf32 -> %[[ACC_PRIVATE_B]] : !fir.ref<!fir.array<10xf32>>) private(@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>) {
+! CHECK: acc.parallel firstprivate(@firstprivatization_section_ext10_ref_10xf32 -> %[[ACC_PRIVATE_B]] : !fir.ref<!fir.array<10xf32>>) private(@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>) {
! FIR: %[[ACC_PRIVATE_A:.*]] = acc.private varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
! HLFIR: %[[ACC_PRIVATE_A:.*]] = acc.private varPtr(%[[DECLA]]#1 : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
! CHECK: acc.loop private(@privatization_ref_10xf32 -> %[[ACC_PRIVATE_A]] : !fir.ref<!fir.array<10xf32>>) {
diff --git a/flang/test/Lower/OpenACC/acc-parallel.f90 b/flang/test/Lower/OpenACC/acc-parallel.f90
index cdde9128d70c9be..56f225b7b603fa4 100644
--- a/flang/test/Lower/OpenACC/acc-parallel.f90
+++ b/flang/test/Lower/OpenACC/acc-parallel.f90
@@ -3,7 +3,7 @@
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefixes=CHECK,HLFIR
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_ext10xext10_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
@@ -371,7 +371,7 @@ subroutine acc_parallel
! HLFIR: %[[ACC_FPRIVATE_B:.*]] = acc.firstprivate varPtr(%[...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me!
3b377f7
to
7309df5
Compare
Add support for assumed shape arrays in lowering of the copy region of the firstprivate recipe. Information is passed in block arguments as it is done for the reduction recipe.