Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -1774,6 +1774,12 @@ currentLocation, symValue.getType(), symValue); } else { mlir::Value symValue = converter.getSymbolAddress(sym); + mlir::Operation *op = symValue.getDefiningOp(); + // The symbol may be use-associated for multiple times, there is nothing + // need to do after the original symbol is mapped to the threadprivatized + // value for the first time. Use the threadprivatized value directly. + if (mlir::isa(op)) + return; symThreadprivateValue = firOpBuilder.create( currentLocation, symValue.getType(), symValue); } Index: flang/test/Lower/OpenMP/threadprivate-use-association-2.f90 =================================================================== --- /dev/null +++ flang/test/Lower/OpenMP/threadprivate-use-association-2.f90 @@ -0,0 +1,39 @@ +! This test checks lowering of OpenMP Threadprivate Directive. +! Test for threadprivate variable double used 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 +! CHECK: %[[VAL_1:.*]] = omp.threadprivate %[[VAL_0]] : !fir.ref -> !fir.ref +! CHECK: fir.call @_QPbar(%[[VAL_1]]) : (!fir.ref) -> () +! CHECK: return +! CHECK: } +! +! CHECK-LABEL: func.func @_QMm2FtestPinternal_test() { +! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QMmEx) : !fir.ref +! CHECK: %[[VAL_1:.*]] = omp.threadprivate %[[VAL_0]] : !fir.ref -> !fir.ref +! CHECK: fir.call @_QPbar(%[[VAL_1]]) : (!fir.ref) -> () +! 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