1! Test unstructured code adjacent to and inside OpenMP constructs. 2 3! RUN: bbc %s -fopenmp -emit-hlfir -o "-" \ 4! RUN: | FileCheck %s 5 6! CHECK-LABEL: func @_QPss1{{.*}} { 7! CHECK: br ^bb1 8! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4 9! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5 10! CHECK: ^bb2: // pred: ^bb1 11! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4 12! CHECK: ^bb4: // pred: ^bb2 13! CHECK: fir.call @_FortranAioBeginExternalListOutput 14! CHECK: br ^bb1 15! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3 16! CHECK: omp.master { 17! CHECK: @_FortranAioBeginExternalListOutput 18! CHECK: omp.terminator 19! CHECK: } 20! CHECK: @_FortranAioBeginExternalListOutput 21! CHECK: } 22subroutine ss1(n) ! unstructured code followed by a structured OpenMP construct 23 do i = 1, 3 24 if (i .eq. n) exit 25 print*, 'ss1-A', i 26 enddo 27 !$omp master 28 print*, 'ss1-B', i 29 !$omp end master 30 print* 31end 32 33! CHECK-LABEL: func @_QPss2{{.*}} { 34! CHECK: omp.master { 35! CHECK: @_FortranAioBeginExternalListOutput 36! CHECK: br ^bb1 37! CHECK: ^bb1: // 2 preds: ^bb0, ^bb4 38! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb5 39! CHECK: ^bb2: // pred: ^bb1 40! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb4 41! CHECK: ^bb3: // pred: ^bb2 42! CHECK: @_FortranAioBeginExternalListOutput 43! CHECK: br ^bb1 44! CHECK: ^bb5: // 2 preds: ^bb1, ^bb3 45! CHECK: omp.terminator 46! CHECK: } 47! CHECK: @_FortranAioBeginExternalListOutput 48! CHECK: @_FortranAioBeginExternalListOutput 49! CHECK: } 50subroutine ss2(n) ! unstructured OpenMP construct; loop exit inside construct 51 !$omp master 52 print*, 'ss2-A', n 53 do i = 1, 3 54 if (i .eq. n) exit 55 print*, 'ss2-B', i 56 enddo 57 !$omp end master 58 print*, 'ss2-C', i 59 print* 60end 61 62! CHECK-LABEL: func @_QPss3{{.*}} { 63! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) { 64! CHECK: %[[ALLOCA_K:.*]] = fir.alloca i32 {bindc_name = "k", pinned} 65! CHECK: %[[K_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_K]] {uniq_name = "_QFss3Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 66 67! CHECK: br ^bb1 68! CHECK: ^bb1: // 2 preds: ^bb0, ^bb3 69! CHECK: cond_br %{{[0-9]*}}, ^bb2, ^bb4 70! CHECK: ^bb2: // pred: ^bb1 71 72! CHECK: %[[ALLOCA_2:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}} 73! CHECK: %[[OMP_LOOP_K_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_2]] {uniq_name = "_QFss3Ek"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 74! CHECK: omp.wsloop { 75! CHECK: omp.loop_nest (%[[ARG1:.*]]) : {{.*}} { 76! CHECK: fir.store %[[ARG1]] to %[[OMP_LOOP_K_DECL]]#1 : !fir.ref<i32> 77! CHECK: @_FortranAioBeginExternalListOutput 78! CHECK: %[[LOAD_1:.*]] = fir.load %[[OMP_LOOP_K_DECL]]#0 : !fir.ref<i32> 79! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_1]]) 80! CHECK: omp.yield 81! CHECK: } 82! CHECK: } 83 84! CHECK: %[[ALLOCA_1:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}} 85! CHECK: %[[OMP_LOOP_J_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_1]] {uniq_name = "_QFss3Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 86 87! CHECK: omp.wsloop { 88! CHECK: omp.loop_nest (%[[ARG2:.*]]) : {{.*}} { 89! CHECK: fir.store %[[ARG2]] to %[[OMP_LOOP_J_DECL]]#1 : !fir.ref<i32> 90! CHECK: br ^bb1 91! CHECK: ^bb2: // 2 preds: ^bb1, ^bb5 92! CHECK: cond_br %{{[0-9]*}}, ^bb3, ^bb6 93! CHECK: ^bb3: // pred: ^bb2 94! CHECK: cond_br %{{[0-9]*}}, ^bb4, ^bb5 95! CHECK: ^bb4: // pred: ^bb3 96! CHECK: @_FortranAioBeginExternalListOutput 97! CHECK: %[[LOAD_2:.*]] = fir.load %[[K_DECL]]#0 : !fir.ref<i32> 98! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD_2]]) 99! CHECK: br ^bb2 100! CHECK: ^bb6: // 2 preds: ^bb2, ^bb4 101! CHECK: omp.yield 102! CHECK: } 103! CHECK: } 104! CHECK: br ^bb1 105! CHECK: ^bb4: // pred: ^bb1 106! CHECK: omp.terminator 107! CHECK: } 108! CHECK: } 109subroutine ss3(n) ! nested unstructured OpenMP constructs 110 !$omp parallel 111 do i = 1, 3 112 !$omp do 113 do k = 1, 3 114 print*, 'ss3-A', k 115 enddo 116 !$omp end do 117 !$omp do 118 do j = 1, 3 119 do k = 1, 3 120 if (k .eq. n) exit 121 print*, 'ss3-B', k 122 enddo 123 enddo 124 !$omp end do 125 enddo 126 !$omp end parallel 127end 128 129! CHECK-LABEL: func @_QPss4{{.*}} { 130! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) { 131! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 {{{.*}}, pinned, uniq_name = "_QFss4Ej"} 132! CHECK: %[[OMP_LOOP_J_DECL:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "_QFss4Ej"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 133! CHECK: omp.wsloop { 134! CHECK-NEXT: omp.loop_nest (%[[ARG:.*]]) : {{.*}} { 135! CHECK: fir.store %[[ARG]] to %[[OMP_LOOP_J_DECL]]#1 : !fir.ref<i32> 136! CHECK: %[[COND:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}} 137! CHECK: %[[COND_XOR:.*]] = arith.xori %[[COND]], %{{.*}} 138! CHECK: fir.if %[[COND_XOR]] { 139! CHECK: @_FortranAioBeginExternalListOutput 140! CHECK: %[[LOAD:.*]] = fir.load %[[OMP_LOOP_J_DECL]]#0 : !fir.ref<i32> 141! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD]]) 142! CHECK: } 143! CHECK-NEXT: omp.yield 144! CHECK-NEXT: } 145! CHECK-NEXT: } 146! CHECK: omp.terminator 147! CHECK-NEXT: } 148subroutine ss4(n) ! CYCLE in OpenMP wsloop constructs 149 !$omp parallel 150 do i = 1, 3 151 !$omp do 152 do j = 1, 3 153 if (j .eq. n) cycle 154 print*, 'ss4', j 155 enddo 156 !$omp end do 157 enddo 158 !$omp end parallel 159end 160 161! CHECK-LABEL: func @_QPss5() { 162! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) { 163! CHECK: omp.wsloop { 164! CHECK: omp.loop_nest {{.*}} { 165! CHECK: br ^[[BB1:.*]] 166! CHECK: ^[[BB1]]: 167! CHECK: br ^[[BB2:.*]] 168! CHECK: ^[[BB2]]: 169! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]] 170! CHECK: ^[[BB3]]: 171! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB3:.*]] 172! CHECK: ^[[BB4]]: 173! CHECK: br ^[[BB6]] 174! CHECK: ^[[BB3]]: 175! CHECK: br ^[[BB2]] 176! CHECK: ^[[BB6]]: 177! CHECK: omp.yield 178! CHECK: } 179! CHECK: } 180! CHECK: omp.terminator 181! CHECK: } 182subroutine ss5() ! EXIT inside OpenMP wsloop (inside parallel) 183 integer :: x 184 !$omp parallel private(x) 185 !$omp do 186 do j = 1, 3 187 x = j * i 188 do k = 1, 3 189 if (k .eq. n) exit 190 x = k 191 x = x + k 192 enddo 193 x = j - 222 194 enddo 195 !$omp end do 196 !$omp end parallel 197end 198 199! CHECK-LABEL: func @_QPss6() { 200! CHECK: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) { 201! CHECK: br ^[[BB1_OUTER:.*]] 202! CHECK: ^[[BB1_OUTER]]: 203! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]] 204! CHECK: ^[[BB2_OUTER]]: 205! CHECK: omp.wsloop { 206! CHECK: omp.loop_nest {{.*}} { 207! CHECK: br ^[[BB1:.*]] 208! CHECK: ^[[BB1]]: 209! CHECK: br ^[[BB2:.*]] 210! CHECK: ^[[BB2]]: 211! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]] 212! CHECK: ^[[BB3]]: 213! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]] 214! CHECK: ^[[BB4]]: 215! CHECK: br ^[[BB6]] 216! CHECK: ^[[BB5]] 217! CHECK: br ^[[BB2]] 218! CHECK: ^[[BB6]]: 219! CHECK: omp.yield 220! CHECK: } 221! CHECK: } 222! CHECK: br ^[[BB1_OUTER]] 223! CHECK: ^[[BB3_OUTER]]: 224! CHECK: omp.terminator 225! CHECK: } 226subroutine ss6() ! EXIT inside OpenMP wsloop in a do loop (inside parallel) 227 integer :: x 228 !$omp parallel private(x) 229 do i = 1, 3 230 !$omp do 231 do j = 1, 3 232 x = j * i 233 do k = 1, 3 234 if (k .eq. n) exit 235 x = k 236 x = x + k 237 enddo 238 x = j - 222 239 enddo 240 !$omp end do 241 enddo 242 !$omp end parallel 243end 244 245! CHECK-LABEL: func @_QPss7() { 246! CHECK: br ^[[BB1_OUTER:.*]] 247! CHECK: ^[[BB1_OUTER]]: 248! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]] 249! CHECK-NEXT: ^[[BB2_OUTER:.*]]: 250! CHECK: omp.parallel { 251! CHECK: omp.wsloop { 252! CHECK: omp.loop_nest {{.*}} { 253! CHECK: br ^[[BB1:.*]] 254! CHECK-NEXT: ^[[BB1]]: 255! CHECK: br ^[[BB2:.*]] 256! CHECK-NEXT: ^[[BB2]]: 257! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]] 258! CHECK-NEXT: ^[[BB3]]: 259! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]] 260! CHECK-NEXT: ^[[BB4]]: 261! CHECK: br ^[[BB6]] 262! CHECK-NEXT: ^[[BB5]]: 263! CHECK: br ^[[BB2]] 264! CHECK-NEXT: ^[[BB6]]: 265! CHECK: omp.yield 266! CHECK: } 267! CHECK: } 268! CHECK: omp.terminator 269! CHECK: } 270! CHECK: br ^[[BB1_OUTER]] 271! CHECK-NEXT: ^[[BB3_OUTER]]: 272! CHECK-NEXT: return 273subroutine ss7() ! EXIT inside OpenMP parallel do (inside do loop) 274 integer :: x 275 do i = 1, 3 276 !$omp parallel do private(x) 277 do j = 1, 3 278 x = j * i 279 do k = 1, 3 280 if (k .eq. n) exit 281 x = k 282 x = x + k 283 enddo 284 enddo 285 !$omp end parallel do 286 enddo 287end 288 289! CHECK-LABEL: func @_QPss8() { 290! CHECK: omp.parallel { 291! CHECK: omp.wsloop { 292! CHECK: omp.loop_nest {{.*}} { 293! CHECK: br ^[[BB1:.*]] 294! CHECK-NEXT: ^[[BB1]]: 295! CHECK: br ^[[BB2:.*]] 296! CHECK: ^[[BB2]]: 297! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB6:.*]] 298! CHECK: ^[[BB3]]: 299! CHECK: cond_br %{{.*}}, ^[[BB4:.*]], ^[[BB5:.*]] 300! CHECK: ^[[BB4]]: 301! CHECK-NEXT: br ^[[BB6]] 302! CHECK: ^[[BB5]]: 303! CHECK: br ^[[BB2]] 304! CHECK-NEXT: ^[[BB6]]: 305! CHECK: omp.yield 306! CHECK: } 307! CHECK: } 308! CHECK: omp.terminator 309! CHECK: } 310subroutine ss8() ! EXIT inside OpenMP parallel do 311 integer :: x 312 !$omp parallel do private(x) 313 do j = 1, 3 314 x = j * i 315 do k = 1, 3 316 if (k .eq. n) exit 317 x = k 318 x = x + k 319 enddo 320 enddo 321 !$omp end parallel do 322end 323 324! CHECK-LABEL: func @_QPss9() { 325! CHECK: omp.parallel { 326! CHECK-NEXT: omp.parallel private(@{{.*}} %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) { 327! CHECK: br ^[[BB1:.*]] 328! CHECK: ^[[BB1]]: 329! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB5:.*]] 330! CHECK-NEXT: ^[[BB2]]: 331! CHECK: cond_br %{{.*}}, ^[[BB3:.*]], ^[[BB4:.*]] 332! CHECK-NEXT: ^[[BB3]]: 333! CHECK-NEXT: br ^[[BB5]] 334! CHECK-NEXT: ^[[BB4]]: 335! CHECK: br ^[[BB1]] 336! CHECK-NEXT: ^[[BB5]]: 337! CHECK: omp.terminator 338! CHECK-NEXT: } 339! CHECK: omp.terminator 340! CHECK-NEXT } 341! CHECK: } 342subroutine ss9() ! EXIT inside OpenMP parallel (inside parallel) 343 integer :: x 344 !$omp parallel 345 !$omp parallel private(x) 346 do k = 1, 3 347 if (k .eq. n) exit 348 x = k 349 x = x + k 350 end do 351 !$omp end parallel 352 !$omp end parallel 353end 354 355! CHECK-LABEL: func @_QQmain 356program p 357 call ss1(2) 358 call ss2(2) 359 call ss3(2) 360 call ss4(2) 361 call ss5() 362 call ss6() 363 call ss7() 364 call ss8() 365 call ss9() 366end 367