From 240b85b1a8540f1ac000dda9042ac2fbccd9bc69 Mon Sep 17 00:00:00 2001 From: Peixin Qiao Date: Mon, 17 Oct 2022 19:46:18 +0800 Subject: [PATCH] [flang][OpenMP] Fix the use-associated bug in threadprivate directive lowering The symbol may be used by use-association for multiple times such as one in module specification part and one in module procedure. Then in module procedure, the variable instantiation will be called for multiple times. But we only need to threadprivatize it once and use the threadprivatized value for the second time. Fix #58379. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D136035 --- flang/lib/Lower/OpenMP.cpp | 6 ++++ .../OpenMP/threadprivate-use-association-2.f90 | 39 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 flang/test/Lower/OpenMP/threadprivate-use-association-2.f90 diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 82c04ab..adada64 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1774,6 +1774,12 @@ void Fortran::lower::genThreadprivateOp( 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(op)) + return; symThreadprivateValue = firOpBuilder.create( currentLocation, symValue.getType(), symValue); } diff --git a/flang/test/Lower/OpenMP/threadprivate-use-association-2.f90 b/flang/test/Lower/OpenMP/threadprivate-use-association-2.f90 new file mode 100644 index 0000000..615885f --- /dev/null +++ b/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 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 +! 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 -- 2.7.4