Skip to content

Commit f0038b4

Browse files
committed
[flang][OpenMP] Delayed privatization for variable with equivalence association
Handles variables that are storage associated via `equivalence`. The problem is that these variables are declared as `fir.ptr`s while their privatized storage is declared as `fir.ref` which was triggering a validation error in the OpenMP dialect.
1 parent 4f42deb commit f0038b4

File tree

3 files changed

+83
-3
lines changed

3 files changed

+83
-3
lines changed

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,9 +549,17 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
549549
symTable->addSymbol(*sym, localExV);
550550
symTable->pushScope();
551551
cloneSymbol(sym);
552-
firOpBuilder.create<mlir::omp::YieldOp>(
553-
hsb.getAddr().getLoc(),
554-
symTable->shallowLookupSymbol(*sym).getAddr());
552+
mlir::Value cloneAddr = symTable->shallowLookupSymbol(*sym).getAddr();
553+
mlir::Type cloneType = cloneAddr.getType();
554+
555+
mlir::Value yieldedValue =
556+
(symType == cloneType) ? cloneAddr
557+
: firOpBuilder.createConvert(
558+
cloneAddr.getLoc(), symType, cloneAddr);
559+
560+
auto yieldOp = firOpBuilder.create<mlir::omp::YieldOp>(
561+
hsb.getAddr().getLoc(), yieldedValue);
562+
yieldOp.getOperand(0).getType();
555563
symTable->popScope();
556564
}
557565

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
! Test delayed privatization for variables that are storage associated via `EQUIVALENCE`.
2+
3+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
4+
! RUN: -o - %s 2>&1 | FileCheck %s
5+
! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 \
6+
! RUN: | FileCheck %s
7+
8+
subroutine private_common
9+
real x, y
10+
equivalence (x,y)
11+
!$omp parallel firstprivate(x)
12+
x = 3.14
13+
!$omp end parallel
14+
end subroutine
15+
16+
! CHECK: omp.private {type = firstprivate} @[[X_PRIVATIZER:.*]] : ![[X_TYPE:fir.ptr<f32>]] alloc {
17+
! CHECK: ^bb0(%{{.*}}: ![[X_TYPE]]):
18+
! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca f32 {bindc_name = "x", {{.*}}}
19+
! CHECK: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]] {{{.*}}} : (![[PRIV_TYPE:fir.ref<f32>]]) -> ({{.*}})
20+
! CHECK: %[[PRIV_CONV:.*]] = fir.convert %[[PRIV_DECL]]#0 : (![[PRIV_TYPE]]) -> ![[X_TYPE]]
21+
! CHECK: omp.yield(%[[PRIV_CONV]] : ![[X_TYPE]])
22+
! CHECK: } copy {
23+
! CHECK: ^bb0(%[[ORIG_PTR:.*]]: ![[X_TYPE]], %[[PRIV_REF:.*]]: ![[X_TYPE]]):
24+
! CHECK: %[[ORIG_VAL:.*]] = fir.load %[[ORIG_PTR]] : !fir.ptr<f32>
25+
! CHECK: hlfir.assign %[[ORIG_VAL]] to %[[PRIV_REF]] temporary_lhs : f32, ![[X_TYPE]]
26+
! CHECK: omp.yield(%[[PRIV_REF]] : ![[X_TYPE]])
27+
! CHECK: }
28+
29+
! CHECK: func.func @_QPprivate_common() {
30+
! CHECK: omp.parallel private(@[[X_PRIVATIZER]] %{{.*}}#0 -> %[[PRIV_ARG:.*]] : ![[X_TYPE]]) {
31+
! CHECK: %[[REG_DECL:.*]]:2 = hlfir.declare %[[PRIV_ARG]] {{{.*}}} : (![[X_TYPE]]) -> ({{.*}})
32+
! CHECK: %[[CST:.*]] = arith.constant {{.*}}
33+
! CHECK: hlfir.assign %[[CST]] to %[[REG_DECL]]#0 : {{.*}}
34+
! CHECK: omp.terminator
35+
! CHECK: }
36+
! CHECK: return
37+
! CHECK: }

mlir/test/Target/LLVMIR/openmp-private.mlir

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,38 @@ omp.declare_reduction @reducer.part : !llvm.ptr init {
234234
^bb0(%arg0: !llvm.ptr):
235235
omp.yield
236236
}
237+
238+
// -----
239+
240+
llvm.func @_QPequivalence() {
241+
%0 = llvm.mlir.constant(1 : i64) : i64
242+
%1 = llvm.alloca %0 x !llvm.array<4 x i8> : (i64) -> !llvm.ptr
243+
%2 = llvm.mlir.constant(0 : index) : i64
244+
%3 = llvm.getelementptr %1[0, %2] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<4 x i8>
245+
omp.parallel private(@_QFequivalenceEx_firstprivate_ptr_f32 %3 -> %arg0 : !llvm.ptr) {
246+
%4 = llvm.mlir.constant(3.140000e+00 : f32) : f32
247+
llvm.store %4, %arg0 : f32, !llvm.ptr
248+
omp.terminator
249+
}
250+
llvm.return
251+
}
252+
253+
omp.private {type = firstprivate} @_QFequivalenceEx_firstprivate_ptr_f32 : !llvm.ptr alloc {
254+
^bb0(%arg0: !llvm.ptr):
255+
%0 = llvm.mlir.constant(1 : i64) : i64
256+
%1 = llvm.alloca %0 x f32 {bindc_name = "x", pinned} : (i64) -> !llvm.ptr
257+
omp.yield(%1 : !llvm.ptr)
258+
} copy {
259+
^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
260+
%0 = llvm.load %arg0 : !llvm.ptr -> f32
261+
llvm.store %0, %arg1 : f32, !llvm.ptr
262+
omp.yield(%arg1 : !llvm.ptr)
263+
}
264+
265+
// CHECK: define internal void @_QPequivalence..omp_par
266+
// CHECK: %[[PRIV_ALLOC:.*]] = alloca float, i64 1, align 4
267+
// CHECK: %[[HOST_VAL:.*]] = load float, ptr %{{.*}}, align 4
268+
// Test that we initialzie the firstprivate variable.
269+
// CHECK: store float %[[HOST_VAL]], ptr %[[PRIV_ALLOC]], align 4
270+
// Test that we inlined the body of the parallel region.
271+
// CHECK: store float 0x{{.*}}, ptr %[[PRIV_ALLOC]], align 4

0 commit comments

Comments
 (0)