Skip to content

Commit 0015bb3

Browse files
committed
Support derived types
There are three cases handled: - Boxed (maybe allocatable or pointer) scalar derived types - Boxed (maybe allocatable or pointer) arrays of derived types - Unboxed scalar derived types Currently I support both boxed and unboxed derived types because unboxed derived types aren't hlfir::Entities so I worry there could be cases where they are in fact boxed. The changes to parallel-private-clause.f90 are because of the arrays becoming boxed. I re-organised the test a bit because the CHECK-DAGs were matching completely the wrong lines outside of the parallel region.
1 parent 870af17 commit 0015bb3

File tree

8 files changed

+129
-106
lines changed

8 files changed

+129
-106
lines changed

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "flang/Optimizer/Builder/BoxValue.h"
2121
#include "flang/Optimizer/Builder/HLFIRTools.h"
2222
#include "flang/Optimizer/Builder/Todo.h"
23+
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
2324
#include "flang/Optimizer/HLFIR/HLFIROps.h"
2425
#include "flang/Semantics/attr.h"
2526
#include "flang/Semantics/tools.h"
@@ -565,24 +566,19 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
565566

566567
// Populate the `init` region.
567568
const bool needsInitialization =
568-
Fortran::lower::hasDefaultInitialization(sym->GetUltimate()) ||
569+
(Fortran::lower::hasDefaultInitialization(sym->GetUltimate()) &&
570+
(!isFirstPrivate || hlfir::mayHaveAllocatableComponent(allocType))) ||
569571
mlir::isa<fir::BaseBoxType>(allocType) ||
570572
mlir::isa<fir::BoxCharType>(allocType);
571573
if (needsInitialization) {
572574
mlir::Region &initRegion = result.getInitRegion();
573575
mlir::Block *initBlock = firOpBuilder.createBlock(
574576
&initRegion, /*insertPt=*/{}, {argType, argType}, {symLoc, symLoc});
575577

576-
if (fir::isa_derived(allocType))
577-
TODO(symLoc, "Privatization init of derived types");
578-
if (Fortran::lower::hasDefaultInitialization(sym->GetUltimate()))
579-
TODO(symLoc,
580-
"Privatization init of symbol with default initialization");
581-
582578
populateByRefInitAndCleanupRegions(
583579
firOpBuilder, symLoc, argType, /*scalarInitValue=*/nullptr, initBlock,
584580
result.getInitPrivateArg(), result.getInitMoldArg(),
585-
result.getDeallocRegion(), /*isPrivate=*/true);
581+
result.getDeallocRegion(), /*isPrivate=*/true, sym);
586582
}
587583

588584
// Populate the `copy` region if this is a `firstprivate`.

flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,34 @@
1212

1313
#include "PrivateReductionUtils.h"
1414

15+
#include "flang/Lower/ConvertVariable.h"
1516
#include "flang/Optimizer/Builder/BoxValue.h"
1617
#include "flang/Optimizer/Builder/Character.h"
1718
#include "flang/Optimizer/Builder/FIRBuilder.h"
1819
#include "flang/Optimizer/Builder/HLFIRTools.h"
20+
#include "flang/Optimizer/Builder/Runtime/Derived.h"
1921
#include "flang/Optimizer/Builder/Todo.h"
2022
#include "flang/Optimizer/Dialect/FIROps.h"
2123
#include "flang/Optimizer/Dialect/FIRType.h"
24+
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
2225
#include "flang/Optimizer/HLFIR/HLFIROps.h"
2326
#include "flang/Optimizer/Support/FatalError.h"
27+
#include "flang/Semantics/symbol.h"
2428
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
2529
#include "mlir/IR/Location.h"
2630

