1! This test checks the lowering of OpenMP sections construct with several clauses present
2
3! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s
4
5!CHECK: func @_QQmain() {
6!CHECK:   %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32>
7!CHECK:   %[[DOUBLE_COUNT:.*]] = fir.address_of(@_QFEdouble_count) : !fir.ref<i32>
8!CHECK:   %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"}
9!CHECK:   %[[CONST_1:.*]] = arith.constant 1 : i32
10!CHECK:   omp.sections allocate(%[[CONST_1]] : i32 -> %0 : !fir.ref<i32>)  {
11!CHECK:     omp.section {
12!CHECK:       {{.*}} = arith.constant 5 : i32
13!CHECK:       fir.store {{.*}} to {{.*}} : !fir.ref<i32>
14!CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
15!CHECK:       {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
16!CHECK:       {{.*}} = arith.muli {{.*}}, {{.*}} : i32
17!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
18!CHECK:       fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
19!CHECK:       omp.terminator
20!CHECK:     }
21!CHECK:     omp.section {
22!CHECK:       {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
23!CHECK:       {{.*}} = arith.constant 1 : i32
24!CHECK:       {{.*}} = arith.addi {{.*}} : i32
25!CHECK:       fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
26!CHECK:       omp.terminator
27!CHECK:     }
28!CHECK:     omp.section {
29!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
30!CHECK:       {{.*}} = arith.constant 7.000000e+00 : f32
31!CHECK:       {{.*}} = arith.subf {{.*}} : f32
32!CHECK:       fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
33!CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
34!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
35!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
36!CHECK:       {{.*}} = arith.mulf {{.*}}, {{.*}} : f32
37!CHECK:       {{.*}} = fir.convert {{.*}} : (f32) -> i32
38!CHECK:       fir.store {{.*}} to %[[COUNT]] : !fir.ref<i32>
39!CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
40!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
41!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
42!CHECK:       {{.*}} = arith.subf {{.*}}, {{.*}} : f32
43!CHECK:       {{.*}} = fir.convert {{.*}} : (f32) -> i32
44!CHECK:       fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
45!CHECK:       omp.terminator
46!CHECK:     }
47!CHECK:     omp.terminator
48!CHECK:   }
49!CHECK:   omp.sections nowait {
50!CHECK:     omp.terminator
51!CHECK:   }
52!CHECK:   return
53!CHECK: }
54
55program sample
56    use omp_lib
57    integer :: count = 0, double_count = 1
58    !$omp sections private (eta, double_count) allocate(omp_high_bw_mem_alloc: count)
59        !$omp section
60            count = 1 + 4
61            eta = count * double_count
62        !$omp section
63            double_count = double_count + 1
64        !$omp section
65            eta = eta - 7
66            count = count * eta
67            double_count = count - eta
68    !$omp end sections
69
70    !$omp sections
71    !$omp end sections nowait
72end program sample
73
74!CHECK: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "alpha"}) {
75!CHECK:   omp.sections {
76!CHECK:     omp.section  {
77!CHECK:       omp.terminator
78!CHECK:     }
79!CHECK:     omp.terminator
80!CHECK:   }
81!CHECK:   omp.sections {
82!CHECK:     omp.section  {
83!CHECK:       %[[PRIVATE_VAR:.*]] = fir.load %[[ARG]] : !fir.ref<f32>
84!CHECK:       %[[CONSTANT:.*]] = arith.constant 5.000000e+00 : f32
85!CHECK:       %[[PRIVATE_VAR_2:.*]] = arith.mulf %[[PRIVATE_VAR]], %[[CONSTANT]] : f32
86!CHECK:       fir.store %[[PRIVATE_VAR_2]] to %[[ARG]] : !fir.ref<f32>
87!CHECK:       omp.terminator
88!CHECK:     }
89!CHECK:     omp.terminator
90!CHECK:   }
91!CHECK:   return
92!CHECK: }
93
94subroutine firstprivate(alpha)
95    real :: alpha
96    !$omp sections firstprivate(alpha)
97    !$omp end sections
98
99    !$omp sections
100        alpha = alpha * 5
101    !$omp end sections
102end subroutine
103