@@ -119,7 +119,7 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
119
119
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
120
120
mlir::Value scalarInitValue, mlir::Block *initBlock,
121
121
mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
122
- mlir::Region &cleanupRegion) {
122
+ mlir::Region &cleanupRegion, bool isPrivate ) {
123
123
mlir::Type ty = fir::unwrapRefType (argType);
124
124
builder.setInsertionPointToEnd (initBlock);
125
125
auto yield = [&](mlir::Value ret) {
@@ -147,11 +147,10 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
147
147
// fir.store %something to %box_alloca
148
148
// }
149
149
// omp.yield %box_alloca
150
- moldArg = builder.loadIfRef (loc, moldArg);
151
150
mlir::SmallVector<mlir::Value> lenParams;
152
- hlfir::genLengthParameters (loc, builder, hlfir::Entity{moldArg}, lenParams);
153
- auto handleNullAllocatable = [&]( mlir::Value boxAlloca ) -> fir::IfOp {
154
- mlir::Value addr = builder.create <fir::BoxAddrOp>(loc, moldArg );
151
+ auto handleNullAllocatable = [&](mlir::Value boxAlloca,
152
+ mlir::Value loadedMold ) -> fir::IfOp {
153
+ mlir::Value addr = builder.create <fir::BoxAddrOp>(loc, loadedMold );
155
154
mlir::Value isNotAllocated = builder.genIsNullAddr (loc, addr);
156
155
fir::IfOp ifOp = builder.create <fir::IfOp>(loc, isNotAllocated,
157
156
/* withElseRegion=*/ true );
@@ -171,6 +170,21 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
171
170
172
171
builder.setInsertionPointToEnd (initBlock);
173
172
mlir::Value boxAlloca = allocatedPrivVarArg;
173
+
174
+ // The initial state of a private pointer is undefined so we don't need to
175
+ // match the mold argument (OpenMP 5.2 end of page 106).
176
+ if (isPrivate && mlir::isa<fir::PointerType>(boxTy.getEleTy ())) {
177
+ // Just incase, do initialize the box with a null value
178
+ mlir::Value null = builder.createNullConstant (loc, boxTy.getEleTy ());
179
+ mlir::Value nullBox = builder.create <fir::EmboxOp>(loc, boxTy, null);
180
+ builder.create <fir::StoreOp>(loc, nullBox, boxAlloca);
181
+ yield (boxAlloca);
182
+ return ;
183
+ }
184
+
185
+ moldArg = builder.loadIfRef (loc, moldArg);
186
+ hlfir::genLengthParameters (loc, builder, hlfir::Entity{moldArg}, lenParams);
187
+
174
188
mlir::Type innerTy = fir::unwrapRefType (boxTy.getEleTy ());
175
189
bool isChar = fir::isa_char (innerTy);
176
190
if (fir::isa_trivial (innerTy) || isChar) {
@@ -179,7 +193,7 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
179
193
TODO (loc,
180
194
" Reduction/Privatization of non-allocatable trivial typed box" );
181
195
182
- fir::IfOp ifUnallocated = handleNullAllocatable (boxAlloca);
196
+ fir::IfOp ifUnallocated = handleNullAllocatable (boxAlloca, moldArg );
183
197
184
198
builder.setInsertionPointToStart (&ifUnallocated.getElseRegion ().front ());
185
199
mlir::Value valAlloc = builder.createHeapTemporary (
@@ -200,9 +214,12 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
200
214
if (!innerTy || !mlir::isa<fir::SequenceType>(innerTy))
201
215
TODO (loc, " Unsupported boxed type for reduction/privatization" );
202
216
217
+ moldArg = builder.loadIfRef (loc, moldArg);
218
+ hlfir::genLengthParameters (loc, builder, hlfir::Entity{moldArg}, lenParams);
219
+
203
220
fir::IfOp ifUnallocated{nullptr };
204
221
if (isAllocatableOrPointer) {
205
- ifUnallocated = handleNullAllocatable (boxAlloca);
222
+ ifUnallocated = handleNullAllocatable (boxAlloca, moldArg );
206
223
builder.setInsertionPointToStart (&ifUnallocated.getElseRegion ().front ());
207
224
}
208
225
0 commit comments