31+
static bool hasFinalization(const Fortran::semantics::Symbol &sym) {
32+
if (sym.has<Fortran::semantics::ObjectEntityDetails>())
33+
if (const Fortran::semantics::DeclTypeSpec *declTypeSpec = sym.GetType())
34+
if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec =
35+
declTypeSpec->AsDerived())
36+
return Fortran::semantics::IsFinalizable(*derivedTypeSpec);
37+
return false;
38+
}
39+
2740
static void createCleanupRegion(fir::FirOpBuilder &builder, mlir::Location loc,
28-
mlir::Type argType,
29-
mlir::Region &cleanupRegion) {
41+
mlir::Type argType, mlir::Region &cleanupRegion,
42+
const Fortran::semantics::Symbol *sym) {
3043
assert(cleanupRegion.empty());
3144
mlir::Block *block = builder.createBlock(&cleanupRegion, cleanupRegion.end(),
3245
{argType}, {loc});
@@ -41,12 +54,6 @@ static void createCleanupRegion(fir::FirOpBuilder &builder, mlir::Location loc,
4154

4255
mlir::Type valTy = fir::unwrapRefType(argType);
4356
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(valTy)) {
44-
if (!mlir::isa<fir::HeapType, fir::PointerType>(boxTy.getEleTy())) {
45-
mlir::Type innerTy = fir::extractSequenceType(boxTy);
46-
if (!mlir::isa<fir::SequenceType>(innerTy))
47-
typeError();
48-
}
49-
5057
mlir::Value arg = builder.loadIfRef(loc, block->getArgument(0));
5158
assert(mlir::isa<fir::BaseBoxType>(arg.getType()));
5259

@@ -138,13 +145,20 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
138145
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
139146
mlir::Value scalarInitValue, mlir::Block *initBlock,
140147
mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
141-
mlir::Region &cleanupRegion, bool isPrivate) {
148+
mlir::Region &cleanupRegion, bool isPrivate,
149+
const Fortran::semantics::Symbol *sym) {
142150
mlir::Type ty = fir::unwrapRefType(argType);
143151
builder.setInsertionPointToEnd(initBlock);
144152
auto yield = [&](mlir::Value ret) {
145153
builder.create<mlir::omp::YieldOp>(loc, ret);
146154
};
147155

156+
if (isPrivate)
157+
assert(sym && "Symbol information is needed to privatize derived types");
158+
bool needsInitialization =
159+
sym ? Fortran::lower::hasDefaultInitialization(sym->GetUltimate())
160+
: false;
161+
148162
if (fir::isa_trivial(ty)) {
149163
builder.setInsertionPointToEnd(initBlock);
150164

@@ -214,39 +228,62 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
214228
}
215229

216230
moldArg = builder.loadIfRef(loc, moldArg);
217-
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
231+
// We pass derived types unboxed and so are not self-contained entities.
232+
if (hlfir::isFortranEntity(moldArg))
233+
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg},
234+
lenParams);
218235

219236
mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
237+
bool isDerived = fir::isa_derived(innerTy);
220238
bool isChar = fir::isa_char(innerTy);
221-
if (fir::isa_trivial(innerTy) || isChar) {
239+
if (fir::isa_trivial(innerTy) || isDerived || isChar) {
222240
// boxed non-sequence value e.g. !fir.box<!fir.heap<i32>>
223-
if (!isAllocatableOrPointer)
224-
TODO(loc,
225-
"Reduction/Privatization of non-allocatable trivial typed box");
241+
if (!isAllocatableOrPointer && !isDerived)
242+
TODO(loc, "Reduction/Privatization of non-allocatable trivial or "
243+
"character typed box");
226244

227-
fir::IfOp ifUnallocated = handleNullAllocatable(boxAlloca, moldArg);
245+
if ((isDerived || isChar) && (!isPrivate || scalarInitValue))
246+
TODO(loc, "Reduction of an unsupported boxed type");
247+
248+
fir::IfOp ifUnallocated{nullptr};
249+
if (isAllocatableOrPointer) {
250+
ifUnallocated = handleNullAllocatable(boxAlloca, moldArg);
251+
builder.setInsertionPointToStart(
252+
&ifUnallocated.getElseRegion().front());
253+
}
228254

229-
builder.setInsertionPointToStart(&ifUnallocated.getElseRegion().front());
230255
mlir::Value valAlloc = builder.createHeapTemporary(
231256
loc, innerTy, /*name=*/{}, /*shape=*/{}, lenParams);
232257
if (scalarInitValue)
233258
builder.createStoreWithConvert(loc, scalarInitValue, valAlloc);
234259
mlir::Value box = builder.create<fir::EmboxOp>(
235260
loc, ty, valAlloc, /*shape=*/mlir::Value{}, /*slice=*/mlir::Value{},
236261
lenParams);
237-
builder.create<fir::StoreOp>(loc, box, boxAlloca);
262+
if (needsInitialization)
263+
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
264+
fir::StoreOp lastOp = builder.create<fir::StoreOp>(loc, box, boxAlloca);
238265

239-
createCleanupRegion(builder, loc, argType, cleanupRegion);
240-
builder.setInsertionPointAfter(ifUnallocated);
266+
createCleanupRegion(builder, loc, argType, cleanupRegion, sym);
267+
268+
if (ifUnallocated)
269+
builder.setInsertionPointAfter(ifUnallocated);
270+
else
271+
builder.setInsertionPointAfter(lastOp);
241272
yield(boxAlloca);
242273
return;
243274
}
275+
244276
innerTy = fir::extractSequenceType(boxTy);
245277
if (!innerTy || !mlir::isa<fir::SequenceType>(innerTy))
246278
TODO(loc, "Unsupported boxed type for reduction/privatization");
247279

248280
moldArg = builder.loadIfRef(loc, moldArg);
249-
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
281+
// We pass derived types unboxed and so are not self-contained entities.
282+
// Assume that if length parameters are required, they will be boxed by
283+
// lowering.
284+
if (hlfir::isFortranEntity(moldArg))
285+
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg},
286+
lenParams);
250287

