| ! Test lowering of COPYIN clause for derived types with allocatable components. |
| ! Threadprivate copies may have uninitialized allocatable component descriptors |
| ! (zero-filled by the OpenMP runtime). For non-master threads, use |
| ! temporary_lhs semantics so that AssignTemporary initializes descriptors |
| ! before performing the deep copy. The master thread is skipped via a runtime |
| ! address comparison (lhs == rhs means same threadprivate storage). |
| |
| ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s |
| ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s |
| |
| ! CHECK-LABEL: func.func @_QPcopyin_derived_alloc_comp |
| subroutine copyin_derived_alloc_comp() |
| type inner |
| integer, allocatable :: a(:) |
| end type inner |
| type outer |
| type(inner) :: s |
| end type outer |
| type(outer), save :: x(2) |
| !$omp threadprivate(x) |
| |
| allocate(x(1)%s%a(3)) |
| x(1)%s%a = 42 |
| |
| ! CHECK: omp.parallel { |
| ! CHECK: omp.threadprivate |
| ! CHECK: hlfir.declare |
| ! CHECK: fir.convert {{.*}} -> index |
| ! CHECK: fir.convert {{.*}} -> index |
| ! CHECK: arith.cmpi eq, {{.*}} : index |
| ! CHECK: fir.if |
| ! CHECK: } else { |
| ! CHECK: hlfir.assign {{.*}} temporary_lhs |
| ! CHECK: } |
| ! CHECK: omp.barrier |
| !$omp parallel copyin(x) |
| call sub(x(1)%s%a) |
| !$omp end parallel |
| deallocate(x(1)%s%a) |
| end subroutine |
| |
| ! CHECK-LABEL: func.func @_QPcopyin_scalar_derived_alloc_comp |
| subroutine copyin_scalar_derived_alloc_comp() |
| type dt |
| integer, allocatable :: a(:) |
| end type dt |
| type(dt), save :: y |
| !$omp threadprivate(y) |
| allocate(y%a(5)) |
| y%a = 10 |
| |
| ! CHECK: omp.parallel { |
| ! CHECK: omp.threadprivate |
| ! CHECK: hlfir.declare |
| ! CHECK: fir.convert {{.*}} -> index |
| ! CHECK: fir.convert {{.*}} -> index |
| ! CHECK: arith.cmpi eq, {{.*}} : index |
| ! CHECK: fir.if |
| ! CHECK: } else { |
| ! CHECK: hlfir.assign {{.*}} temporary_lhs |
| ! CHECK: } |
| ! CHECK: omp.barrier |
| !$omp parallel copyin(y) |
| call sub(y%a) |
| !$omp end parallel |
| deallocate(y%a) |
| end subroutine |
| |
| ! Derived type WITHOUT allocatable components: plain assign, no address check. |
| ! CHECK-LABEL: func.func @_QPcopyin_no_alloc_comp |
| subroutine copyin_no_alloc_comp() |
| type simple |
| integer :: val |
| end type simple |
| type(simple), save :: z |
| !$omp threadprivate(z) |
| ! CHECK: omp.parallel { |
| ! CHECK: omp.threadprivate |
| ! CHECK: hlfir.declare |
| ! CHECK-NOT: arith.cmpi |
| ! CHECK: hlfir.assign |
| ! CHECK-NOT: temporary_lhs |
| ! CHECK: omp.barrier |
| !$omp parallel copyin(z) |
| call sub2(z%val) |
| !$omp end parallel |
| end subroutine |
| |