Skip to content

Commit 7fa388d

Browse files
authored
[Flang][OpenMP] Fix bug with default(none) and host-assoc threadprivate variable (#134122)
When a host associated `threadprivate` variable was used in a parallel region with `default(none)` in an internal subroutine was failing, because the compiler did not properly determine that the variable was pre-determined `threadprivate` and thus should not have been reported as missing a DSA.
1 parent 48bad5b commit 7fa388d

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
23012301
if (symbol != found) {
23022302
name.symbol = found; // adjust the symbol within region
23032303
} else if (GetContext().defaultDSA == Symbol::Flag::OmpNone &&
2304-
!symbol->test(Symbol::Flag::OmpThreadprivate) &&
2304+
!symbol->GetUltimate().test(Symbol::Flag::OmpThreadprivate) &&
23052305
// Exclude indices of sequential loops that are privatised in
23062306
// the scope of the parallel region, and not in this scope.
23072307
// TODO: check whether this should be caught in IsObjectWithDSA
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
! This test checks lowering of OpenMP Threadprivate Directive.
2+
! Test for threadprivate variable in host association.
3+
4+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
5+
6+
!CHECK: func.func @_QQmain() attributes {fir.bindc_name = "main"} {
7+
!CHECK: %[[A:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
8+
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs<internal_assoc>, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
9+
!CHECK: %[[A_ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
10+
!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
11+
!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {fortran_attrs = #fir.var_attrs<internal_assoc>, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
12+
!CHECK: fir.call @_QFPsub() fastmath<contract> : () -> ()
13+
!CHECK: return
14+
!CHECK: }
15+
!CHECK: func.func private @_QFPsub() attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
16+
!CHECK: %[[A:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFEa"}
17+
!CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
18+
!CHECK: %[[A_ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref<i32>
19+
!CHECK: %[[TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
20+
!CHECK: %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
21+
!CHECK: omp.parallel {
22+
!CHECK: %[[PAR_TP_A:.*]] = omp.threadprivate %[[A_ADDR]] : !fir.ref<i32> -> !fir.ref<i32>
23+
!CHECK: %[[PAR_TP_A_DECL:.*]]:2 = hlfir.declare %[[PAR_TP_A]] {uniq_name = "_QFEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
24+
!CHECK: %{{.*}} = fir.load %[[PAR_TP_A_DECL]]#0 : !fir.ref<i32>
25+
!CHECK: omp.terminator
26+
!CHECK: }
27+
!CHECK: return
28+
!CHECK: }
29+
!CHECK: fir.global internal @_QFEa : i32 {
30+
!CHECK: %[[A:.*]] = fir.undefined i32
31+
!CHECK: fir.has_value %[[A]] : i32
32+
!CHECK: }
33+
34+
program main
35+
integer :: a
36+
!$omp threadprivate(a)
37+
call sub()
38+
contains
39+
subroutine sub()
40+
!$omp parallel default(none)
41+
print *, a
42+
!$omp end parallel
43+
end
44+
end

0 commit comments

Comments
 (0)