251288
fir::IfOp ifUnallocated{nullptr};
252289
if (isAllocatableOrPointer) {
@@ -274,7 +311,7 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
274311
"createTempFromMold decides this statically");
275312
if (cstNeedsDealloc.has_value() && *cstNeedsDealloc != false) {
276313
mlir::OpBuilder::InsertionGuard guard(builder);
277-
createCleanupRegion(builder, loc, argType, cleanupRegion);
314+
createCleanupRegion(builder, loc, argType, cleanupRegion, sym);
278315
} else {
279316
assert(!isAllocatableOrPointer &&
280317
"Pointer-like arrays must be heap allocated");
@@ -298,6 +335,9 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
298335

299336
if (scalarInitValue)
300337
builder.create<hlfir::AssignOp>(loc, scalarInitValue, box);
338+
if (needsInitialization)
339+
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
340+
301341
builder.create<fir::StoreOp>(loc, box, boxAlloca);
302342
if (ifUnallocated)
303343
builder.setInsertionPointAfter(ifUnallocated);
@@ -323,13 +363,29 @@ void Fortran::lower::omp::populateByRefInitAndCleanupRegions(
323363
loc, eleTy, /*name=*/{}, /*shape=*/{}, /*lenParams=*/len);
324364
mlir::Value boxChar = charExprHelper.createEmboxChar(privateAddr, len);
325365

326-
createCleanupRegion(builder, loc, argType, cleanupRegion);
366+
createCleanupRegion(builder, loc, argType, cleanupRegion, sym);
327367

328368
builder.setInsertionPointToEnd(initBlock);
329369
yield(boxChar);
330370
return;
331371
}
332372

373+
if (fir::isa_derived(ty)) {
374+
if (needsInitialization) {
375+
builder.setInsertionPointToStart(initBlock);
376+
mlir::Type boxedTy = fir::BoxType::get(ty);
377+
mlir::Value box =
378+
builder.create<fir::EmboxOp>(loc, boxedTy, allocatedPrivVarArg);
379+
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
380+
}
381+
if (sym && hasFinalization(*sym))
382+
createCleanupRegion(builder, loc, argType, cleanupRegion, sym);
383+
384+
builder.setInsertionPointToEnd(initBlock);
385+
yield(allocatedPrivVarArg);
386+
return;
387+
}
388+
333389
TODO(loc,
334390
"creating reduction/privatization init region for unsupported type");
335391
return;

flang/lib/Lower/OpenMP/PrivateReductionUtils.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ namespace mlir {
2020
class Region;
2121
} // namespace mlir
2222

23+
namespace Fortran {
24+
namespace semantics {
25+
class Symbol;
26+
} // namespace semantics
27+
} // namespace Fortran
28+
2329
namespace fir {
2430
class FirOpBuilder;
2531
class ShapeShiftOp;
@@ -37,7 +43,8 @@ void populateByRefInitAndCleanupRegions(
3743
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type argType,
3844
mlir::Value scalarInitValue, mlir::Block *initBlock,
3945
mlir::Value allocatedPrivVarArg, mlir::Value moldArg,
40-
mlir::Region &cleanupRegion, bool isPrivate = false);
46+
mlir::Region &cleanupRegion, bool isPrivate = false,
47+
const Fortran::semantics::Symbol *sym = nullptr);
4148

