[flang-commits] [flang] [Flang][OpenMP] Port openmp threadprivate tests to HLFIR flow (PR #70440)

via flang-commits flang-commits at lists.llvm.org
Fri Oct 27 03:53:30 PDT 2023


https://github.com/harishch4 created https://github.com/llvm/llvm-project/pull/70440

None

>From f4401ce5fbcd3fd450fc2ac35963b098a7d5add7 Mon Sep 17 00:00:00 2001
From: Harish Chambeti <harishcse44 at gmail.com>
Date: Fri, 27 Oct 2023 16:22:58 +0530
Subject: [PATCH] [Flang][OpenMP] Port openmp threadprivate tests to HLFIR flow

---
 .../threadprivate-char-array-chararray.f90    |  54 +++++++++
 .../OpenMP/threadprivate-commonblock.f90      | 104 ++++++++++++++++++
 .../threadprivate-integer-different-kinds.f90 |  85 ++++++++++++++
 .../Lower/OpenMP/threadprivate-non-global.f90 | 103 +++++++++++++++++
 .../threadprivate-pointer-allocatable.f90     |  63 +++++++++++
 ...ivate-real-logical-complex-derivedtype.f90 |  69 ++++++++++++
 6 files changed, 478 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-char-array-chararray.f90
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-commonblock.f90
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-integer-different-kinds.f90
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-non-global.f90
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-pointer-allocatable.f90
 create mode 100644 flang/test/Lower/OpenMP/threadprivate-real-logical-complex-derivedtype.f90

diff --git a/flang/test/Lower/OpenMP/threadprivate-char-array-chararray.f90 b/flang/test/Lower/OpenMP/threadprivate-char-array-chararray.f90
new file mode 100644
index 000000000000000..ce2490aee4f553a
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-char-array-chararray.f90
@@ -0,0 +1,54 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for character, array, and character array.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+module test
+  character :: x
+  integer :: y(5)
+  character(5) :: z(5)
+
+  !$omp threadprivate(x, y, z)
+
+!CHECK-DAG: fir.global @_QMtestEx : !fir.char<1> {
+!CHECK-DAG: fir.global @_QMtestEy : !fir.array<5xi32> {
+!CHECK-DAG: fir.global @_QMtestEz : !fir.array<5x!fir.char<1,5>> {
+
+contains
+  subroutine sub()
+!CHECK-DAG:  %[[X:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<!fir.char<1>>
+!CHECK-DAG:  %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] typeparams %c1 {uniq_name = "_QMtestEx"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+!CHECK-DAG:  %[[OMP_X:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<!fir.char<1>> -> !fir.ref<!fir.char<1>>
+!CHECK-DAG:  %[[OMP_X_DECL:.*]]:2 = hlfir.declare %[[OMP_X]] typeparams %c1 {uniq_name = "_QMtestEx"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+!CHECK-DAG:  %[[Y:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<!fir.array<5xi32>>
+!CHECK-DAG:  %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]](%{{.*}}) {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>)
+!CHECK-DAG:  %[[OMP_Y:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.array<5xi32>> -> !fir.ref<!fir.array<5xi32>>
+!CHECK-DAG:  %[[OMP_Y_DECL:.*]]:2 = hlfir.declare %[[OMP_Y]](%{{.*}}) {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>)
+!CHECK-DAG:  %[[Z:.*]] = fir.address_of(@_QMtestEz) : !fir.ref<!fir.array<5x!fir.char<1,5>>>
+!CHECK-DAG:  %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]](%{{.*}}) typeparams %c5_0 {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.ref<!fir.array<5x!fir.char<1,5>>>)
+!CHECK-DAG:  %[[OMP_Z:.*]] = omp.threadprivate %[[Z_DECL]]#1 : !fir.ref<!fir.array<5x!fir.char<1,5>>> -> !fir.ref<!fir.array<5x!fir.char<1,5>>>
+!CHECK-DAG:  %[[OMP_Z_DECL:.*]]:2 = hlfir.declare %[[OMP_Z]](%{{.*}}) typeparams %c5_0 {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.ref<!fir.array<5x!fir.char<1,5>>>)
+!CHECK-DAG:  %{{.*}} = fir.convert %[[OMP_X_DECL]]#1 : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[OMP_Y_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<5xi32>>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[OMP_Z_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<5x!fir.char<1,5>>>
+    print *, x, y, z
+
+    !$omp parallel
+!CHECK-DAG:  %[[X_PVT:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<!fir.char<1>> -> !fir.ref<!fir.char<1>>
+!CHECK-DAG:  %[[X_PVT_DECL:.*]]:2 = hlfir.declare %[[X_PVT]] typeparams %c1 {uniq_name = "_QMtestEx"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+!CHECK-DAG:  %[[Y_PVT:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.array<5xi32>> -> !fir.ref<!fir.array<5xi32>>
+!CHECK-DAG:  %[[Y_PVT_DECL:.*]]:2 = hlfir.declare %[[Y_PVT]](%{{.*}}) {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>)
+!CHECK-DAG:  %[[Z_PVT:.*]] = omp.threadprivate %[[Z_DECL]]#1 : !fir.ref<!fir.array<5x!fir.char<1,5>>> -> !fir.ref<!fir.array<5x!fir.char<1,5>>>
+!CHECK-DAG:  %[[Z_PVT_DECL:.*]]:2 = hlfir.declare %[[Z_PVT]](%{{.*}}) typeparams %c5_0 {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.ref<!fir.array<5x!fir.char<1,5>>>)
+!CHECK-DAG:  %{{.*}} = fir.convert %[[X_PVT_DECL]]#1 : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[Y_PVT_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<5xi32>>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[Z_PVT_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<5x!fir.char<1,5>>>
+    print *, x, y, z
+    !$omp end parallel
+!CHECK-DAG:  %{{.*}} = fir.convert %[[OMP_X_DECL]]#1 : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[OMP_Y_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<5xi32>>
+!CHECK-DAG:  %{{.*}} = fir.embox %[[OMP_Z_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<5x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<5x!fir.char<1,5>>>
+    print *, x, y, z
+
+  end
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-commonblock.f90 b/flang/test/Lower/OpenMP/threadprivate-commonblock.f90
new file mode 100644
index 000000000000000..ddbe5bd52465754
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-commonblock.f90
@@ -0,0 +1,104 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for common block.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+module test
+  integer:: a
+  real :: b(2)
+  complex, pointer :: c, d(:)
+  character(5) :: e, f(2)
+  common /blk/ a, b, c, d, e, f
+
+  !$omp threadprivate(/blk/)
+
+!CHECK: fir.global common @blk_(dense<0> : vector<103xi8>) : !fir.array<103xi8>
+
+contains
+  subroutine sub()
+  !CHECK-DAG:  %[[CBLK_ADDR:.*]] = fir.address_of(@blk_) : !fir.ref<!fir.array<103xi8>>
+  !CHECK-DAG:  %[[CBLK_ADDR_CVT:.*]] = fir.convert %[[CBLK_ADDR]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[A_ADDR:.*]] = fir.coordinate_of %[[CBLK_ADDR_CVT]], %c0 : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[A_ADDR_CVT:.*]] = fir.convert %[[A_ADDR]] : (!fir.ref<i8>) -> !fir.ref<i32>
+  !CHECK-DAG:  %[[A_VAL:.*]]:2 = hlfir.declare %[[A_ADDR_CVT]] {uniq_name = "_QMtestEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  !CHECK-DAG:  %[[OMP_CBLK:.*]] = omp.threadprivate %[[CBLK_ADDR]] : !fir.ref<!fir.array<103xi8>> -> !fir.ref<!fir.array<103xi8>>
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[A_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[A_ADDR_CVT:.*]] = fir.convert %[[A_ADDR]] : (!fir.ref<i8>) -> !fir.ref<i32>
+  !CHECK-DAG:  %[[A_DECL:.*]]:2 = hlfir.declare %[[A_ADDR_CVT]] {uniq_name = "_QMtestEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[B_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[B_ADDR_CVT:.*]] = fir.convert %[[B_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.array<2xf32>>
+  !CHECK-DAG:  %[[B_DECL:.*]]:2 = hlfir.declare %[[B_ADDR_CVT]]({{.*}}) {uniq_name = "_QMtestEb"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[C_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[C_ADDR_CVT:.*]] = fir.convert %[[C_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>
+  !CHECK-DAG:  %[[C_DECL:.*]]:2 = hlfir.declare %[[C_ADDR_CVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEc"} : (!fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>)
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[D_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[D_ADDR_CVT:.*]] = fir.convert %[[D_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>
+  !CHECK-DAG:  %[[D_DECL:.*]]:2 = hlfir.declare %[[D_ADDR_CVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEd"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>)
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[E_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[E_ADDR_CVT:.*]] = fir.convert %[[E_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.char<1,5>>
+  !CHECK-DAG:  %[[E_DECL:.*]]:2 = hlfir.declare %[[E_ADDR_CVT]] typeparams {{.*}} {uniq_name = "_QMtestEe"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
+  !CHECK-DAG:  %[[OMP_CBLK_ADDR:.*]] = fir.convert %[[OMP_CBLK]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+  !CHECK-DAG:  %[[F_ADDR:.*]] = fir.coordinate_of %[[OMP_CBLK_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+  !CHECK-DAG:  %[[F_ADDR_CVT:.*]] = fir.convert %[[F_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
+  !CHECK-DAG:  %[[F_DECL:.*]]:2 = hlfir.declare %[[F_ADDR_CVT]]({{.*}}) typeparams {{.*}} {uniq_name = "_QMtestEf"} : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.ref<!fir.array<2x!fir.char<1,5>>>)
+  !CHECK-DAG:  {{.*}} = fir.load %[[A_DECL]]#0 : !fir.ref<i32>
+  !CHECK-DAG:  {{.*}} = fir.embox %[[B_DECL]]#1({{.*}}) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+  !CHECK-DAG:  {{.*}} = fir.load %[[C_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>
+  !CHECK-DAG:  {{.*}} = fir.load %[[D_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>
+  !CHECK-DAG:  {{.*}} = fir.convert %[[E_DECL]]#1 : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<i8>
+  !CHECK-DAG:  {{.*}} = fir.embox %[[F_DECL]]#1({{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
+    print *, a, b, c, d, e, f
+
+    !$omp parallel
+    !CHECK-DAG: omp.parallel   {
+    !CHECK-DAG:  %[[TP_PARALLEL:.*]] = omp.threadprivate %[[CBLK_ADDR]] : !fir.ref<!fir.array<103xi8>> -> !fir.ref<!fir.array<103xi8>>
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_A_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_A_ADDR_CVT:.*]] = fir.convert %[[TP_A_ADDR]] : (!fir.ref<i8>) -> !fir.ref<i32>
+    !CHECK-DAG:  %[[TP_A_DECL:.*]]:2 = hlfir.declare %[[TP_A_ADDR_CVT]] {uniq_name = "_QMtestEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_B_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_B_ADDR_CVT:.*]] = fir.convert %[[TP_B_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.array<2xf32>>
+    !CHECK-DAG:  %[[TP_B_DECL:.*]]:2 = hlfir.declare %[[TP_B_ADDR_CVT]](%92) {uniq_name = "_QMtestEb"} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>)
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_C_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_C_ADDR_CVT:.*]] = fir.convert %[[TP_C_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>
+    !CHECK-DAG:  %[[TP_C_DECL:.*]]:2 = hlfir.declare %[[TP_C_ADDR_CVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEc"} : (!fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>)
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_D_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_D_ADDR_CVT:.*]] = fir.convert %[[TP_D_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>
+    !CHECK-DAG:  %[[TP_D_DECL:.*]]:2 = hlfir.declare %[[TP_D_ADDR_CVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEd"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>)
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_E_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], {{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_E_ADDR_CVT:.*]] = fir.convert %[[TP_E_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.char<1,5>>
+    !CHECK-DAG:  %[[TP_E_DECL:.*]]:2 = hlfir.declare %[[TP_E_ADDR_CVT]] typeparams {{.*}} {uniq_name = "_QMtestEe"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
+    !CHECK-DAG:  %[[TP_PARALLEL_ADDR:.*]] = fir.convert %[[TP_PARALLEL]] : (!fir.ref<!fir.array<103xi8>>) -> !fir.ref<!fir.array<?xi8>>
+    !CHECK-DAG:  %[[TP_F_ADDR:.*]] = fir.coordinate_of %[[TP_PARALLEL_ADDR]], %{{.*}} : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
+    !CHECK-DAG:  %[[TP_F_ADDR_CVT:.*]] = fir.convert %[[TP_F_ADDR]] : (!fir.ref<i8>) -> !fir.ref<!fir.array<2x!fir.char<1,5>>>
+    !CHECK-DAG:  %[[TP_F_DECL:.*]]:2 = hlfir.declare %[[TP_F_ADDR_CVT]]({{.*}}) typeparams {{.*}} {uniq_name = "_QMtestEf"} : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>, index) -> (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.ref<!fir.array<2x!fir.char<1,5>>>)
+    !CHECK-DAG:  {{.*}} = fir.load %[[TP_A_DECL]]#0 : !fir.ref<i32>
+    !CHECK-DAG:  {{.*}} = fir.embox %[[TP_B_DECL]]#1({{.*}}) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+    !CHECK-DAG:  {{.*}} = fir.load %[[TP_C_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>
+    !CHECK-DAG:  {{.*}} = fir.load %[[TP_D_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>
+    !CHECK-DAG:  {{.*}} = fir.convert %[[TP_E_DECL]]#1 : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<i8>
+    !CHECK-DAG:  {{.*}} = fir.embox %[[TP_F_DECL]]#1(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
+    !CHECK-DAG: omp.terminator
+    !CHECK-DAG: }
+    print *, a, b, c, d, e, f
+    !$omp end parallel
+
+  !CHECK-DAG:  %{{.*}} = fir.load %[[A_DECL]]#0 : !fir.ref<i32>
+  !CHECK-DAG:  %{{.*}} = fir.embox %[[B_DECL]]#1(%63) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
+  !CHECK-DAG:  %{{.*}} = fir.load %[[C_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.complex<4>>>>
+  !CHECK-DAG:  %{{.*}} = fir.load %[[D_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.complex<4>>>>>
+  !CHECK-DAG:  %{{.*}} = fir.convert %[[E_DECL]]#1 : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<i8>
+  !CHECK-DAG:  %{{.*}} = fir.embox %[[F_DECL]]#1(%79) : (!fir.ref<!fir.array<2x!fir.char<1,5>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1,5>>>
+    print *, a, b, c, d, e, f
+
+  end
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-integer-different-kinds.f90 b/flang/test/Lower/OpenMP/threadprivate-integer-different-kinds.f90
new file mode 100644
index 000000000000000..660202221e3f87c
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-integer-different-kinds.f90
@@ -0,0 +1,85 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for variables with different kind.
+
+!REQUIRES: shell
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+program test
+  integer, save :: i
+  integer(kind=1), save :: i1
+  integer(kind=2), save :: i2
+  integer(kind=4), save :: i4
+  integer(kind=8), save :: i8
+  integer(kind=16), save :: i16
+
+!CHECK-DAG:  %[[I:.*]] = fir.address_of(@_QFEi) : !fir.ref<i32>
+!CHECK-DAG:  %[[I_DECL:.*]]:2 = hlfir.declare %[[I]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[OMP_I:.*]] = omp.threadprivate %[[I_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[OMP_I_DECL:.*]]:2 = hlfir.declare %[[OMP_I]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[I1:.*]] = fir.address_of(@_QFEi1) : !fir.ref<i8>
+!CHECK-DAG:  %[[I1_DECL:.*]]:2 = hlfir.declare %[[I1]] {uniq_name = "_QFEi1"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>)
+!CHECK-DAG:  %[[OMP_I1:.*]] = omp.threadprivate %[[I1_DECL]]#1 : !fir.ref<i8> -> !fir.ref<i8>
+!CHECK-DAG:  %[[OMP_I1_DECL:.*]]:2 = hlfir.declare %[[OMP_I1]] {uniq_name = "_QFEi1"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>)
+!CHECK-DAG:  %[[I16:.*]] = fir.address_of(@_QFEi16) : !fir.ref<i128>
+!CHECK-DAG:  %[[I16_DECL:.*]]:2 = hlfir.declare %[[I16]] {uniq_name = "_QFEi16"} : (!fir.ref<i128>) -> (!fir.ref<i128>, !fir.ref<i128>)
+!CHECK-DAG:  %[[OMP_I16:.*]] = omp.threadprivate %[[I16_DECL]]#1 : !fir.ref<i128> -> !fir.ref<i128>
+!CHECK-DAG:  %[[OMP_I16_DECL:.*]]:2 = hlfir.declare %[[OMP_I16]] {uniq_name = "_QFEi16"} : (!fir.ref<i128>) -> (!fir.ref<i128>, !fir.ref<i128>)
+!CHECK-DAG:  %[[I2:.*]] = fir.address_of(@_QFEi2) : !fir.ref<i16>
+!CHECK-DAG:  %[[I2_DECL:.*]]:2 = hlfir.declare %[[I2]] {uniq_name = "_QFEi2"} : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>)
+!CHECK-DAG:  %[[OMP_I2:.*]] = omp.threadprivate %[[I2_DECL]]#1 : !fir.ref<i16> -> !fir.ref<i16>
+!CHECK-DAG:  %[[OMP_I2_DECL:.*]]:2 = hlfir.declare %[[OMP_I2]] {uniq_name = "_QFEi2"} : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>)
+!CHECK-DAG:  %[[I4:.*]] = fir.address_of(@_QFEi4) : !fir.ref<i32>
+!CHECK-DAG:  %[[I4_DECL:.*]]:2 = hlfir.declare %[[I4]] {uniq_name = "_QFEi4"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[OMP_I4:.*]] = omp.threadprivate %[[I4_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[OMP_I4_DECL:.*]]:2 = hlfir.declare %[[OMP_I4]] {uniq_name = "_QFEi4"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[I8:.*]] = fir.address_of(@_QFEi8) : !fir.ref<i64>
+!CHECK-DAG:  %[[I8_DECL:.*]]:2 = hlfir.declare %[[I8]] {uniq_name = "_QFEi8"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+!CHECK-DAG:  %[[OMP_I8:.*]] = omp.threadprivate %[[I8_DECL]]#1 : !fir.ref<i64> -> !fir.ref<i64>
+!CHECK-DAG:  %[[OMP_I8_DECL:.*]]:2 = hlfir.declare %[[OMP_I8]] {uniq_name = "_QFEi8"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+  !$omp threadprivate(i, i1, i2, i4, i8, i16)
+
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I1_DECL]]#0 : !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I16_DECL]]#0 : !fir.ref<i128>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I2_DECL]]#0 : !fir.ref<i16>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I4_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I8_DECL]]#0 : !fir.ref<i64>
+  print *, i, i1, i2, i4, i8, i16
+
+  !$omp parallel
+!CHECK-DAG:  %[[I_PVT:.*]] = omp.threadprivate %[[I_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[I_PVT_DECL:.*]]:2 = hlfir.declare %[[I_PVT]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[I1_PVT:.*]] = omp.threadprivate %[[I1_DECL]]#1 : !fir.ref<i8> -> !fir.ref<i8>
+!CHECK-DAG:  %[[I1_PVT_DECL:.*]]:2 = hlfir.declare %[[I1_PVT]] {uniq_name = "_QFEi1"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>)
+!CHECK-DAG:  %[[I2_PVT:.*]] = omp.threadprivate %[[I2_DECL]]#1 : !fir.ref<i16> -> !fir.ref<i16>
+!CHECK-DAG:  %[[I2_PVT_DECL:.*]]:2 = hlfir.declare %[[I2_PVT]] {uniq_name = "_QFEi2"} : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>)
+!CHECK-DAG:  %[[I4_PVT:.*]] = omp.threadprivate %[[I4_DECL]]#1 : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[I4_PVT_DECL:.*]]:2 = hlfir.declare %[[I4_PVT]] {uniq_name = "_QFEi4"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[I8_PVT:.*]] = omp.threadprivate %[[I8_DECL]]#1 : !fir.ref<i64> -> !fir.ref<i64>
+!CHECK-DAG:  %[[I8_PVT_DECL:.*]]:2 = hlfir.declare %[[I8_PVT]] {uniq_name = "_QFEi8"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+!CHECK-DAG:  %[[I16_PVT:.*]] = omp.threadprivate %[[I16_DECL]]#1 : !fir.ref<i128> -> !fir.ref<i128>
+!CHECK-DAG:  %[[I16_PVT_DECL:.*]]:2 = hlfir.declare %[[I16_PVT]] {uniq_name = "_QFEi16"} : (!fir.ref<i128>) -> (!fir.ref<i128>, !fir.ref<i128>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[I_PVT_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[I1_PVT_DECL]]#0 : !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.load %[[I16_PVT_DECL]]#0 : !fir.ref<i128>
+!CHECK-DAG:  %{{.*}} = fir.load %[[I2_PVT_DECL]]#0 : !fir.ref<i16>
+!CHECK-DAG:  %{{.*}} = fir.load %[[I4_PVT_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[I8_PVT_DECL]]#0 : !fir.ref<i64>
+    print *, i, i1, i2, i4, i8, i16
+  !$omp end parallel
+
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I1_DECL]]#0 : !fir.ref<i8>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I16_DECL]]#0 : !fir.ref<i128>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I2_DECL]]#0 : !fir.ref<i16>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I4_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_I8_DECL]]#0 : !fir.ref<i64>
+  print *, i, i1, i2, i4, i8, i16
+
+!CHECK-DAG: fir.global internal @_QFEi : i32 {
+!CHECK-DAG: fir.global internal @_QFEi1 : i8 {
+!CHECK-DAG: fir.global internal @_QFEi16 : i128 {
+!CHECK-DAG: fir.global internal @_QFEi2 : i16 {
+!CHECK-DAG: fir.global internal @_QFEi4 : i32 {
+!CHECK-DAG: fir.global internal @_QFEi8 : i64 {
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-non-global.f90 b/flang/test/Lower/OpenMP/threadprivate-non-global.f90
new file mode 100644
index 000000000000000..7cdadabe2247a25
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-non-global.f90
@@ -0,0 +1,103 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for non-character non-SAVEd non-initialized scalars with or without
+! allocatable or pointer attribute in main program.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+program test
+  integer :: x
+  real :: y
+  logical :: z
+  complex :: w
+  integer, pointer :: a
+  real, allocatable :: b
+
+!CHECK-DAG:  %[[A:.*]] = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[OMP_A:.*]] = omp.threadprivate %[[A]] : !fir.ref<!fir.box<!fir.ptr<i32>>> -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[OMP_A_DECL:.*]]:2 = hlfir.declare %[[OMP_A]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-DAG:  %[[B:.*]] = fir.address_of(@_QFEb) : !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[OMP_B:.*]] = omp.threadprivate %[[B]] : !fir.ref<!fir.box<!fir.heap<f32>>> -> !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[OMP_B_DECL:.*]]:2 = hlfir.declare %[[OMP_B]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+!CHECK-DAG:  %[[W:.*]] = fir.address_of(@_QFEw) : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[OMP_W:.*]] = omp.threadprivate %[[W]] : !fir.ref<!fir.complex<4>> -> !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[OMP_W_DECL:.*]]:2 = hlfir.declare %[[OMP_W]] {uniq_name = "_QFEw"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+!CHECK-DAG:  %[[X:.*]] = fir.address_of(@_QFEx) : !fir.ref<i32>
+!CHECK-DAG:  %[[OMP_X:.*]] = omp.threadprivate %[[X]] : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[OMP_X_DECL:.*]]:2 = hlfir.declare %[[OMP_X]] {uniq_name = "_QFEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[Y:.*]] = fir.address_of(@_QFEy) : !fir.ref<f32>
+!CHECK-DAG:  %[[OMP_Y:.*]] = omp.threadprivate %[[Y]] : !fir.ref<f32> -> !fir.ref<f32>
+!CHECK-DAG:  %[[OMP_Y_DECL:.*]]:2 = hlfir.declare %[[OMP_Y]] {uniq_name = "_QFEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+!CHECK-DAG:  %[[Z:.*]] = fir.address_of(@_QFEz) : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[OMP_Z:.*]] = omp.threadprivate %[[Z]] : !fir.ref<!fir.logical<4>> -> !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[OMP_Z_DECL:.*]]:2 = hlfir.declare %[[OMP_Z]] {uniq_name = "_QFEz"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+  !$omp threadprivate(x, y, z, w, a, b)
+
+  call sub(a, b)
+
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Z_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_W_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_A_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_B_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+  print *, x, y, z, w, a, b
+
+  !$omp parallel
+!CHECK-DAG:  %[[X_PVT:.*]] = omp.threadprivate %[[X]] : !fir.ref<i32> -> !fir.ref<i32>
+!CHECK-DAG:  %[[X_PVT_DECL:.*]]:2 = hlfir.declare %[[X_PVT]] {uniq_name = "_QFEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK-DAG:  %[[Y_PVT:.*]] = omp.threadprivate %[[Y]] : !fir.ref<f32> -> !fir.ref<f32>
+!CHECK-DAG:  %[[Y_PVT_DECL:.*]]:2 = hlfir.declare %[[Y_PVT]] {uniq_name = "_QFEy"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+!CHECK-DAG:  %[[Z_PVT:.*]] = omp.threadprivate %[[Z]] : !fir.ref<!fir.logical<4>> -> !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[Z_PVT_DECL:.*]]:2 = hlfir.declare %[[Z_PVT]] {uniq_name = "_QFEz"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+!CHECK-DAG:  %[[W_PVT:.*]] = omp.threadprivate %[[W]] : !fir.ref<!fir.complex<4>> -> !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[W_PVT_DECL:.*]]:2 = hlfir.declare %[[W_PVT]] {uniq_name = "_QFEw"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+!CHECK-DAG:  %[[A_PVT:.*]] = omp.threadprivate %[[A]] : !fir.ref<!fir.box<!fir.ptr<i32>>> -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[A_PVT_DECL:.*]]:2 = hlfir.declare %[[A_PVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-DAG:  %[[B_PVT:.*]] = omp.threadprivate %[[B]] : !fir.ref<!fir.box<!fir.heap<f32>>> -> !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[B_PVT_DECL:.*]]:2 = hlfir.declare %[[B_PVT]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[X_PVT_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Y_PVT_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Z_PVT_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[W_PVT_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[A_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[B_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+  print *, x, y, z, w, a, b
+  !$omp end parallel
+
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#0 : !fir.ref<i32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Z_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_W_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_A_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_B_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+  print *, x, y, z, w, a, b
+
+!CHECK:  return
+
+!CHECK-DAG: fir.global internal @_QFEa : !fir.box<!fir.ptr<i32>> {
+!CHECK-DAG:   [[Z0:%.*]] = fir.zero_bits !fir.ptr<i32>
+!CHECK-DAG:   [[E0:%.*]] = fir.embox [[Z0]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+!CHECK-DAG:   fir.has_value [[E0]] : !fir.box<!fir.ptr<i32>>
+!CHECK-DAG: }
+!CHECK-DAG: fir.global internal @_QFEb : !fir.box<!fir.heap<f32>> {
+!CHECK-DAG:   [[Z1:%.*]] = fir.zero_bits !fir.heap<f32>
+!CHECK-DAG:   [[E1:%.*]] = fir.embox [[Z1]] : (!fir.heap<f32>) -> !fir.box<!fir.heap<f32>>
+!CHECK-DAG:   fir.has_value [[E1]] : !fir.box<!fir.heap<f32>>
+!CHECK-DAG: }
+!CHECK-DAG: fir.global internal @_QFEw : !fir.complex<4> {
+!CHECK-DAG:   [[Z2:%.*]] = fir.undefined !fir.complex<4>
+!CHECK-DAG:   fir.has_value [[Z2]] : !fir.complex<4>
+!CHECK-DAG: }
+!CHECK-DAG: fir.global internal @_QFEx : i32 {
+!CHECK-DAG:   [[Z3:%.*]] = fir.undefined i32
+!CHECK-DAG:   fir.has_value [[Z3]] : i32
+!CHECK-DAG: }
+!CHECK-DAG: fir.global internal @_QFEy : f32 {
+!CHECK-DAG:   [[Z4:%.*]] = fir.undefined f32
+!CHECK-DAG:   fir.has_value [[Z4]] : f32
+!CHECK-DAG: }
+!CHECK-DAG: fir.global internal @_QFEz : !fir.logical<4> {
+!CHECK-DAG:   [[Z5:%.*]] = fir.undefined !fir.logical<4>
+!CHECK-DAG:   fir.has_value [[Z5]] : !fir.logical<4>
+!CHECK-DAG: }
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-pointer-allocatable.f90 b/flang/test/Lower/OpenMP/threadprivate-pointer-allocatable.f90
new file mode 100644
index 000000000000000..059667d35d840d0
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-pointer-allocatable.f90
@@ -0,0 +1,63 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for allocatable and pointer variables.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+module test
+  integer, pointer :: x(:), m
+  real, allocatable :: y(:), n
+
+  !$omp threadprivate(x, y, m, n)
+
+!CHECK-DAG: fir.global @_QMtestEm : !fir.box<!fir.ptr<i32>> {
+!CHECK-DAG: fir.global @_QMtestEn : !fir.box<!fir.heap<f32>> {
+!CHECK-DAG: fir.global @_QMtestEx : !fir.box<!fir.ptr<!fir.array<?xi32>>> {
+!CHECK-DAG: fir.global @_QMtestEy : !fir.box<!fir.heap<!fir.array<?xf32>>> {
+
+contains
+  subroutine sub()
+!CHECK-DAG:  %[[M:.*]] = fir.address_of(@_QMtestEm) : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[M_DECL:.*]]:2 = hlfir.declare %[[M]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEm"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-DAG:  %[[OMP_M:.*]] = omp.threadprivate %[[M_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>> -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[OMP_M_DECL:.*]]:2 = hlfir.declare %[[OMP_M]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEm"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-DAG:  %[[N:.*]] = fir.address_of(@_QMtestEn) : !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[N_DECL:.*]]:2 = hlfir.declare %[[N]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEn"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+!CHECK-DAG:  %[[OMP_N:.*]] = omp.threadprivate %[[N_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<f32>>> -> !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[OMP_N_DECL:.*]]:2 = hlfir.declare %[[OMP_N]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEn"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+!CHECK-DAG:  %[[X:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+!CHECK-DAG:  %[[OMP_X:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %[[OMP_X_DECL:.*]]:2 = hlfir.declare %[[OMP_X]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+!CHECK-DAG:  %[[Y:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEy"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+!CHECK-DAG:  %[[OMP_Y:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %[[OMP_Y_DECL:.*]]:2 = hlfir.declare %[[OMP_Y]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEy"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_M_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_N_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+    print *, x, y, m, n
+
+    !$omp parallel
+!CHECK-DAG:  %[[X_PVT:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %[[X_PVT_DECL:.*]]:2 = hlfir.declare %[[X_PVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEx"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
+!CHECK-DAG:  %[[Y_PVT:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %[[Y_PVT_DECL:.*]]:2 = hlfir.declare %[[Y_PVT]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEy"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+!CHECK-DAG:  %[[Z_PVT:.*]] = omp.threadprivate %[[M_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<i32>>> -> !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %[[Z_PVT_DECL:.*]]:2 = hlfir.declare %[[Z_PVT]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtestEm"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-DAG:  %[[N_PVT:.*]] = omp.threadprivate %[[N_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<f32>>> -> !fir.ref<!fir.box<!fir.heap<f32>>>
+!CHECK-DAG:  %[[N_PVT_DECL:.*]]:2 = hlfir.declare %[[N_PVT]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtestEn"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[X_PVT_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Y_PVT_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Z_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[N_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+      print *, x, y, m, n
+    !$omp end parallel
+
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_M_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_N_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<f32>>>
+    print *, x, y, m, n
+  end
+end
diff --git a/flang/test/Lower/OpenMP/threadprivate-real-logical-complex-derivedtype.f90 b/flang/test/Lower/OpenMP/threadprivate-real-logical-complex-derivedtype.f90
new file mode 100644
index 000000000000000..55f806962a609fa
--- /dev/null
+++ b/flang/test/Lower/OpenMP/threadprivate-real-logical-complex-derivedtype.f90
@@ -0,0 +1,69 @@
+! This test checks lowering of OpenMP Threadprivate Directive.
+! Test for real, logical, complex, and derived type.
+
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
+
+module test
+  type my_type
+    integer :: t_i
+    real :: t_arr(5)
+  end type my_type
+  real :: x
+  complex :: y
+  logical :: z
+  type(my_type) :: t
+
+  !$omp threadprivate(x, y, z, t)
+
+!CHECK-DAG: fir.global @_QMtestEt : !fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}> {
+!CHECK-DAG: fir.global @_QMtestEx : f32 {
+!CHECK-DAG: fir.global @_QMtestEy : !fir.complex<4> {
+!CHECK-DAG: fir.global @_QMtestEz : !fir.logical<4> {
+
+contains
+  subroutine sub()
+!CHECK-DAG:  %[[T:.*]] = fir.address_of(@_QMtestEt) : !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>
+!CHECK-DAG:  %[[T_DECL:.*]]:2 = hlfir.declare %[[T]] {uniq_name = "_QMtestEt"} : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>, !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>)
+!CHECK-DAG:  %[[OMP_T:.*]] = omp.threadprivate %[[T_DECL]]#1 : !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>> -> !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>
+!CHECK-DAG:  %[[OMP_T_DECL:.*]]:2 = hlfir.declare %[[OMP_T]] {uniq_name = "_QMtestEt"} : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>, !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>)
+!CHECK-DAG:  %[[X:.*]] = fir.address_of(@_QMtestEx) : !fir.ref<f32>
+!CHECK-DAG:  %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+!CHECK-DAG:  %[[OMP_X:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<f32> -> !fir.ref<f32>
+!CHECK-DAG:  %[[OMP_X_DECL:.*]]:2 = hlfir.declare %[[OMP_X]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+!CHECK-DAG:  %[[Y:.*]] = fir.address_of(@_QMtestEy) : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+!CHECK-DAG:  %[[OMP_Y:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.complex<4>> -> !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[OMP_Y_DECL:.*]]:2 = hlfir.declare %[[OMP_Y]] {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+!CHECK-DAG:  %[[Z:.*]] = fir.address_of(@_QMtestEz) : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+!CHECK-DAG:  %[[OMP_Z:.*]] = omp.threadprivate %[[Z_DECL]]#1 : !fir.ref<!fir.logical<4>> -> !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[OMP_Z_DECL:.*]]:2 = hlfir.declare %[[OMP_Z]] {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Z_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = hlfir.designate %[[OMP_T_DECL]]#0{"t_i"}   : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> !fir.ref<i32>
+    print *, x, y, z, t%t_i
+
+    !$omp parallel
+!CHECK-DAG:  %[[T_PVT:.*]] = omp.threadprivate %[[T_DECL]]#1 : !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>> -> !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>
+!CHECK-DAG:  %[[T_PVT_DECL:.*]]:2 = hlfir.declare %[[T_PVT]] {uniq_name = "_QMtestEt"} : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>, !fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>)
+!CHECK-DAG:  %[[X_PVT:.*]] = omp.threadprivate %[[X_DECL]]#1 : !fir.ref<f32> -> !fir.ref<f32>
+!CHECK-DAG:  %[[X_PVT_DECL:.*]]:2 = hlfir.declare %[[X_PVT]] {uniq_name = "_QMtestEx"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+!CHECK-DAG:  %[[Y_PVT:.*]] = omp.threadprivate %[[Y_DECL]]#1 : !fir.ref<!fir.complex<4>> -> !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %[[Y_PVT_DECL:.*]]:2 = hlfir.declare %[[Y_PVT]] {uniq_name = "_QMtestEy"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+!CHECK-DAG:  %[[Z_PVT:.*]] = omp.threadprivate %[[Z_DECL]]#1 : !fir.ref<!fir.logical<4>> -> !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %[[Z_PVT_DECL:.*]]:2 = hlfir.declare %[[Z_PVT]] {uniq_name = "_QMtestEz"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
+!CHECK-DAG:  %{{.*}} = fir.load %[[X_PVT_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Y_PVT_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[Z_PVT_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = hlfir.designate %[[T_PVT_DECL]]#0{"t_i"}   : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> !fir.ref<i32>
+print *, x, y, z, t%t_i
+    !$omp end parallel
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_X_DECL]]#0 : !fir.ref<f32>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Y_DECL]]#0 : !fir.ref<!fir.complex<4>>
+!CHECK-DAG:  %{{.*}} = fir.load %[[OMP_Z_DECL]]#0 : !fir.ref<!fir.logical<4>>
+!CHECK-DAG:  %{{.*}} = hlfir.designate %[[OMP_T_DECL]]#0{"t_i"}   : (!fir.ref<!fir.type<_QMtestTmy_type{t_i:i32,t_arr:!fir.array<5xf32>}>>) -> !fir.ref<i32>
+    print *, x, y, z, t%t_i
+
+  end
+end



More information about the flang-commits mailing list