currentLocation, symValue.getType(), symValue);
} else {
mlir::Value symValue = converter.getSymbolAddress(sym);
+ mlir::Operation *op = symValue.getDefiningOp();
+ // The symbol may be use-associated multiple times, and nothing needs to be
+ // done after the original symbol is mapped to the threadprivatized value
+ // for the first time. Use the threadprivatized value directly.
+ if (mlir::isa<mlir::omp::ThreadprivateOp>(op))
+ return;
symThreadprivateValue = firOpBuilder.create<mlir::omp::ThreadprivateOp>(
currentLocation, symValue.getType(), symValue);
}
--- /dev/null
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for threadprivate variable double use in use association.
+
+!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
+!RUN: bbc -emit-fir -fopenmp %s -o - | FileCheck %s
+
+! CHECK-LABEL: fir.global @_QMmEx : i32
+module m
+ integer :: x
+ !$omp threadprivate(x)
+end
+
+! CHECK-LABEL: func.func @_QMm2Ptest() {
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMmEx) : !fir.ref<i32>
+! CHECK: %[[VAL_1:.*]] = omp.threadprivate %[[VAL_0]] : !fir.ref<i32> -> !fir.ref<i32>
+! CHECK: fir.call @_QPbar(%[[VAL_1]]) : (!fir.ref<i32>) -> ()
+! CHECK: return
+! CHECK: }
+!
+! CHECK-LABEL: func.func @_QMm2FtestPinternal_test() {
+! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMmEx) : !fir.ref<i32>
+! CHECK: %[[VAL_1:.*]] = omp.threadprivate %[[VAL_0]] : !fir.ref<i32> -> !fir.ref<i32>
+! CHECK: fir.call @_QPbar(%[[VAL_1]]) : (!fir.ref<i32>) -> ()
+! CHECK: return
+! CHECK: }
+
+module m2
+ use m
+ contains
+ subroutine test()
+ use m
+ call bar(x)
+ contains
+ subroutine internal_test()
+ use m
+ call bar(x)
+ end
+ end
+end