4249
/// Generate a fir::ShapeShift op describing the provided boxed array.
4350
fir::ShapeShiftOp getShapeShift(fir::FirOpBuilder &builder, mlir::Location loc,

flang/test/Integration/OpenMP/copyprivate.f90

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99
!RUN: %flang_fc1 -emit-llvm -fopenmp %s -o - | FileCheck %s
1010

1111
!CHECK-DAG: define internal void @_copy_box_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
12-
!CHECK-DAG: define internal void @_copy_10xi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
12+
!CHECK-DAG: define internal void @_copy_box_10xi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
1313
!CHECK-DAG: define internal void @_copy_i64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
1414
!CHECK-DAG: define internal void @_copy_box_Uxi64(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
1515
!CHECK-DAG: define internal void @_copy_f32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
16-
!CHECK-DAG: define internal void @_copy_2x3xf32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
16+
!CHECK-DAG: define internal void @_copy_box_2x3xf32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
1717
!CHECK-DAG: define internal void @_copy_z32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
18-
!CHECK-DAG: define internal void @_copy_10xz32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
18+
!CHECK-DAG: define internal void @_copy_box_10xz32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
1919
!CHECK-DAG: define internal void @_copy_l32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
20-
!CHECK-DAG: define internal void @_copy_5xl32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
20+
!CHECK-DAG: define internal void @_copy_box_5xl32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
2121
!CHECK-DAG: define internal void @_copy_c8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
22-
!CHECK-DAG: define internal void @_copy_10xc8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
22+
!CHECK-DAG: define internal void @_copy_box_10xc8x8(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
2323
!CHECK-DAG: define internal void @_copy_c16x5(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
2424
!CHECK-DAG: define internal void @_copy_rec__QFtest_typesTdt(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
2525
!CHECK-DAG: define internal void @_copy_box_heap_Uxi32(ptr nocapture %{{.*}}, ptr nocapture %{{.*}})
@@ -33,8 +33,12 @@
3333
!CHECK-NEXT: }
3434

3535
!CHECK-LABEL: define internal void @test_scalar_..omp_par({{.*}})
36-
!CHECK: %[[I:.*]] = alloca i32, i64 1
37-
!CHECK: %[[J:.*]] = alloca i32, i64 1
36+
!CHECK-NEXT: omp.par.entry:
37+
!CHECK: %[[TID_ADDR:.*]] = alloca i32, align 4
38+
!CHECK: %[[I:.*]] = alloca i32, align 4
39+
!CHECK: %[[J:.*]] = alloca i32, align 4
40+
!CHECK: br label %[[OMP_REDUCTION_INIT:.*]]
41+
3842
!CHECK: %[[DID_IT:.*]] = alloca i32
3943
!CHECK: store i32 0, ptr %[[DID_IT]]
4044
!CHECK: %[[THREAD_NUM1:.*]] = call i32 @__kmpc_global_thread_num(ptr @[[LOC:.*]])

flang/test/Lower/OpenMP/default-clause-byref.f90

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,27 @@
77
! RUN: bbc -fopenmp -emit-hlfir --force-byref-reduction %s -o - \
88
! RUN: | FileCheck %s
99

10-
!CHECK: omp.private {type = firstprivate} @[[W_FIRSTPRIVATIZER:_QFEw_firstprivate_ref_i32]] : !fir.ref<i32> alloc {
11-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
12-
!CHECK: %[[PRIV_W_ALLOC:.*]] = fir.alloca i32 {bindc_name = "w", {{.*}}}
13-
!CHECK: %[[PRIV_W_DECL:.*]]:2 = hlfir.declare %[[PRIV_W_ALLOC]] {uniq_name = "_QFEw"}
14-
!CHECK: omp.yield(%[[PRIV_W_DECL]]#0 : !fir.ref<i32>)
15-
!CHECK: } copy {
10+
!CHECK: omp.private {type = firstprivate} @[[W_FIRSTPRIVATIZER:_QFEw_firstprivate_i32]] : i32 copy {
1611
!CHECK: ^bb0(%[[ORIG_W:.*]]: !fir.ref<i32>, %[[PRIV_W:.*]]: !fir.ref<i32>):
1712
!CHECK: %[[ORIG_W_VAL:.*]] = fir.load %[[ORIG_W]]
1813
!CHECK: hlfir.assign %[[ORIG_W_VAL]] to %[[PRIV_W]]
1914
!CHECK: omp.yield(%[[PRIV_W]] : !fir.ref<i32>)
2015
!CHECK: }
2116

22-
!CHECK: omp.private {type = firstprivate} @[[Y_FIRSTPRIVATIZER:_QFEy_firstprivate_ref_i32]] : !fir.ref<i32> alloc {
23-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
24-
!CHECK: %[[PRIV_Y_ALLOC:.*]] = fir.alloca i32 {bindc_name = "y", {{.*}}}
25-
!CHECK: %[[PRIV_Y_DECL:.*]]:2 = hlfir.declare %[[PRIV_Y_ALLOC]] {uniq_name = "_QFEy"}
26-
!CHECK: omp.yield(%[[PRIV_Y_DECL]]#0 : !fir.ref<i32>)
27-
!CHECK: } copy {
17+
!CHECK: omp.private {type = firstprivate} @[[Y_FIRSTPRIVATIZER:_QFEy_firstprivate_i32]] : i32 copy {
2818
!CHECK: ^bb0(%[[ORIG_Y:.*]]: !fir.ref<i32>, %[[PRIV_Y:.*]]: !fir.ref<i32>):
2919
!CHECK: %[[ORIG_Y_VAL:.*]] = fir.load %[[ORIG_Y]]
3020
!CHECK: hlfir.assign %[[ORIG_Y_VAL]] to %[[PRIV_Y]]
3121
!CHECK: omp.yield(%[[PRIV_Y]] : !fir.ref<i32>)
3222
!CHECK: }
3323

34-
!CHECK: omp.private {type = private} @[[X_PRIVATIZER:_QFEx_private_ref_i32]] : !fir.ref<i32> alloc {
35-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
36-
!CHECK: %[[PRIV_X_ALLOC:.*]] = fir.alloca i32 {bindc_name = "x", {{.*}}}
37-
!CHECK: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X_ALLOC]] {uniq_name = "_QFEx"}
38-
!CHECK: omp.yield(%[[PRIV_X_DECL]]#0 : !fir.ref<i32>)
39-
!CHECK: }
24+
!CHECK: omp.private {type = private} @[[X_PRIVATIZER:_QFEx_private_i32]] : i32
4025

41-
!CHECK: omp.private {type = private} @[[W_PRIVATIZER:_QFEw_private_ref_i32]] : !fir.ref<i32> alloc {
42-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
43-
!CHECK: %[[PRIV_W_ALLOC:.*]] = fir.alloca i32 {bindc_name = "w", {{.*}}}
44-
!CHECK: %[[PRIV_W_DECL:.*]]:2 = hlfir.declare %[[PRIV_W_ALLOC]] {uniq_name = "_QFEw"}
45-
!CHECK: omp.yield(%[[PRIV_W_DECL]]#0 : !fir.ref<i32>)
46-
!CHECK: }
26+
!CHECK: omp.private {type = private} @[[W_PRIVATIZER:_QFEw_private_i32]] : i32
4727

48-
!CHECK: omp.private {type = private} @[[Y_PRIVATIZER:_QFEy_private_ref_i32]] : !fir.ref<i32> alloc {
49-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
50-
!CHECK: %[[PRIV_Y_ALLOC:.*]] = fir.alloca i32 {bindc_name = "y", {{.*}}}
51-
!CHECK: %[[PRIV_Y_DECL:.*]]:2 = hlfir.declare %[[PRIV_Y_ALLOC]] {uniq_name = "_QFEy"}
52-
!CHECK: omp.yield(%[[PRIV_Y_DECL]]#0 : !fir.ref<i32>)
53-
!CHECK: }
28+
!CHECK: omp.private {type = private} @[[Y_PRIVATIZER:_QFEy_private_i32]] : i32
5429

55-
!CHECK: omp.private {type = firstprivate} @[[X_FIRSTPRIVATIZER:_QFEx_firstprivate_ref_i32]] : !fir.ref<i32> alloc {
56-
!CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
57-
!CHECK: %[[PRIV_X_ALLOC:.*]] = fir.alloca i32 {bindc_name = "x", {{.*}}}
58-
!CHECK: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X_ALLOC]] {uniq_name = "_QFEx"}
59-
!CHECK: omp.yield(%[[PRIV_X_DECL]]#0 : !fir.ref<i32>)
60-
!CHECK: } copy {
30+
!CHECK: omp.private {type = firstprivate} @[[X_FIRSTPRIVATIZER:_QFEx_firstprivate_i32]] : i32 copy {
6131
!CHECK: ^bb0(%[[ORIG_X:.*]]: !fir.ref<i32>, %[[PRIV_X:.*]]: !fir.ref<i32>):
6232
!CHECK: %[[ORIG_X_VAL:.*]] = fir.load %[[ORIG_X]]
6333
!CHECK: hlfir.assign %[[ORIG_X_VAL]] to %[[PRIV_X]]

0 commit comments

Comments
 (0)