Skip to content

Commit c6b728b

Browse files
luporlsahas3
authored andcommitted
[flang][OpenMP] Fix lowering of LINEAR iteration variables (llvm#183794)
Linear iteration variables were being treated as private. This fixes one of the issues reported in llvm#170784.
1 parent d34cc66 commit c6b728b

8 files changed

Lines changed: 42 additions & 36 deletions

File tree

‎flang/lib/Lower/OpenMP/DataSharingProcessor.cpp‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,6 @@ void DataSharingProcessor::collectSymbolsForPrivatization() {
235235
// Such cases are suggested to be clearly documented and explained
236236
// instead of being silently skipped
237237
auto isException = [&](const Fortran::semantics::Symbol *sym) -> bool {
238-
// `OmpPreDetermined` symbols cannot be exceptions since
239-
// their privatized symbols are heavily used in FIR.
240-
if (sym->test(Fortran::semantics::Symbol::Flag::OmpPreDetermined))
241-
return false;
242-
243238
// The handling of linear clause is deferred to the OpenMP
244239
// IRBuilder which is responsible for all its aspects,
245240
// including privatization. Privatizing linear variables at this point would
@@ -263,6 +258,11 @@ void DataSharingProcessor::collectSymbolsForPrivatization() {
263258
// draw a relation between %linear and %arg0. Hence skip.
264259
if (sym->test(Fortran::semantics::Symbol::Flag::OmpLinear))
265260
return true;
261+
262+
// `OmpPreDetermined` symbols cannot be exceptions since
263+
// their privatized symbols are heavily used in FIR.
264+
if (sym->test(Fortran::semantics::Symbol::Flag::OmpPreDetermined))
265+
return false;
266266
return false;
267267
};
268268

@@ -508,7 +508,10 @@ void DataSharingProcessor::collectSymbols(
508508
!sym.GetUltimate().has<semantics::DerivedTypeDetails>() &&
509509
!sym.GetUltimate().has<semantics::NamelistDetails>() &&
510510
!semantics::IsImpliedDoIndex(sym.GetUltimate()) &&
511-
!semantics::IsStmtFunction(sym);
511+
!semantics::IsStmtFunction(sym) &&
512+
// Linear symbols are privatized by OpenMP IRBuilder. See comments
513+
// in collectSymbolsForPrivatization() for more details.
514+
!sym.test(semantics::Symbol::Flag::OmpLinear);
512515
};
513516

514517
auto shouldCollectSymbol = [&](const semantics::Symbol *sym) {

‎flang/lib/Lower/OpenMP/OpenMP.cpp‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,10 @@ static mlir::Operation *
716716
createAndSetPrivatizedLoopVar(lower::AbstractConverter &converter,
717717
mlir::Location loc, mlir::Value indexVal,
718718
const semantics::Symbol *sym) {
719-
assert(converter.isPresentShallowLookup(*sym) &&
719+
// The handling of linear symbols is deferred to the OpenMP IRBuilder,
720+
// which is responsible for all its aspects, including privatization.
721+
assert((converter.isPresentShallowLookup(*sym) ||
722+
sym->test(semantics::Symbol::Flag::OmpLinear)) &&
720723
"Expected symbol to be in symbol table.");
721724
return setLoopVar(converter, loc, indexVal, sym);
722725
}

‎flang/test/Lower/OpenMP/composite_simd_linear.f90‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ subroutine do_simd
88
!CHECK: %{{.*}} = arith.constant 1 : i32
99
!CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
1010
!CHECK: omp.wsloop {
11-
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[CONST]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFdo_simdEi_private_i32 {{.*}} -> %arg0 : !fir.ref<i32>) {
11+
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[CONST]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) {
1212
!CHECK: }
1313
!CHECK: } {linear_var_types = [i32, i32], omp.composite}
1414
!CHECK: } {omp.composite}
@@ -21,9 +21,10 @@ end subroutine do_simd
2121

2222

2323
subroutine distribute_simd
24+
!CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFdistribute_simdEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
2425
!CHECK: omp.teams {
25-
!CHECK: omp.distribute private(@_QFdistribute_simdEi_private_i32 {{.*}} -> %[[ARG0:.*]] : !fir.ref<i32>) {
26-
!CHECK: omp.simd linear(%[[ARG0]] : !fir.ref<i32> = %c1_i32 : i32) private(@_QFdistribute_simdEi_private_i32 %[[ARG0]] -> {{.*}} : !fir.ref<i32>) {
26+
!CHECK: omp.distribute {
27+
!CHECK: omp.simd linear(%[[I]]#0 : !fir.ref<i32> = %c1_i32 : i32) {
2728
!CHECK: } {linear_var_types = [i32], omp.composite}
2829
!CHECK: } {omp.composite}
2930
integer :: i
@@ -44,7 +45,7 @@ subroutine distribute_parallel_do
4445
!CHECK: %[[CONST]] = arith.constant 1 : i32
4546
!CHECK: omp.distribute {
4647
!CHECK: omp.wsloop {
47-
!CHECK: omp.simd linear(%[[I]]#0 : !fir.ref<i32> = %[[CONST]] : i32) private(@_QFdistribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
48+
!CHECK: omp.simd linear(%[[I]]#0 : !fir.ref<i32> = %[[CONST]] : i32) {
4849
!$omp teams
4950
!$omp distribute parallel do simd linear(i:1)
5051
do i = 1, N
@@ -62,7 +63,7 @@ subroutine parallel_do
6263
!CHECK: %{{.*}} = arith.constant 1 : i32
6364
!CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
6465
!CHECK: omp.wsloop {
65-
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFparallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
66+
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) {
6667
integer :: x
6768
!$omp parallel do simd linear(x:2)
6869
do i = 1, N
@@ -79,7 +80,7 @@ subroutine teams_distribute
7980
!CHECK: {{.*}} = arith.constant 1 : i32
8081
!CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
8182
!CHECK: omp.distribute {
82-
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFteams_distributeEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
83+
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) {
8384
integer :: x
8485
!$omp teams distribute simd linear(x)
8586
do i = 1, N
@@ -98,7 +99,7 @@ subroutine teams_distribute_parallel_do
9899
!CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
99100
!CHECK: omp.distribute {
100101
!CHECK: omp.wsloop {
101-
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %c1_i32 : i32, %[[I]]#0 : !fir.ref<i32> = %c1_i32_1 : i32) private(@_QFteams_distribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
102+
!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %c1_i32 : i32, %[[I]]#0 : !fir.ref<i32> = %c1_i32_1 : i32) {
102103
integer :: x
103104
!$omp teams distribute parallel do simd linear(x)
104105
do i = 1, N

‎flang/test/Lower/OpenMP/distribute-parallel-do-simd.f90‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ subroutine distribute_parallel_do_simd_num_threads()
1111
! CHECK: omp.parallel num_threads({{.*}}) {
1212
! CHECK: omp.distribute {
1313
! CHECK-NEXT: omp.wsloop {
14-
! CHECK-NEXT: omp.simd linear({{.*}}) private({{.*}}) {
14+
! CHECK-NEXT: omp.simd linear({{.*}}) {
1515
! CHECK-NEXT: omp.loop_nest
1616
!$omp distribute parallel do simd num_threads(10)
1717
do index_ = 1, 10
@@ -28,7 +28,7 @@ subroutine distribute_parallel_do_simd_dist_schedule()
2828
! CHECK: omp.parallel {
2929
! CHECK: omp.distribute dist_schedule_static dist_schedule_chunk_size({{.*}}) {
3030
! CHECK-NEXT: omp.wsloop {
31-
! CHECK-NEXT: omp.simd linear({{.*}}) private({{.*}}) {
31+
! CHECK-NEXT: omp.simd linear({{.*}}) {
3232
! CHECK-NEXT: omp.loop_nest
3333
!$omp distribute parallel do simd dist_schedule(static, 4)
3434
do index_ = 1, 10
@@ -45,7 +45,7 @@ subroutine distribute_parallel_do_simd_schedule()
4545
! CHECK: omp.parallel {
4646
! CHECK: omp.distribute {
4747
! CHECK-NEXT: omp.wsloop schedule(static = {{.*}}) {
48-
! CHECK-NEXT: omp.simd linear({{.*}}) private({{.*}}) {
48+
! CHECK-NEXT: omp.simd linear({{.*}}) {
4949
! CHECK-NEXT: omp.loop_nest
5050
!$omp distribute parallel do simd schedule(static, 4)
5151
do index_ = 1, 10
@@ -62,7 +62,7 @@ subroutine distribute_parallel_do_simd_simdlen()
6262
! CHECK: omp.parallel {
6363
! CHECK: omp.distribute {
6464
! CHECK-NEXT: omp.wsloop {
65-
! CHECK-NEXT: omp.simd linear({{.*}}) simdlen(4) private({{.*}}) {
65+
! CHECK-NEXT: omp.simd linear({{.*}}) simdlen(4) {
6666
! CHECK-NEXT: omp.loop_nest
6767
!$omp distribute parallel do simd simdlen(4)
6868
do index_ = 1, 10
@@ -86,11 +86,10 @@ subroutine distribute_parallel_do_simd_private()
8686
! CHECK: omp.parallel {
8787
! CHECK: omp.distribute {
8888
! CHECK-NEXT: omp.wsloop {
89-
! CHECK-NEXT: omp.simd linear(%{{.*}}) private(@{{.*}} %[[X]]#0 -> %[[X_ARG:[^,]+]],
90-
! CHECK-SAME: @{{.*}} %[[INDEX]]#0 -> %[[INDEX_ARG:.*]] : !fir.ref<i64>, !fir.ref<i32>) {
89+
! CHECK-NEXT: omp.simd linear(%{{.*}}) private(@{{.*}} %[[X]]#0 -> %[[X_ARG:[^:]+]]
90+
! CHECK-SAME: : !fir.ref<i64>) {
9191
! CHECK-NEXT: omp.loop_nest
9292
! CHECK: %[[X_PRIV:.*]]:2 = hlfir.declare %[[X_ARG]]
93-
! CHECK: %[[INDEX_PRIV:.*]]:2 = hlfir.declare %[[INDEX_ARG]]
9493
!$omp distribute parallel do simd private(x)
9594
do index_ = 1, 10
9695
end do

‎flang/test/Lower/OpenMP/distribute-simd.f90‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,17 @@ end subroutine distribute_simd_simdlen
6161
! CHECK-LABEL: func.func @_QPdistribute_simd_private(
6262
subroutine distribute_simd_private()
6363
integer, allocatable :: tmp
64+
! CHECK: %[[INDEX:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFdistribute_simd_privateEindex_"}
6465
! CHECK: omp.teams
6566
!$omp teams
6667
! CHECK: omp.distribute
6768
! CHECK: omp.simd
68-
! CHECK-SAME: private(@[[PRIV_BOX_SYM:.*]] %{{.*}} -> %[[PRIV_BOX:.*]], @[[PRIV_IVAR_SYM:.*]] %{{.*}} -> %[[PRIV_IVAR:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>)
69+
! CHECK-SAME: private(@[[PRIV_BOX_SYM:.*]] %{{.*}} -> %[[PRIV_BOX:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>)
6970
! CHECK-NEXT: omp.loop_nest (%[[IVAR:.*]]) : i32
7071
!$omp distribute simd private(tmp)
7172
do index_ = 1, 10
7273
! CHECK: %[[PRIV_BOX_DECL:.*]]:2 = hlfir.declare %[[PRIV_BOX]]
73-
! CHECK: %[[PRIV_IVAR_DECL:.*]]:2 = hlfir.declare %[[PRIV_IVAR]]
74-
! CHECK: hlfir.assign %[[IVAR]] to %[[PRIV_IVAR_DECL]]#0
74+
! CHECK: hlfir.assign %[[IVAR]] to %[[INDEX]]#0
7575
end do
7676
!$omp end distribute simd
7777
!$omp end teams

‎flang/test/Lower/OpenMP/loop-pointer-variable.f90‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ program loop_var
88
integer, pointer :: ip1, ip2
99
integer, allocatable :: ia1
1010

11+
!CHECK: %[[IA1:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEia1"}
1112
!CHECK: omp.wsloop private(@_QFEip1_private_box_ptr_i32 %{{.*}}#0 -> %[[IP1_PVT:.*]], @_QFEip2_private_box_ptr_i32 %{{.*}}#0 -> %[[IP2_PVT:.*]] : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
1213
!CHECK: omp.loop_nest (%[[IP1_INDX:.*]], %[[IP2_INDX:.*]]) : i64 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
1314
!CHECK: %[[IP1_PVT_DECL:.*]]:2 = hlfir.declare %[[IP1_PVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEip1"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
@@ -28,13 +29,12 @@ program loop_var
2829
end do
2930
!$omp end do
3031

31-
!CHECK: omp.simd private(@_QFEia1_private_box_heap_i32 %{{.*}}#0 -> %[[IA1_PVT:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>)
32+
!CHECK: omp.simd
3233
!CHECK: omp.loop_nest (%[[IA1_INDX:.*]]) : i64 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
33-
!CHECK: %[[IA1_PVT_DECL:.*]]:2 = hlfir.declare %[[IA1_PVT]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEia1"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
34-
!CHECK: %[[IA1:.*]] = fir.convert %[[IA1_INDX]] : (i64) -> i32
35-
!CHECK: %[[IA1_BOX:.*]] = fir.load %[[IA1_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
34+
!CHECK: %[[IA1_INDX_I32:.*]] = fir.convert %[[IA1_INDX]] : (i64) -> i32
35+
!CHECK: %[[IA1_BOX:.*]] = fir.load %[[IA1]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
3636
!CHECK: %[[IA1_ADDR:.*]] = fir.box_addr %[[IA1_BOX]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
37-
!CHECK: hlfir.assign %[[IA1]] to %[[IA1_ADDR]] : i32, !fir.heap<i32>
37+
!CHECK: hlfir.assign %[[IA1_INDX_I32]] to %[[IA1_ADDR]] : i32, !fir.heap<i32>
3838
!CHECK: omp.yield
3939
!$omp simd
4040
do ia1 = 1, 10

‎flang/test/Lower/OpenMP/ordered-simd.f90‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ subroutine ordered_simd(n)
77
integer :: n, a(n), b(n), c(n), i
88

99
! CHECK-LABEL: func @_QPordered_simd
10-
! CHECK: omp.simd linear({{.*}}) private({{.*}}) {
10+
! CHECK: omp.simd linear({{.*}}) {
1111
! CHECK: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) {
1212
! CHECK: omp.ordered.region par_level_simd {
1313
! CHECK: omp.terminator
@@ -34,7 +34,7 @@ subroutine ws_ordered_simd(n)
3434

3535
! CHECK-LABEL: func @_QPws_ordered_simd
3636
! CHECK: omp.wsloop ordered(0) {
37-
! CHECK: omp.simd linear({{.*}}) private({{.*}}) {
37+
! CHECK: omp.simd linear({{.*}}) {
3838
! CHECK: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) {
3939
! CHECK: omp.ordered.region par_level_simd {
4040
! CHECK: omp.terminator

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ end subroutine do_simd_reduction
7070
! CHECK-LABEL: func.func @_QPdo_simd_private(
7171
subroutine do_simd_private()
7272
integer, allocatable :: tmp
73+
! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFdo_simd_privateEi"}
7374
! CHECK: omp.wsloop
7475
! CHECK-NEXT: omp.simd
75-
! CHECK-SAME: private(@[[PRIV_BOX_SYM:.*]] %{{.*}} -> %[[PRIV_BOX:.*]], @[[PRIV_IVAR_SYM:.*]] %{{.*}} -> %[[PRIV_IVAR:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<i32>)
76+
! CHECK-SAME: private(@[[PRIV_BOX_SYM:.*]] %{{.*}} -> %[[PRIV_BOX:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>>)
7677
! CHECK-NEXT: omp.loop_nest (%[[IVAR:.*]]) : i32
7778
!$omp do simd private(tmp)
7879
do i=1, 10
7980
! CHECK: %[[PRIV_BOX_DECL:.*]]:2 = hlfir.declare %[[PRIV_BOX]]
80-
! CHECK: %[[PRIV_IVAR_DECL:.*]]:2 = hlfir.declare %[[PRIV_IVAR]]
81-
! CHECK: hlfir.assign %[[IVAR]] to %[[PRIV_IVAR_DECL]]#0
81+
! CHECK: hlfir.assign %[[IVAR]] to %[[I_DECL]]#0
8282
! CHECK: %[[PRIV_BOX_LOAD:.*]] = fir.load %[[PRIV_BOX_DECL]]
8383
! CHECK: hlfir.assign %{{.*}} to %[[PRIV_BOX_DECL]]#0
8484
! CHECK: omp.yield
@@ -92,12 +92,12 @@ subroutine do_simd_lastprivate_firstprivate()
9292
! CHECK: omp.wsloop
9393
! CHECK-SAME: private(@[[FIRSTPRIVATE_A_SYM:.*]] %{{.*}} -> %[[FIRSTPRIVATE_A:.*]] : !fir.ref<i32>)
9494
! CHECK-NEXT: omp.simd
95-
! CHECK-SAME: private(@[[PRIVATE_A_SYM:.*]] %{{.*}} -> %[[PRIVATE_A:.*]], @[[PRIVATE_I_SYM:.*]] %{{.*}} -> %[[PRIVATE_I:.*]] : !fir.ref<i32>, !fir.ref<i32>)
95+
! CHECK-SAME: linear({{.*}}#0 : !fir.ref<i32> = %{{[^:]*}} : i32)
96+
! CHECK-SAME: private(@[[PRIVATE_A_SYM:.*]] %{{.*}} -> %[[PRIVATE_A:.*]] : !fir.ref<i32>)
9697
!$omp do simd lastprivate(a) firstprivate(a)
9798
do i = 1, 10
9899
! CHECK: %[[FIRSTPRIVATE_A_DECL:.*]]:2 = hlfir.declare %[[FIRSTPRIVATE_A]]
99100
! CHECK: %[[PRIVATE_A_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_A]]
100-
! CHECK: %[[PRIVATE_I_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_I]]
101101
a = a + 1
102102
end do
103103
!$omp end do simd

0 commit comments

Comments
 (0)