Skip to content

Commit 9cf8752

Browse files
authored
[flang][OpenMP] Handle symbols on composite simd with multiple privatizers (#155640)
In some cases, a clause on a composite simd construct applied to simd can be using a symbol that is also used by another privatizer, not applied to simd. Correctly handle this scenario by checking which directive the privatizer is being generated for while determining whether to emit the copy region. Fixes #155195. Signed-off-by: Kajetan Puchalski <[email protected]>
1 parent 1f67b94 commit 9cf8752

File tree

6 files changed

+49
-15
lines changed

6 files changed

+49
-15
lines changed

flang/include/flang/Lower/Support/Utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ void privatizeSymbol(
102102
lower::SymMap &symTable,
103103
llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
104104
llvm::SmallPtrSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
105-
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps);
105+
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps,
106+
std::optional<llvm::omp::Directive> dir = std::nullopt);
106107

107108
} // end namespace Fortran::lower
108109

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,14 @@ DataSharingProcessor::DataSharingProcessor(lower::AbstractConverter &converter,
9090
isTargetPrivatization) {}
9191

9292
void DataSharingProcessor::processStep1(
93-
mlir::omp::PrivateClauseOps *clauseOps) {
93+
mlir::omp::PrivateClauseOps *clauseOps,
94+
std::optional<llvm::omp::Directive> dir) {
9495
collectSymbolsForPrivatization();
9596
collectDefaultSymbols();
9697
collectImplicitSymbols();
9798
collectPreDeterminedSymbols();
9899

99-
privatize(clauseOps);
100+
privatize(clauseOps, dir);
100101

101102
insertBarrier(clauseOps);
102103
}
@@ -581,14 +582,15 @@ void DataSharingProcessor::collectPreDeterminedSymbols() {
581582
preDeterminedSymbols);
582583
}
583584

584-
void DataSharingProcessor::privatize(mlir::omp::PrivateClauseOps *clauseOps) {
585+
void DataSharingProcessor::privatize(mlir::omp::PrivateClauseOps *clauseOps,
586+
std::optional<llvm::omp::Directive> dir) {
585587
for (const semantics::Symbol *sym : allPrivatizedSymbols) {
586588
if (const auto *commonDet =
587589
sym->detailsIf<semantics::CommonBlockDetails>()) {
588590
for (const auto &mem : commonDet->objects())
589-
privatizeSymbol(&*mem, clauseOps);
591+
privatizeSymbol(&*mem, clauseOps, dir);
590592
} else
591-
privatizeSymbol(sym, clauseOps);
593+
privatizeSymbol(sym, clauseOps, dir);
592594
}
593595
}
594596

@@ -607,7 +609,8 @@ void DataSharingProcessor::copyLastPrivatize(mlir::Operation *op) {
607609

608610
void DataSharingProcessor::privatizeSymbol(
609611
const semantics::Symbol *symToPrivatize,
610-
mlir::omp::PrivateClauseOps *clauseOps) {
612+
mlir::omp::PrivateClauseOps *clauseOps,
613+
std::optional<llvm::omp::Directive> dir) {
611614
if (!useDelayedPrivatization) {
612615
cloneSymbol(symToPrivatize);
613616
copyFirstPrivateSymbol(symToPrivatize);
@@ -617,7 +620,7 @@ void DataSharingProcessor::privatizeSymbol(
617620
Fortran::lower::privatizeSymbol<mlir::omp::PrivateClauseOp,
618621
mlir::omp::PrivateClauseOps>(
619622
converter, firOpBuilder, symTable, allPrivatizedSymbols,
620-
mightHaveReadHostSym, symToPrivatize, clauseOps);
623+
mightHaveReadHostSym, symToPrivatize, clauseOps, dir);
621624
}
622625
} // namespace omp
623626
} // namespace lower

flang/lib/Lower/OpenMP/DataSharingProcessor.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ class DataSharingProcessor {
126126
void collectDefaultSymbols();
127127
void collectImplicitSymbols();
128128
void collectPreDeterminedSymbols();
129-
void privatize(mlir::omp::PrivateClauseOps *clauseOps);
129+
void privatize(mlir::omp::PrivateClauseOps *clauseOps,
130+
std::optional<llvm::omp::Directive> dir = std::nullopt);
130131
void copyLastPrivatize(mlir::Operation *op);
131132
void insertLastPrivateCompare(mlir::Operation *op);
132133
void cloneSymbol(const semantics::Symbol *sym);
@@ -167,7 +168,8 @@ class DataSharingProcessor {
167168
// Step2 performs the copying for lastprivates and requires knowledge of the
168169
// MLIR operation to insert the last private update. Step2 adds
169170
// dealocation code as well.
170-
void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr);
171+
void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr,
172+
std::optional<llvm::omp::Directive> dir = std::nullopt);
171173
void processStep2(mlir::Operation *op, bool isLoop);
172174

173175
void pushLoopIV(mlir::Value iv) { loopIVs.push_back(iv); }
@@ -184,7 +186,8 @@ class DataSharingProcessor {
184186
}
185187

186188
void privatizeSymbol(const semantics::Symbol *symToPrivatize,
187-
mlir::omp::PrivateClauseOps *clauseOps);
189+
mlir::omp::PrivateClauseOps *clauseOps,
190+
std::optional<llvm::omp::Directive> dir = std::nullopt);
188191
};
189192

