[flang-commits] [flang] a0406ce - [flang][OpenMP] Add `hostIsSource` paramemter to `copyHostAssociateVar` (#123162)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 16 10:10:16 PST 2025
Author: Kareem Ergawy
Date: 2025-01-16T19:10:12+01:00
New Revision: a0406ce823e8f1c1993b565d08b045c0104c3a5a
URL: https://github.com/llvm/llvm-project/commit/a0406ce823e8f1c1993b565d08b045c0104c3a5a
DIFF: https://github.com/llvm/llvm-project/commit/a0406ce823e8f1c1993b565d08b045c0104c3a5a.diff
LOG: [flang][OpenMP] Add `hostIsSource` paramemter to `copyHostAssociateVar` (#123162)
This fixes a bug when the same variable is used in `firstprivate` and
`lastprivate` clauses on the same construct. The issue boils down to the
fact that `copyHostAssociateVar` was deciding the direction of the copy
assignment (i.e. the `lhs` and `rhs`) based on whether the
`copyAssignIP`
parameter is set. This is not the best way to do it since it is not
related to whether we doing a copy from host to localized copy or the
other way around. When we set the insertion for `firstprivate` in
delayed privatization, this resulted in switching the direction of the
copy assignment. Instead, this PR adds a new paramter to explicitely
tell
the function the direction of the assignment.
This is a follow up PR for
https://github.com/llvm/llvm-project/pull/122471, only the latest commit
is relevant.
Added:
flang/test/Lower/OpenMP/same_var_first_lastprivate.f90
Modified:
flang/include/flang/Lower/AbstractConverter.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
flang/lib/Lower/OpenMP/OpenMP.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h
index 607aff41f64595..c24f43737df50a 100644
--- a/flang/include/flang/Lower/AbstractConverter.h
+++ b/flang/include/flang/Lower/AbstractConverter.h
@@ -130,9 +130,18 @@ class AbstractConverter {
virtual void
createHostAssociateVarCloneDealloc(const Fortran::semantics::Symbol &sym) = 0;
- virtual void copyHostAssociateVar(
- const Fortran::semantics::Symbol &sym,
- mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) = 0;
+ /// For a host-associated symbol (a symbol associated with another symbol from
+ /// an enclosing scope), either:
+ ///
+ /// * if \p hostIsSource == true: copy \p sym's value *from* its corresponding
+ /// host symbol,
+ ///
+ /// * if \p hostIsSource == false: copy \p sym's value *to* its corresponding
+ /// host symbol.
+ virtual void
+ copyHostAssociateVar(const Fortran::semantics::Symbol &sym,
+ mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr,
+ bool hostIsSource = true) = 0;
virtual void copyVar(mlir::Location loc, mlir::Value dst, mlir::Value src,
fir::FortranVariableFlagsEnum attrs) = 0;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 37f51d74d23f8f..700ca56141a324 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -891,9 +891,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
isPointer, Fortran::semantics::Symbol::Flags());
}
- void copyHostAssociateVar(
- const Fortran::semantics::Symbol &sym,
- mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr) override final {
+ void
+ copyHostAssociateVar(const Fortran::semantics::Symbol &sym,
+ mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr,
+ bool hostIsSource = true) override final {
// 1) Fetch the original copy of the variable.
assert(sym.has<Fortran::semantics::HostAssocDetails>() &&
"No host-association found");
@@ -908,16 +909,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
"Host and associated symbol boxes are the same");
// 3) Perform the assignment.
- mlir::OpBuilder::InsertPoint insPt = builder->saveInsertionPoint();
+ mlir::OpBuilder::InsertionGuard guard(*builder);
if (copyAssignIP && copyAssignIP->isSet())
builder->restoreInsertionPoint(*copyAssignIP);
else
builder->setInsertionPointAfter(sb.getAddr().getDefiningOp());
Fortran::lower::SymbolBox *lhs_sb, *rhs_sb;
- if (copyAssignIP && copyAssignIP->isSet() &&
- sym.test(Fortran::semantics::Symbol::Flag::OmpLastPrivate)) {
- // lastprivate case
+ if (!hostIsSource) {
lhs_sb = &hsb;
rhs_sb = &sb;
} else {
@@ -926,11 +925,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
copyVar(sym, *lhs_sb, *rhs_sb, sym.flags());
-
- if (copyAssignIP && copyAssignIP->isSet() &&
- sym.test(Fortran::semantics::Symbol::Flag::OmpLastPrivate)) {
- builder->restoreInsertionPoint(insPt);
- }
}
void genEval(Fortran::lower::pft::Evaluation &eval,
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index 9dfdbd8337ae91..5b89816850beda 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -145,7 +145,7 @@ void DataSharingProcessor::copyFirstPrivateSymbol(
void DataSharingProcessor::copyLastPrivateSymbol(
const semantics::Symbol *sym, mlir::OpBuilder::InsertPoint *lastPrivIP) {
if (sym->test(semantics::Symbol::Flag::OmpLastPrivate))
- converter.copyHostAssociateVar(*sym, lastPrivIP);
+ converter.copyHostAssociateVar(*sym, lastPrivIP, /*hostIsSource=*/false);
}
void DataSharingProcessor::collectOmpObjectListSymbol(
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index a02ad27d33e067..52541bb91481d4 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2082,7 +2082,7 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
const auto &objList = std::get<ObjectList>(lastp->t);
for (const Object &object : objList) {
semantics::Symbol *sym = object.sym();
- converter.copyHostAssociateVar(*sym, &insp);
+ converter.copyHostAssociateVar(*sym, &insp, /*hostIsSource=*/false);
}
}
}
diff --git a/flang/test/Lower/OpenMP/same_var_first_lastprivate.f90 b/flang/test/Lower/OpenMP/same_var_first_lastprivate.f90
new file mode 100644
index 00000000000000..c49a0908b721e6
--- /dev/null
+++ b/flang/test/Lower/OpenMP/same_var_first_lastprivate.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck %s
+
+subroutine first_and_lastprivate
+ integer i
+ integer :: var = 1
+
+ !$omp parallel do firstprivate(var) lastprivate(var)
+ do i=1,1
+ end do
+ !$omp end parallel do
+end subroutine
+
+! CHECK: omp.private {type = firstprivate} @{{.*}}Evar_firstprivate_ref_i32 : {{.*}} alloc {
+! CHECK: %[[ALLOC:.*]] = fir.alloca i32 {{.*}}
+! CHECK: %[[ALLOC_DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
+! CHECK: omp.yield(%[[ALLOC_DECL]]#0 : !fir.ref<i32>)
+! CHECK: } copy {
+! CHECK: ^{{.*}}(%[[ORIG_REF:.*]]: {{.*}}, %[[PRIV_REF:.*]]: {{.*}}):
+! CHECK: %[[ORIG_VAL:.*]] = fir.load %[[ORIG_REF]]
+! CHECK: hlfir.assign %[[ORIG_VAL]] to %[[PRIV_REF]]
+! CHECK: omp.yield(%[[PRIV_REF]] : !fir.ref<i32>)
+! CHECK: }
+
+! CHECK: func.func @{{.*}}first_and_lastprivate()
+! CHECK: %[[ORIG_VAR_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "{{.*}}Evar"}
+! CHECK: omp.parallel {
+! CHECK: omp.barrier
+! CHECK: omp.wsloop private(@{{.*}}var_firstprivate_ref_i32 {{.*}}) {
+! CHECK: omp.loop_nest {{.*}} {
+! CHECK: %[[PRIV_VAR_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "{{.*}}Evar"}
+! CHECK: fir.if %{{.*}} {
+! CHECK: %[[PRIV_VAR_VAL:.*]] = fir.load %[[PRIV_VAR_DECL]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[PRIV_VAR_VAL]] to %[[ORIG_VAR_DECL]]#0
+! CHECK: }
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
More information about the flang-commits
mailing list