[Mlir-commits] [mlir] [flang][openacc] Support array with dynamic extents in firstprivate recipe (PR #69026)
Valentin Clement バレンタイン クレメン
llvmlistbot at llvm.org
Fri Oct 13 14:23:20 PDT 2023
https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/69026
>From d6b184bd042354b2e6729475c72ae4cf324b61cb Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Fri, 13 Oct 2023 13:37:52 -0700
Subject: [PATCH 1/2] [flang][openacc] Support array with dynamic extents in
firstprivate recipe
---
flang/lib/Lower/OpenACC.cpp | 174 ++++++++++--------
.../test/Lower/OpenACC/acc-parallel-loop.f90 | 27 ---
flang/test/Lower/OpenACC/acc-private.f90 | 60 ++++--
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp | 2 +-
4 files changed, 139 insertions(+), 124 deletions(-)
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 61a1b9fd86717cb..b020415be418e09 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -463,7 +463,7 @@ bool isConstantBound(mlir::acc::DataBoundsOp &op) {
}
/// Return true iff all the bounds are expressed with constant values.
-bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
+bool areAllBoundConstant(const llvm::SmallVector<mlir::Value> &bounds) {
for (auto bound : bounds) {
auto dataBound =
mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
@@ -474,27 +474,6 @@ bool areAllBoundConstant(llvm::SmallVector<mlir::Value> &bounds) {
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) {
@@ -520,6 +499,63 @@ genConstantBounds(fir::FirOpBuilder &builder, mlir::Location loc,
return {lb, ub, step};
}
+static fir::ShapeOp genShapeFromBoundsOrArgs(
+ mlir::Location loc, fir::FirOpBuilder &builder, fir::SequenceType seqTy,
+ const llvm::SmallVector<mlir::Value> &bounds, mlir::ValueRange arguments) {
+ llvm::SmallVector<mlir::Value> args;
+ if (areAllBoundConstant(bounds)) {
+ for (auto bound : llvm::reverse(bounds)) {
+ auto dataBound =
+ mlir::cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
+ args.append(genConstantBounds(builder, loc, dataBound));
+ }
+ } else {
+ assert(((arguments.size() - 2) / 3 == seqTy.getDimension()) &&
+ "Expect 3 block arguments per dimension");
+ for (auto arg : arguments.drop_front(2))
+ args.push_back(arg);
+ }
+
+ 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 hlfir::DesignateOp::Subscripts
+getSubscriptsFromArgs(mlir::ValueRange args) {
+ hlfir::DesignateOp::Subscripts triplets;
+ for (unsigned i = 2; i < args.size(); i += 3)
+ triplets.emplace_back(
+ hlfir::DesignateOp::Triplet{args[i], args[i + 1], args[i + 2]});
+ return triplets;
+}
+
+static hlfir::Entity genDesignateWithTriplets(
+ fir::FirOpBuilder &builder, mlir::Location loc, hlfir::Entity &entity,
+ hlfir::DesignateOp::Subscripts &triplets, mlir::Value shape) {
+ llvm::SmallVector<mlir::Value> lenParams;
+ hlfir::genLengthParameters(loc, builder, entity, lenParams);
+ auto designate = builder.create<hlfir::DesignateOp>(
+ loc, entity.getBase().getType(), entity, /*component=*/"",
+ /*componentShape=*/mlir::Value{}, triplets,
+ /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt, shape,
+ lenParams);
+ return hlfir::Entity{designate.getResult()};
+}
+
mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
mlir::OpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
mlir::Type ty, llvm::SmallVector<mlir::Value> &bounds) {
@@ -533,8 +569,20 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
mlir::OpBuilder modBuilder(mod.getBodyRegion());
auto recipe =
modBuilder.create<mlir::acc::FirstprivateRecipeOp>(loc, recipeName, ty);
+ llvm::SmallVector<mlir::Type> initArgsTy{ty};
+ llvm::SmallVector<mlir::Location> initArgsLoc{loc};
+ auto refTy = fir::unwrapRefType(ty);
+ if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(refTy)) {
+ if (seqTy.hasDynamicExtents()) {
+ mlir::Type idxTy = builder.getIndexType();
+ for (unsigned i = 0; i < seqTy.getDimension(); ++i) {
+ initArgsTy.push_back(idxTy);
+ initArgsLoc.push_back(loc);
+ }
+ }
+ }
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
- {ty}, {loc});
+ initArgsTy, initArgsLoc);
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
genPrivateLikeInitRegion<mlir::acc::FirstprivateRecipeOp>(builder, recipe, ty,
loc);
@@ -565,32 +613,28 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
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, "firstprivate 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]);
+ fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
+ auto shape = genShapeFromBoundsOrArgs(
+ loc, firBuilder, seqTy, bounds, recipe.getCopyRegion().getArguments());
+
+ auto leftDeclOp = builder.create<hlfir::DeclareOp>(
+ loc, recipe.getCopyRegion().getArgument(0), llvm::StringRef{}, shape,
+ llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
+ auto rightDeclOp = builder.create<hlfir::DeclareOp>(
+ loc, recipe.getCopyRegion().getArgument(1), llvm::StringRef{}, shape,
+ llvm::ArrayRef<mlir::Value>{}, fir::FortranVariableFlagsAttr{});
+
+ hlfir::DesignateOp::Subscripts triplets =
+ getSubscriptsFromArgs(recipe.getCopyRegion().getArguments());
+ auto leftEntity = hlfir::Entity{leftDeclOp.getBase()};
+ auto left =
+ genDesignateWithTriplets(firBuilder, loc, leftEntity, triplets, shape);
+ auto rightEntity = hlfir::Entity{rightDeclOp.getBase()};
+ auto right =
+ genDesignateWithTriplets(firBuilder, loc, rightEntity, triplets, shape);
+
+ firBuilder.create<hlfir::AssignOp>(loc, left, right);
+
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(ty)) {
fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
llvm::SmallVector<mlir::Value> tripletArgs;
@@ -600,20 +644,8 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
if (!seqTy)
TODO(loc, "Unsupported boxed type in OpenACC firstprivate");
- if (allConstantBound) {
- for (auto bound : llvm::reverse(bounds)) {
- auto dataBound =
- mlir::cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
- tripletArgs.append(genConstantBounds(firBuilder, loc, dataBound));
- }
- } 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);
+ auto shape = genShapeFromBoundsOrArgs(
+ loc, firBuilder, seqTy, bounds, recipe.getCopyRegion().getArguments());
hlfir::DesignateOp::Subscripts triplets;
for (unsigned i = 2; i < recipe.getCopyRegion().getArguments().size();
i += 3)
@@ -1110,20 +1142,8 @@ static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
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(builder, loc, dataBound));
- }
- } else {
- assert(((recipe.getCombinerRegion().getArguments().size() - 2) / 3 ==
- seqTy.getDimension()) &&
- "Expect 3 block arguments per dimension");
- for (auto arg : recipe.getCombinerRegion().getArguments().drop_front(2))
- tripletArgs.push_back(arg);
- }
- auto shape = genShapeFromBounds(loc, builder, tripletArgs);
+ auto shape = genShapeFromBoundsOrArgs(
+ loc, builder, seqTy, bounds, recipe.getCombinerRegion().getArguments());
hlfir::DesignateOp::Subscripts triplets;
for (unsigned i = 2; i < recipe.getCombinerRegion().getArguments().size();
diff --git a/flang/test/Lower/OpenACC/acc-parallel-loop.f90 b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
index 9a27a359e80b73b..80b1272bd1b10b6 100644
--- a/flang/test/Lower/OpenACC/acc-parallel-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-parallel-loop.f90
@@ -3,33 +3,6 @@
! 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_section_ext10_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<10xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<10xf32>>):
-! CHECK: %[[LB0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB0:.*]] = arith.constant 9 : index
-! CHECK: %[[STEP0:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] {
-! CHECK: %[[COORD0:.*]] = fir.coordinate_of %[[SRC]], %[[IV0]] : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[DST]], %[[IV0]] : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[LOAD:.*]] = fir.load %[[COORD0]] : !fir.ref<f32>
-! CHECK: fir.store %[[LOAD]] to %[[COORD1]] : !fir.ref<f32>
-! CHECK: }
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
-! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! HLFIR: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
-! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
-! CHECK: }
-
! CHECK-LABEL: func.func @_QPacc_parallel_loop()
subroutine acc_parallel_loop
diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90
index 10c1bfc7c3802a3..9ce1828e63ddf10 100644
--- a/flang/test/Lower/OpenACC/acc-private.f90
+++ b/flang/test/Lower/OpenACC/acc-private.f90
@@ -3,6 +3,23 @@
! 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_UxUx2xi32 : !fir.ref<!fir.array<?x?x2xi32>> init {
+! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.array<?x?x2xi32>>, %[[ARG1:.*]]: index, %[[ARG2:.*]]: index, %[[ARG3:.*]]: index):
+! HLFIR: %[[SHAPE:.*]] = fir.shape %[[ARG1]], %[[ARG2]], %[[ARG3]] : (index, index, index) -> !fir.shape<3>
+! HLFIR: %[[TEMP:.*]] = fir.alloca !fir.array<?x?x2xi32>, %[[ARG1]], %[[ARG2]], %[[ARG3]]
+! HLFIR: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.ref<!fir.array<?x?x2xi32>>)
+! HLFIR: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?x2xi32>>
+! CHECK: } copy {
+! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<?x?x2xi32>>, %[[DST:.*]]: !fir.ref<!fir.array<?x?x2xi32>>, %[[LB0:.*]]: index, %[[UB0:.*]]: index, %[[STEP0:.*]]: index, %[[LB1:.*]]: index, %[[UB1:.*]]: index, %[[STEP1:.*]]: index, %[[LB2:.*]]: index, %[[UB2:.*]]: index, %[[STEP2:.*]]: index):
+! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shape<3>
+! HLFIR: %[[DECL_SRC:.*]]:2 = hlfir.declare %[[SRC]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.ref<!fir.array<?x?x2xi32>>)
+! HLFIR: %[[DECL_DST:.*]]:2 = hlfir.declare %[[DST]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.ref<!fir.array<?x?x2xi32>>)
+! HLFIR: %[[DES_SRC:.*]] = hlfir.designate %[[DECL_SRC]]#0 (%[[LB0]]:%[[UB0]]:%[[STEP0]], %[[LB1]]:%[[UB1]]:%[[STEP1]], %[[LB2]]:%[[UB2]]:%[[STEP2]]) shape %[[SHAPE]] : (!fir.box<!fir.array<?x?x2xi32>>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.box<!fir.array<?x?x2xi32>>
+! HLFIR: %[[DES_DST:.*]] = hlfir.designate %[[DECL_DST]]#0 (%[[LB0]]:%[[UB0]]:%[[STEP0]], %[[LB1]]:%[[UB1]]:%[[STEP1]], %[[LB2]]:%[[UB2]]:%[[STEP2]]) shape %[[SHAPE]] : (!fir.box<!fir.array<?x?x2xi32>>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.box<!fir.array<?x?x2xi32>>
+! HLFIR: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.box<!fir.array<?x?x2xi32>>, !fir.box<!fir.array<?x?x2xi32>>
+! HLFIR: acc.terminator
+! CHECK: }
+
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb4.ub9_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.box<!fir.array<?xi32>>):
! CHECK: } copy {
@@ -87,16 +104,12 @@
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<50xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<50xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<50xf32>>):
-! CHECK: %[[LB0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB0:.*]] = arith.constant 49 : index
-! CHECK: %[[STEP0:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] {
-! CHECK: %[[COORD0:.*]] = fir.coordinate_of %[[SRC]], %[[IV0]] : (!fir.ref<!fir.array<50xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[DST]], %[[IV0]] : (!fir.ref<!fir.array<50xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[VALUE:.*]] = fir.load %[[COORD0]] : !fir.ref<f32>
-! CHECK: fir.store %[[VALUE]] to %[[COORD1]] : !fir.ref<f32>
-! CHECK: }
-! CHECK: acc.terminator
+! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! HLFIR: %[[DECL_SRC:.*]]:2 = hlfir.declare %[[SRC]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
+! HLFIR: %[[DECL_DST:.*]]:2 = hlfir.declare %[[DST]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
+! HLFIR: %[[DES_SRC:.*]] = hlfir.designate %[[DECL_SRC]]#0 shape %[[SHAPE:.*]] : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! HLFIR: %[[DES_DST:.*]] = hlfir.designate %[[DECL_DST]]#0 shape %[[SHAPE:.*]] : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! HLFIR: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>
! CHECK: }
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_ext100_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
@@ -107,15 +120,12 @@
! HLFIR: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<100xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<100xf32>>):
-! CHECK: %[[LB0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB0:.*]] = arith.constant 99 : index
-! CHECK: %[[STEP1:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[IV0:.*]] = %c0 to %c99 step %c1 {
-! CHECK: %[[COORD0:.*]] = fir.coordinate_of %[[SRC]], %[[IV0]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[DST]], %[[IV0]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[VALUE:.*]] = fir.load %[[COORD0]] : !fir.ref<f32>
-! CHECK: fir.store %[[VALUE]] to %[[COORD1]] : !fir.ref<f32>
-! CHECK: }
+! HLFIR: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
+! HLFIR: %[[DECL_SRC:.*]]:2 = hlfir.declare %[[SRC]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+! HLFIR: %[[DECL_DST:.*]]:2 = hlfir.declare %[[DST]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+! HLFIR: %[[DES_SRC:.*]] = hlfir.designate %[[DECL_SRC]]#0 shape %[[SHAPE]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<100xf32>>
+! HLFIR: %[[DES_DST:.*]] = hlfir.designate %[[DECL_DST]]#0 shape %[[SHAPE]] : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<100xf32>>
+! HLFIR: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>
! CHECK: acc.terminator
! CHECK: }
@@ -337,3 +347,15 @@ subroutine acc_firstprivate_assumed_shape_with_section(a, n)
a(i) = i
end do
end subroutine
+
+subroutine acc_firstprivate_dynamic_extent(a, n)
+ integer :: n, i
+ integer :: a(n, n, 2)
+
+ !$acc parallel loop firstprivate(a)
+ do i = 1, n
+ a(i, i, 1) = i
+ end do
+end subroutine
+
+! CHECK: acc.parallel firstprivate(@firstprivatization_ref_UxUx2xi32 -> %{{.*}} : !fir.ref<!fir.array<?x?x2xi32>>)
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index cea93b8a2ca8ceb..b7e2aec6a4e6a92 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -452,7 +452,7 @@ LogicalResult acc::PrivateRecipeOp::verifyRegions() {
LogicalResult acc::FirstprivateRecipeOp::verifyRegions() {
if (failed(verifyInitLikeSingleArgRegion(*this, getInitRegion(),
"privatization", "init", getType(),
- /*verifyYield=*/true)))
+ /*verifyYield=*/false)))
return failure();
if (getCopyRegion().empty())
>From c109c5c73055987ecb44699e8c0e5086a705d185 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Fri, 13 Oct 2023 14:23:06 -0700
Subject: [PATCH 2/2] Fix OpenACC mlir test
---
mlir/test/Dialect/OpenACC/invalid.mlir | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir
index 225a8766fc550f1..ff92eab478bb4f5 100644
--- a/mlir/test/Dialect/OpenACC/invalid.mlir
+++ b/mlir/test/Dialect/OpenACC/invalid.mlir
@@ -312,18 +312,6 @@ acc.firstprivate.recipe @privatization_i32 : !llvm.ptr<i32> init {
// -----
-// expected-error at +1 {{expects init region to yield a value of the privatization type}}
-acc.firstprivate.recipe @privatization_i32 : !llvm.ptr<f32> init {
-^bb0(%arg0 : !llvm.ptr<f32>):
- %c1 = arith.constant 1 : i32
- %c0 = arith.constant 0 : i32
- %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<i32>
- llvm.store %c0, %0 : !llvm.ptr<i32>
- acc.yield %0 : !llvm.ptr<i32>
-} copy {}
-
-// -----
-
// expected-error at +1 {{expects non-empty copy region}}
acc.firstprivate.recipe @privatization_i32 : !llvm.ptr<i32> init {
^bb0(%arg0 : !llvm.ptr<i32>):
More information about the Mlir-commits
mailing list