190193
} // namespace omp

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3257,7 +3257,7 @@ static mlir::omp::WsloopOp genCompositeDoSimd(
32573257
DataSharingProcessor simdItemDSP(converter, semaCtx, simdItem->clauses, eval,
32583258
/*shouldCollectPreDeterminedSymbols=*/true,
32593259
/*useDelayedPrivatization=*/true, symTable);
3260-
simdItemDSP.processStep1(&simdClauseOps);
3260+
simdItemDSP.processStep1(&simdClauseOps, simdItem->id);
32613261

32623262
// Pass the innermost leaf construct's clauses because that's where COLLAPSE
32633263
// is placed by construct decomposition.

flang/lib/Lower/Support/Utils.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ void privatizeSymbol(
655655
lower::SymMap &symTable,
656656
llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
657657
llvm::SmallPtrSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
658-
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps) {
658+
const semantics::Symbol *symToPrivatize, OperandsStructType *clauseOps,
659+
std::optional<llvm::omp::Directive> dir) {
659660
constexpr bool isDoConcurrent =
660661
std::is_same_v<OpType, fir::LocalitySpecifierOp>;
661662
mlir::OpBuilder::InsertPoint dcIP;
@@ -676,6 +677,13 @@ void privatizeSymbol(
676677
bool emitCopyRegion =
677678
symToPrivatize->test(semantics::Symbol::Flag::OmpFirstPrivate) ||
678679
symToPrivatize->test(semantics::Symbol::Flag::LocalityLocalInit);
680+
// A symbol attached to the simd directive can have the firstprivate flag set
681+
// on it when it is also used in a non-firstprivate privatization clause.
682+
// For instance: $omp do simd lastprivate(a) firstprivate(a)
683+
// We cannot apply the firstprivate privatizer to simd, so make sure we do
684+
// not emit the copy region when dealing with the SIMD directive.
685+
if (dir && dir == llvm::omp::Directive::OMPD_simd)
686+
emitCopyRegion = false;
679687

680688
mlir::Value privVal = hsb.getAddr();
681689
mlir::Type allocType = privVal.getType();
@@ -848,7 +856,8 @@ privatizeSymbol<mlir::omp::PrivateClauseOp, mlir::omp::PrivateClauseOps>(
848856
llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
849857
llvm::SmallPtrSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
850858
const semantics::Symbol *symToPrivatize,
851-
mlir::omp::PrivateClauseOps *clauseOps);
859+
mlir::omp::PrivateClauseOps *clauseOps,
860+
std::optional<llvm::omp::Directive> dir);
852861

853862
template void
854863
privatizeSymbol<fir::LocalitySpecifierOp, fir::LocalitySpecifierOperands>(
@@ -857,6 +866,7 @@ privatizeSymbol<fir::LocalitySpecifierOp, fir::LocalitySpecifierOperands>(
857866
llvm::SetVector<const semantics::Symbol *> &allPrivatizedSymbols,
858867
llvm::SmallPtrSet<const semantics::Symbol *, 16> &mightHaveReadHostSym,
859868
const semantics::Symbol *symToPrivatize,
860-
fir::LocalitySpecifierOperands *clauseOps);
869+
fir::LocalitySpecifierOperands *clauseOps,
870+
std::optional<llvm::omp::Directive> dir);
861871

862872
} // end namespace Fortran::lower

flang/test/Lower/OpenMP/wsloop-simd.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,20 @@ subroutine do_simd_private()
8585
tmp = tmp + 1
8686
end do
8787
end subroutine do_simd_private
88+
89+
! CHECK-LABEL: func.func @_QPdo_simd_lastprivate_firstprivate(
90+
subroutine do_simd_lastprivate_firstprivate()
91+
integer :: a
92+
! CHECK: omp.wsloop
93+
! CHECK-SAME: private(@[[FIRSTPRIVATE_A_SYM:.*]] %{{.*}} -> %[[FIRSTPRIVATE_A:.*]] : !fir.ref<i32>)
94+
! CHECK-NEXT: omp.simd
95+
! CHECK-SAME: private(@[[PRIVATE_A_SYM:.*]] %{{.*}} -> %[[PRIVATE_A:.*]], @[[PRIVATE_I_SYM:.*]] %{{.*}} -> %[[PRIVATE_I:.*]] : !fir.ref<i32>, !fir.ref<i32>)
96+
!$omp do simd lastprivate(a) firstprivate(a)
97+
do i = 1, 10
98+
! CHECK: %[[FIRSTPRIVATE_A_DECL:.*]]:2 = hlfir.declare %[[FIRSTPRIVATE_A]]
99+
! CHECK: %[[PRIVATE_A_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_A]]
100+
! CHECK: %[[PRIVATE_I_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_I]]
101+
a = a + 1
102+
end do
103+
!$omp end do simd
104+
end subroutine do_simd_lastprivate_firstprivate

0 commit comments

Comments
 (0)