! This test checks the lowering of the OpenMP `declare simd` directive with ! different clauses (e.g. aligned, linear, simdlen). It also verifies that ! the `omp.declare_simd` operation is emitted after the function prologue, ! since the directive requires access to function arguments. ! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s ! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -cpp -DOMP_60 %s -o - | FileCheck %s subroutine declare_simd_no_clause() #ifdef OMP_60 !$omp declare_simd #else !$omp declare simd #endif end subroutine declare_simd_no_clause ! CHECK-LABEL: func.func @_QPdeclare_simd_no_clause() ! CHECK: omp.declare_simd{{$}} ! CHECK: return subroutine declare_simd_aligned(x, y, n, i) #ifdef OMP_60 !$omp declare_simd aligned(x, y : 64) #else !$omp declare simd aligned(x, y : 64) #endif real(8), pointer, intent(inout) :: x(:) real(8), pointer, intent(in) :: y(:) integer, intent(in) :: n, i if (i <= n) x(i) = x(i) + y(i) end subroutine declare_simd_aligned ! CHECK-LABEL: func.func @_QPdeclare_simd_aligned( ! CHECK: %[[SCOPE_A:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[I_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 4 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[N_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 3 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[X_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 1 {{.*pointer.*}} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[Y_A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE_A]] arg 2 {{.*pointer.*}} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: omp.declare_simd aligned(%[[X_A]]#0 : !fir.ref>>> -> 64 : i64, ! CHECK-SAME: %[[Y_A]]#0 : !fir.ref>>> -> 64 : i64){{$}} ! CHECK: return subroutine declare_simd_linear(x, y, n, i) #ifdef OMP_60 !$omp declare_simd linear(i) #else !$omp declare simd linear(i) #endif real(8), pointer, intent(inout) :: x(:) real(8), pointer, intent(in) :: y(:) integer, intent(in) :: n, i if (i <= n) x(i) = x(i) + y(i) end subroutine declare_simd_linear ! CHECK-LABEL: func.func @_QPdeclare_simd_linear( ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK: omp.declare_simd linear(ref(%[[I]]#0 : !fir.ref = %[[C1]] : i32)) {linear_var_types = [i32]}{{$}} ! CHECK: return subroutine declare_simd_simdlen(x, y, n, i) #ifdef OMP_60 !$omp declare_simd simdlen(8) #else !$omp declare simd simdlen(8) #endif end subroutine declare_simd_simdlen ! CHECK-LABEL: func.func @_QPdeclare_simd_simdlen( ! CHECK: %[[SCOPE_S:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: omp.declare_simd{{.*}}simdlen(8){{$}} ! CHECK-NEXT: return subroutine declare_simd_uniform(x, y, n, i) #ifdef OMP_60 !$omp declare_simd uniform(x, y) #else !$omp declare simd uniform(x, y) #endif real(8), pointer, intent(inout) :: x(:) real(8), pointer, intent(in) :: y(:) integer, intent(in) :: n, i if (i <= n) then x(i) = x(i) + y(i) end if end subroutine declare_simd_uniform ! CHECK-LABEL: func.func @_QPdeclare_simd_uniform( ! CHECK-SAME: fir.bindc_name = "x" ! CHECK-SAME: fir.bindc_name = "y" ! CHECK-SAME: fir.bindc_name = "n" ! CHECK-SAME: fir.bindc_name = "i" ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[IDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 ! CHECK: %[[NDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3 ! CHECK: %[[XDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 ! CHECK: %[[YDECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 ! CHECK: omp.declare_simd uniform(%[[XDECL]]#0 : !fir.ref>>>, %[[YDECL]]#0 : !fir.ref>>>) ! CHECK: return subroutine declare_simd_inbranch() #ifdef OMP_60 !$omp declare_simd inbranch #else !$omp declare simd inbranch #endif end subroutine declare_simd_inbranch ! CHECK-LABEL: func.func @_QPdeclare_simd_inbranch() ! CHECK: omp.declare_simd inbranch{{$}} ! CHECK: return subroutine declare_simd_notinbranch() #ifdef OMP_60 !$omp declare_simd notinbranch #else !$omp declare simd notinbranch #endif end subroutine declare_simd_notinbranch ! CHECK-LABEL: func.func @_QPdeclare_simd_notinbranch() ! CHECK: omp.declare_simd notinbranch{{$}} ! CHECK: return subroutine declare_simd_combined(x, y, n, i) #ifdef OMP_60 !$omp declare_simd inbranch aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y) #else !$omp declare simd inbranch aligned(x, y : 64) linear(i) simdlen(8) uniform(x, y) #endif real(8), pointer, intent(inout) :: x(:) real(8), pointer, intent(in) :: y(:) integer, intent(in) :: n, i if (i <= n) then x(i) = x(i) + y(i) end if end subroutine declare_simd_combined ! CHECK-LABEL: func.func @_QPdeclare_simd_combined( ! CHECK-SAME: %{{.*}}: !fir.ref>>>{{.*}}fir.bindc_name = "x" ! CHECK-SAME: %{{.*}}: !fir.ref>>>{{.*}}fir.bindc_name = "y" ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}fir.bindc_name = "n" ! CHECK-SAME: %{{.*}}: !fir.ref{{.*}}fir.bindc_name = "i" ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[N_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 3 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 {{.*}} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK: omp.declare_simd ! CHECK-SAME: aligned(%[[X_DECL]]#0 : !fir.ref>>> -> 64 : i64, ! CHECK-SAME: %[[Y_DECL]]#0 : !fir.ref>>> -> 64 : i64) ! CHECK-SAME: inbranch ! CHECK-SAME: linear(ref(%[[I_DECL]]#0 : !fir.ref = %[[C1]] : i32)) ! CHECK-SAME: simdlen(8) ! CHECK-SAME: uniform(%[[X_DECL]]#0 : !fir.ref>>>, ! CHECK-SAME: %[[Y_DECL]]#0 : !fir.ref>>>) ! CHECK-SAME: {linear_var_types = [i32]}{{$}} ! CHECK: return subroutine declare_simd_linear_val(a, b) #ifdef OMP_60 !$omp declare_simd linear(a : val, step(2)) linear(b : val) #else !$omp declare simd linear(a : val, step(2)) linear(b : val) #endif integer, intent(in) :: a, b end subroutine declare_simd_linear_val ! CHECK-LABEL: func.func @_QPdeclare_simd_linear_val( ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[A:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[B:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 2 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK: omp.declare_simd linear(val(%[[A]]#0 : !fir.ref = %[[C2]] : i32), val(%[[B]]#0 : !fir.ref = %[[C1]] : i32)) ! CHECK-SAME: {linear_var_types = [i32, i32]}{{$}} ! CHECK: return subroutine declare_simd_linear_ref(x) #ifdef OMP_60 !$omp declare_simd linear(x : ref, step(4)) #else !$omp declare simd linear(x : ref, step(4)) #endif integer, allocatable, intent(inout) :: x end subroutine declare_simd_linear_ref ! CHECK-LABEL: func.func @_QPdeclare_simd_linear_ref( ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[X:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref>>, !fir.dscope) -> (!fir.ref>>, !fir.ref>>) ! CHECK: %[[C4:.*]] = arith.constant 4 : i32 ! CHECK: omp.declare_simd linear(ref(%[[X]]#0 : !fir.ref>> = %[[C4]] : i32)) ! CHECK-SAME: {linear_var_types = [!fir.box>]}{{$}} ! CHECK: return subroutine declare_simd_linear_uval(y) #ifdef OMP_60 !$omp declare_simd linear(y : uval) #else !$omp declare simd linear(y : uval) #endif integer, intent(in) :: y end subroutine declare_simd_linear_uval ! CHECK-LABEL: func.func @_QPdeclare_simd_linear_uval( ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope ! CHECK: %[[Y:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 1 {{.*}} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 ! CHECK: omp.declare_simd linear(uval(%[[Y]]#0 : !fir.ref = %[[C1]] : i32)) ! CHECK-SAME: {linear_var_types = [i32]}{{$}} ! CHECK: return