[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