3370 lines · plain
1// RUN: mlir-opt %s | mlir-opt | FileCheck %s2 3func.func @omp_barrier() -> () {4 // CHECK: omp.barrier5 omp.barrier6 return7}8 9func.func @omp_master() -> () {10 // CHECK: omp.master11 omp.master {12 // CHECK: omp.terminator13 omp.terminator14 }15 16 return17}18 19// CHECK-LABEL: omp_masked20func.func @omp_masked(%filtered_thread_id : i32) -> () {21 // CHECK: omp.masked filter(%{{.*}} : i32)22 "omp.masked" (%filtered_thread_id) ({23 omp.terminator24 }) : (i32) -> ()25 26 // CHECK: omp.masked27 "omp.masked" () ({28 omp.terminator29 }) : () -> ()30 return31}32 33func.func @omp_taskwait() -> () {34 // CHECK: omp.taskwait35 omp.taskwait36 return37}38 39func.func @omp_taskyield() -> () {40 // CHECK: omp.taskyield41 omp.taskyield42 return43}44 45// CHECK-LABEL: func @omp_flush46// CHECK-SAME: ([[ARG0:%.*]]: memref<i32>) {47func.func @omp_flush(%arg0 : memref<i32>) -> () {48 // Test without data var49 // CHECK: omp.flush50 omp.flush51 52 // Test with one data var53 // CHECK: omp.flush([[ARG0]] : memref<i32>)54 omp.flush(%arg0 : memref<i32>)55 56 // Test with two data var57 // CHECK: omp.flush([[ARG0]], [[ARG0]] : memref<i32>, memref<i32>)58 omp.flush(%arg0, %arg0: memref<i32>, memref<i32>)59 60 return61}62 63func.func @omp_terminator() -> () {64 // CHECK: omp.terminator65 omp.terminator66}67 68func.func @omp_parallel(%data_var : memref<i32>, %if_cond : i1, %num_threads : i32, %idx : index) -> () {69 // CHECK: omp.parallel allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>) if(%{{.*}}) num_threads(%{{.*}} : i32)70 "omp.parallel" (%data_var, %data_var, %if_cond, %num_threads) ({71 72 // test without if condition73 // CHECK: omp.parallel allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>) num_threads(%{{.*}} : i32)74 "omp.parallel"(%data_var, %data_var, %num_threads) ({75 omp.terminator76 }) {operandSegmentSizes = array<i32: 1,1,0,1,0,0>} : (memref<i32>, memref<i32>, i32) -> ()77 78 // CHECK: omp.barrier79 omp.barrier80 81 // test without num_threads82 // CHECK: omp.parallel allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>) if(%{{.*}})83 "omp.parallel"(%data_var, %data_var, %if_cond) ({84 omp.terminator85 }) {operandSegmentSizes = array<i32: 1,1,1,0,0,0>} : (memref<i32>, memref<i32>, i1) -> ()86 87 // test without allocate88 // CHECK: omp.parallel if(%{{.*}}) num_threads(%{{.*}} : i32)89 "omp.parallel"(%if_cond, %num_threads) ({90 omp.terminator91 }) {operandSegmentSizes = array<i32: 0,0,1,1,0,0>} : (i1, i32) -> ()92 93 omp.terminator94 }) {operandSegmentSizes = array<i32: 1,1,1,1,0,0>, proc_bind_kind = #omp<procbindkind spread>} : (memref<i32>, memref<i32>, i1, i32) -> ()95 96 // test with multiple parameters for single variadic argument97 // CHECK: omp.parallel allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>)98 "omp.parallel" (%data_var, %data_var) ({99 omp.terminator100 }) {operandSegmentSizes = array<i32: 1,1,0,0,0,0>} : (memref<i32>, memref<i32>) -> ()101 102 // CHECK: omp.parallel103 omp.parallel {104 // CHECK-NOT: omp.terminator105 // CHECK: omp.distribute106 omp.distribute {107 // CHECK-NEXT: omp.wsloop108 omp.wsloop {109 // CHECK-NEXT: omp.loop_nest110 omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {111 omp.yield112 }113 } {omp.composite}114 } {omp.composite}115 omp.terminator116 } {omp.composite}117 118 // CHECK: omp.parallel119 omp.parallel {120 // CHECK-NOT: omp.terminator121 // CHECK: omp.distribute122 omp.distribute {123 // CHECK-NEXT: omp.wsloop124 omp.wsloop {125 // CHECK-NEXT: omp.simd126 omp.simd {127 // CHECK-NEXT: omp.loop_nest128 omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {129 omp.yield130 }131 } {omp.composite}132 } {omp.composite}133 } {omp.composite}134 omp.terminator135 } {omp.composite}136 137 return138}139 140func.func @omp_parallel_pretty(%data_var : memref<i32>, %if_cond : i1, %num_threads : i32, %allocator : si32) -> () {141 // CHECK: omp.parallel142 omp.parallel {143 omp.terminator144 }145 146 // CHECK: omp.parallel num_threads(%{{.*}} : i32)147 omp.parallel num_threads(%num_threads : i32) {148 omp.terminator149 }150 151 %n_index = arith.constant 2 : index152 // CHECK: omp.parallel num_threads(%{{.*}} : index)153 omp.parallel num_threads(%n_index : index) {154 omp.terminator155 }156 157 %n_i64 = arith.constant 4 : i64158 // CHECK: omp.parallel num_threads(%{{.*}} : i64)159 omp.parallel num_threads(%n_i64 : i64) {160 omp.terminator161 }162 163 // CHECK: omp.parallel allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>)164 omp.parallel allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {165 omp.terminator166 }167 168 // CHECK: omp.parallel169 // CHECK-NEXT: omp.parallel if(%{{.*}})170 omp.parallel {171 omp.parallel if(%if_cond) {172 omp.terminator173 }174 omp.terminator175 }176 177 // CHECK: omp.parallel if(%{{.*}}) num_threads(%{{.*}} : i32) proc_bind(close)178 omp.parallel num_threads(%num_threads : i32) if(%if_cond) proc_bind(close) {179 omp.terminator180 }181 182 return183}184 185// CHECK-LABEL: omp_loop_nest186func.func @omp_loop_nest(%lb : index, %ub : index, %step : index) -> () {187 omp.wsloop {188 // CHECK: omp.loop_nest189 // CHECK-SAME: (%{{.*}}) : index =190 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) step (%{{.*}})191 "omp.loop_nest" (%lb, %ub, %step) ({192 ^bb0(%iv: index):193 omp.yield194 }) : (index, index, index) -> ()195 }196 197 omp.wsloop {198 // CHECK: omp.loop_nest199 // CHECK-SAME: (%{{.*}}) : index =200 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}})201 "omp.loop_nest" (%lb, %ub, %step) ({202 ^bb0(%iv: index):203 omp.yield204 }) {loop_inclusive} : (index, index, index) -> ()205 }206 207 omp.wsloop {208 // CHECK: omp.loop_nest209 // CHECK-SAME: (%{{.*}}, %{{.*}}) : index =210 // CHECK-SAME: (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}})211 "omp.loop_nest" (%lb, %lb, %ub, %ub, %step, %step) ({212 ^bb0(%iv: index, %iv3: index):213 omp.yield214 }) : (index, index, index, index, index, index) -> ()215 }216 217 omp.wsloop {218 // CHECK: omp.loop_nest219 // CHECK-SAME: (%{{.*}}) : index =220 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) step (%{{.*}})221 "omp.loop_nest" (%lb, %ub, %step) ({222 ^bb0(%iv: index):223 // CHECK: test.op1224 "test.op1"(%lb) : (index) -> ()225 // CHECK: test.op2226 "test.op2"() : () -> ()227 // CHECK: omp.yield228 omp.yield229 }) : (index, index, index) -> ()230 }231 232 return233}234 235// CHECK-LABEL: omp_loop_nest_pretty236func.func @omp_loop_nest_pretty(%lb : index, %ub : index, %step : index) -> () {237 omp.wsloop {238 // CHECK: omp.loop_nest239 // CHECK-SAME: (%{{.*}}) : index =240 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) step (%{{.*}})241 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {242 omp.yield243 }244 }245 246 omp.wsloop {247 // CHECK: omp.loop_nest248 // CHECK-SAME: (%{{.*}}) : index =249 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}})250 omp.loop_nest (%iv) : index = (%lb) to (%ub) inclusive step (%step) {251 omp.yield252 }253 }254 255 omp.wsloop {256 // CHECK: omp.loop_nest257 // CHECK-SAME: (%{{.*}}) : index =258 // CHECK-SAME: (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}})259 omp.loop_nest (%iv1, %iv2) : index = (%lb, %lb) to (%ub, %ub) step (%step, %step) {260 omp.yield261 }262 }263 264 omp.wsloop {265 // CHECK: omp.loop_nest266 // CHECK-SAME: (%{{.*}}) : index =267 // CHECK-SAME: (%{{.*}}) to (%{{.*}}) step (%{{.*}})268 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {269 // CHECK: test.op1270 "test.op1"(%lb) : (index) -> ()271 // CHECK: test.op2272 "test.op2"() : () -> ()273 // CHECK: omp.yield274 omp.yield275 }276 }277 278 return279}280 281// CHECK-LABEL: omp_loop_nest_pretty_multi_block282func.func @omp_loop_nest_pretty_multi_block(%lb : index, %ub : index,283 %step : index, %data1 : memref<?xi32>, %data2 : memref<?xi32>) -> () {284 285 omp.wsloop {286 // CHECK: omp.loop_nest (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}})287 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {288 %1 = "test.payload"(%iv) : (index) -> (i32)289 cf.br ^bb1(%1: i32)290 ^bb1(%arg: i32):291 memref.store %arg, %data1[%iv] : memref<?xi32>292 omp.yield293 }294 }295 296 omp.wsloop {297 // CHECK: omp.loop_nest (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}})298 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {299 %c = "test.condition"(%iv) : (index) -> (i1)300 %v1 = "test.payload"(%iv) : (index) -> (i32)301 cf.cond_br %c, ^bb1(%v1: i32), ^bb2(%v1: i32)302 ^bb1(%arg0: i32):303 memref.store %arg0, %data1[%iv] : memref<?xi32>304 cf.br ^bb3305 ^bb2(%arg1: i32):306 memref.store %arg1, %data2[%iv] : memref<?xi32>307 cf.br ^bb3308 ^bb3:309 omp.yield310 }311 }312 313 omp.wsloop {314 // CHECK: omp.loop_nest (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}})315 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {316 %c = "test.condition"(%iv) : (index) -> (i1)317 %v1 = "test.payload"(%iv) : (index) -> (i32)318 cf.cond_br %c, ^bb1(%v1: i32), ^bb2(%v1: i32)319 ^bb1(%arg0: i32):320 memref.store %arg0, %data1[%iv] : memref<?xi32>321 omp.yield322 ^bb2(%arg1: i32):323 memref.store %arg1, %data2[%iv] : memref<?xi32>324 omp.yield325 }326 }327 328 return329}330 331// CHECK-LABEL: omp_loop_nest_pretty_non_index332func.func @omp_loop_nest_pretty_non_index(%lb1 : i32, %ub1 : i32, %step1 : i32,333 %lb2 : i64, %ub2 : i64, %step2 : i64, %data1 : memref<?xi32>,334 %data2 : memref<?xi64>) -> () {335 336 omp.wsloop {337 // CHECK: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) step (%{{.*}})338 omp.loop_nest (%iv1) : i32 = (%lb1) to (%ub1) step (%step1) {339 %1 = "test.payload"(%iv1) : (i32) -> (index)340 cf.br ^bb1(%1: index)341 ^bb1(%arg1: index):342 memref.store %iv1, %data1[%arg1] : memref<?xi32>343 omp.yield344 }345 }346 347 omp.wsloop {348 // CHECK: omp.loop_nest (%{{.*}}) : i64 = (%{{.*}}) to (%{{.*}}) step (%{{.*}})349 omp.loop_nest (%iv) : i64 = (%lb2) to (%ub2) step (%step2) {350 %2 = "test.payload"(%iv) : (i64) -> (index)351 cf.br ^bb1(%2: index)352 ^bb1(%arg2: index):353 memref.store %iv, %data2[%arg2] : memref<?xi64>354 omp.yield355 }356 }357 358 return359}360 361// CHECK-LABEL: omp_loop_nest_pretty_multiple362func.func @omp_loop_nest_pretty_multiple(%lb1 : i32, %ub1 : i32, %step1 : i32,363 %lb2 : i32, %ub2 : i32, %step2 : i32, %data1 : memref<?xi32>) -> () {364 365 omp.wsloop {366 // CHECK: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}})367 omp.loop_nest (%iv1, %iv2) : i32 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) {368 %1 = "test.payload"(%iv1) : (i32) -> (index)369 %2 = "test.payload"(%iv2) : (i32) -> (index)370 memref.store %iv1, %data1[%1] : memref<?xi32>371 memref.store %iv2, %data1[%2] : memref<?xi32>372 omp.yield373 }374 }375 376 return377}378 379// CHECK-LABEL: omp_loop_nest_pretty_multiple_collapse380func.func @omp_loop_nest_pretty_multiple_collapse(%lb1 : i32, %ub1 : i32, %step1 : i32,381 %lb2 : i32, %ub2 : i32, %step2 : i32, %data1 : memref<?xi32>) -> () {382 383 omp.wsloop {384 // CHECK: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}}) collapse(2)385 omp.loop_nest (%iv1, %iv2) : i32 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) collapse(2) {386 %1 = "test.payload"(%iv1) : (i32) -> (index)387 %2 = "test.payload"(%iv2) : (i32) -> (index)388 memref.store %iv1, %data1[%1] : memref<?xi32>389 memref.store %iv2, %data1[%2] : memref<?xi32>390 omp.yield391 }392 }393 394 return395}396 397// CHECK-LABEL: omp_loop_nest_pretty_multiple_tiles398func.func @omp_loop_nest_pretty_multiple_tiles(%lb1 : i32, %ub1 : i32, %step1 : i32,399 %lb2 : i32, %ub2 : i32, %step2 : i32, %data1 : memref<?xi32>) -> () {400 401 omp.wsloop {402 // CHECK: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}}) tiles(5, 10)403 omp.loop_nest (%iv1, %iv2) : i32 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) tiles(5, 10) {404 %1 = "test.payload"(%iv1) : (i32) -> (index)405 %2 = "test.payload"(%iv2) : (i32) -> (index)406 memref.store %iv1, %data1[%1] : memref<?xi32>407 memref.store %iv2, %data1[%2] : memref<?xi32>408 omp.yield409 }410 }411 412 return413}414 415// CHECK-LABEL: omp_loop_nest_pretty_multiple_collapse_tiles416func.func @omp_loop_nest_pretty_multiple_collapse_tiles(%lb1 : i32, %ub1 : i32, %step1 : i32,417 %lb2 : i32, %ub2 : i32, %step2 : i32, %data1 : memref<?xi32>) -> () {418 419 omp.wsloop {420 // CHECK: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 = (%{{.*}}, %{{.*}}) to (%{{.*}}, %{{.*}}) step (%{{.*}}, %{{.*}}) collapse(2) tiles(5, 10)421 omp.loop_nest (%iv1, %iv2) : i32 = (%lb1, %lb2) to (%ub1, %ub2) step (%step1, %step2) collapse(2) tiles(5, 10) {422 %1 = "test.payload"(%iv1) : (i32) -> (index)423 %2 = "test.payload"(%iv2) : (i32) -> (index)424 memref.store %iv1, %data1[%1] : memref<?xi32>425 memref.store %iv2, %data1[%2] : memref<?xi32>426 omp.yield427 }428 }429 430 return431}432 433// CHECK-LABEL: omp_wsloop434func.func @omp_wsloop(%lb : index, %ub : index, %step : index, %data_var : memref<i32>, %linear_var : i32, %chunk_var : i32) -> () {435 436 // CHECK: omp.wsloop ordered(1) {437 // CHECK-NEXT: omp.loop_nest438 "omp.wsloop" () ({439 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {440 omp.yield441 }442 }) {operandSegmentSizes = array<i32: 0,0,0,0,0,0,0>, ordered = 1} :443 () -> ()444 445 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) schedule(static) {446 // CHECK-NEXT: omp.loop_nest447 "omp.wsloop" (%data_var, %linear_var) ({448 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {449 omp.yield450 }451 }) {operandSegmentSizes = array<i32: 0,0,1,1,0,0,0>, schedule_kind = #omp<schedulekind static>} :452 (memref<i32>, i32) -> ()453 454 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>, %{{.*}} = %{{.*}} : memref<i32>) schedule(static) {455 // CHECK-NEXT: omp.loop_nest456 "omp.wsloop" (%data_var, %data_var, %linear_var, %linear_var) ({457 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {458 omp.yield459 }460 }) {operandSegmentSizes = array<i32: 0,0,2,2,0,0,0>, schedule_kind = #omp<schedulekind static>} :461 (memref<i32>, memref<i32>, i32, i32) -> ()462 463 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}}) {464 // CHECK-NEXT: omp.loop_nest465 "omp.wsloop" (%data_var, %linear_var, %chunk_var) ({466 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {467 omp.yield468 }469 }) {operandSegmentSizes = array<i32: 0,0,1,1,0,0,1>, schedule_kind = #omp<schedulekind dynamic>, ordered = 2} :470 (memref<i32>, i32, i32) -> ()471 472 // CHECK: omp.wsloop nowait schedule(auto) {473 // CHECK-NEXT: omp.loop_nest474 "omp.wsloop" () ({475 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {476 omp.yield477 }478 }) {operandSegmentSizes = array<i32: 0,0,0,0,0,0,0>, nowait, schedule_kind = #omp<schedulekind auto>} :479 () -> ()480 481 // CHECK: omp.wsloop {482 // CHECK-NEXT: omp.simd483 // CHECK-NEXT: omp.loop_nest484 "omp.wsloop" () ({485 omp.simd {486 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {487 omp.yield488 }489 } {omp.composite}490 }) {omp.composite} : () -> ()491 492 return493}494 495// CHECK-LABEL: omp_wsloop_pretty496func.func @omp_wsloop_pretty(%lb : index, %ub : index, %step : index, %data_var : memref<i32>, %linear_var : i32, %chunk_var : i32, %chunk_var2 : i16) -> () {497 498 // CHECK: omp.wsloop ordered(2) {499 // CHECK-NEXT: omp.loop_nest500 omp.wsloop ordered(2) {501 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {502 omp.yield503 }504 }505 506 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) schedule(static) {507 // CHECK-NEXT: omp.loop_nest508 omp.wsloop schedule(static) linear(%data_var = %linear_var : memref<i32>) {509 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {510 omp.yield511 }512 }513 514 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(static = %{{.*}} : i32) {515 // CHECK-NEXT: omp.loop_nest516 omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(static = %chunk_var : i32) {517 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {518 omp.yield519 }520 }521 522 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}} : i32, nonmonotonic) {523 // CHECK-NEXT: omp.loop_nest524 omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(dynamic = %chunk_var : i32, nonmonotonic) {525 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {526 omp.yield527 }528 }529 530 // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}} : i16, monotonic) {531 // CHECK-NEXT: omp.loop_nest532 omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(dynamic = %chunk_var2 : i16, monotonic) {533 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {534 omp.yield535 }536 }537 538 // CHECK: omp.wsloop {539 // CHECK-NEXT: omp.loop_nest540 omp.wsloop {541 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {542 omp.yield543 }544 }545 546 // CHECK: omp.wsloop nowait {547 // CHECK-NEXT: omp.loop_nest548 omp.wsloop nowait {549 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {550 omp.yield551 }552 }553 554 // CHECK: omp.wsloop nowait order(concurrent) {555 // CHECK-NEXT: omp.loop_nest556 omp.wsloop order(concurrent) nowait {557 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {558 omp.yield559 }560 }561 562 // CHECK: omp.wsloop nowait order(reproducible:concurrent) {563 // CHECK-NEXT: omp.loop_nest564 omp.wsloop order(reproducible:concurrent) nowait {565 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {566 omp.yield567 }568 }569 // CHECK: omp.wsloop nowait order(unconstrained:concurrent) {570 // CHECK-NEXT: omp.loop_nest571 omp.wsloop order(unconstrained:concurrent) nowait {572 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {573 omp.yield574 }575 }576 // CHECK: omp.wsloop {577 // CHECK-NEXT: omp.simd578 // CHECK-NEXT: omp.loop_nest579 omp.wsloop {580 omp.simd {581 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {582 omp.yield583 }584 } {omp.composite}585 } {omp.composite}586 587 return588}589 590// CHECK-LABEL: omp_simd591func.func @omp_simd(%lb : index, %ub : index, %step : index) -> () {592 // CHECK: omp.simd593 omp.simd {594 "omp.loop_nest" (%lb, %ub, %step) ({595 ^bb1(%iv2: index):596 "omp.yield"() : () -> ()597 }) : (index, index, index) -> ()598 }599 600 return601}602 603// CHECK-LABEL: omp_simd_aligned_list604func.func @omp_simd_aligned_list(%arg0 : index, %arg1 : index, %arg2 : index,605 %arg3 : memref<i32>, %arg4 : memref<i32>) -> () {606 // CHECK: omp.simd aligned(607 // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,608 // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)609 "omp.simd"(%arg3, %arg4) ({610 "omp.loop_nest" (%arg0, %arg1, %arg2) ({611 ^bb1(%iv2: index):612 "omp.yield"() : () -> ()613 }) : (index, index, index) -> ()614 }) {alignments = [32, 128],615 operandSegmentSizes = array<i32: 2, 0, 0, 0, 0, 0, 0>} : (memref<i32>, memref<i32>) -> ()616 return617}618 619// CHECK-LABEL: omp_simd_aligned_single620func.func @omp_simd_aligned_single(%arg0 : index, %arg1 : index, %arg2 : index,621 %arg3 : memref<i32>, %arg4 : memref<i32>) -> () {622 // CHECK: omp.simd aligned(%{{.*}} : memref<i32> -> 32 : i64)623 "omp.simd"(%arg3) ({624 "omp.loop_nest" (%arg0, %arg1, %arg2) ({625 ^bb1(%iv2: index):626 "omp.yield"() : () -> ()627 }) : (index, index, index) -> ()628 }) {alignments = [32],629 operandSegmentSizes = array<i32: 1, 0, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()630 return631}632 633// CHECK-LABEL: omp_simd_nontemporal_list634func.func @omp_simd_nontemporal_list(%arg0 : index, %arg1 : index,635 %arg2 : index, %arg3 : memref<i32>,636 %arg4 : memref<i64>) -> () {637 // CHECK: omp.simd nontemporal(%{{.*}}, %{{.*}} : memref<i32>, memref<i64>)638 "omp.simd"(%arg3, %arg4) ({639 "omp.loop_nest" (%arg0, %arg1, %arg2) ({640 ^bb1(%iv2: index):641 "omp.yield"() : () -> ()642 }) : (index, index, index) -> ()643 }) {operandSegmentSizes = array<i32: 0, 0, 0, 0, 2, 0, 0>} : (memref<i32>, memref<i64>) -> ()644 return645}646 647// CHECK-LABEL: omp_simd_nontemporal_single648func.func @omp_simd_nontemporal_single(%arg0 : index, %arg1 : index,649 %arg2 : index, %arg3 : memref<i32>,650 %arg4 : memref<i64>) -> () {651 // CHECK: omp.simd nontemporal(%{{.*}} : memref<i32>)652 "omp.simd"(%arg3) ({653 "omp.loop_nest" (%arg0, %arg1, %arg2) ({654 ^bb1(%iv2: index):655 "omp.yield"() : () -> ()656 }) : (index, index, index) -> ()657 }) {operandSegmentSizes = array<i32: 0, 0, 0, 0, 1, 0, 0>} : (memref<i32>) -> ()658 return659}660 661// CHECK-LABEL: omp_simd_pretty662func.func @omp_simd_pretty(%lb : index, %ub : index, %step : index) -> () {663 // CHECK: omp.simd {664 omp.simd {665 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {666 omp.yield667 }668 }669 return670}671 672// CHECK-LABEL: func.func @omp_simd_pretty_aligned(673func.func @omp_simd_pretty_aligned(%lb : index, %ub : index, %step : index,674 %data_var : memref<i32>,675 %data_var1 : memref<i32>) -> () {676 // CHECK: omp.simd aligned(677 // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,678 // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)679 omp.simd aligned(%data_var : memref<i32> -> 32, %data_var1 : memref<i32> -> 128) {680 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {681 omp.yield682 }683 }684 return685}686 687// CHECK-LABEL: omp_simd_pretty_if688func.func @omp_simd_pretty_if(%lb : index, %ub : index, %step : index, %if_cond : i1) -> () {689 // CHECK: omp.simd if(%{{.*}})690 omp.simd if(%if_cond) {691 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {692 omp.yield693 }694 }695 return696}697 698// CHECK-LABEL: func.func @omp_simd_pretty_nontemporal699func.func @omp_simd_pretty_nontemporal(%lb : index, %ub : index, %step : index,700 %data_var : memref<i32>,701 %data_var1 : memref<i32>) -> () {702 // CHECK: omp.simd nontemporal(%{{.*}}, %{{.*}} : memref<i32>, memref<i32>)703 omp.simd nontemporal(%data_var, %data_var1 : memref<i32>, memref<i32>) {704 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {705 omp.yield706 }707 }708 return709}710 711// CHECK-LABEL: omp_simd_pretty_order712func.func @omp_simd_pretty_order(%lb : index, %ub : index, %step : index) -> () {713 // CHECK: omp.simd order(concurrent)714 omp.simd order(concurrent) {715 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {716 omp.yield717 }718 }719 // CHECK: omp.simd order(reproducible:concurrent)720 omp.simd order(reproducible:concurrent) {721 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {722 omp.yield723 }724 }725 // CHECK: omp.simd order(unconstrained:concurrent)726 omp.simd order(unconstrained:concurrent) {727 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {728 omp.yield729 }730 }731 return732}733 734// CHECK-LABEL: omp_simd_pretty_simdlen735func.func @omp_simd_pretty_simdlen(%lb : index, %ub : index, %step : index) -> () {736 // CHECK: omp.simd simdlen(2)737 omp.simd simdlen(2) {738 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {739 omp.yield740 }741 }742 return743}744 745// CHECK-LABEL: omp_simd_pretty_safelen746func.func @omp_simd_pretty_safelen(%lb : index, %ub : index, %step : index) -> () {747 // CHECK: omp.simd safelen(2)748 omp.simd safelen(2) {749 omp.loop_nest (%iv): index = (%lb) to (%ub) step (%step) {750 omp.yield751 }752 }753 return754}755 756// CHECK-LABEL: omp_distribute757func.func @omp_distribute(%chunk_size : i32, %data_var : memref<i32>, %arg0 : i32) -> () {758 // CHECK: omp.distribute759 "omp.distribute" () ({760 "omp.loop_nest" (%arg0, %arg0, %arg0) ({761 ^bb0(%iv: i32):762 "omp.yield"() : () -> ()763 }) : (i32, i32, i32) -> ()764 }) {} : () -> ()765 // CHECK: omp.distribute766 omp.distribute {767 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {768 omp.yield769 }770 }771 // CHECK: omp.distribute dist_schedule_static772 omp.distribute dist_schedule_static {773 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {774 omp.yield775 }776 }777 // CHECK: omp.distribute dist_schedule_static dist_schedule_chunk_size(%{{.+}} : i32)778 omp.distribute dist_schedule_static dist_schedule_chunk_size(%chunk_size : i32) {779 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {780 omp.yield781 }782 }783 // CHECK: omp.distribute order(concurrent)784 omp.distribute order(concurrent) {785 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {786 omp.yield787 }788 }789 // CHECK: omp.distribute order(reproducible:concurrent)790 omp.distribute order(reproducible:concurrent) {791 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {792 omp.yield793 }794 }795 // CHECK: omp.distribute order(unconstrained:concurrent)796 omp.distribute order(unconstrained:concurrent) {797 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {798 omp.yield799 }800 }801 // CHECK: omp.distribute allocate(%{{.+}} : memref<i32> -> %{{.+}} : memref<i32>)802 omp.distribute allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {803 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {804 omp.yield805 }806 }807 // CHECK: omp.distribute808 omp.distribute {809 omp.simd {810 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {811 omp.yield812 }813 } {omp.composite}814 } {omp.composite}815 return816}817 818// CHECK-LABEL: omp_target819func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %device_ptr: memref<i32>, %device_addr: memref<?xi32>, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () {820 821 // Test with optional operands; if_expr, device, thread_limit, private, firstprivate and nowait.822 // CHECK: omp.target device({{.*}}) if({{.*}}) nowait thread_limit({{.*}})823 "omp.target"(%device, %if_cond, %num_threads) ({824 // CHECK: omp.terminator825 omp.terminator826 }) {nowait, operandSegmentSizes = array<i32: 0,0,0,1,0,0,1,0,0,0,0,1>} : ( si32, i1, i32 ) -> ()827 828 // Test with optional map clause.829 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""}830 // CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}831 // CHECK: %[[MAP_C:.*]] = omp.map.info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}832 // CHECK: omp.target is_device_ptr(%[[VAL_4:.*]] : memref<i32>) has_device_addr(%[[MAP_A]] -> {{.*}} : memref<?xi32>) map_entries(%[[MAP_B]] -> {{.*}}, %[[MAP_C]] -> {{.*}} : memref<?xi32>, memref<?xi32>) {833 %mapv0 = omp.map.info var_ptr(%device_addr : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""}834 %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}835 %mapv2 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}836 omp.target is_device_ptr(%device_ptr : memref<i32>) has_device_addr(%mapv0 -> %arg0 : memref<?xi32>) map_entries(%mapv1 -> %arg1, %mapv2 -> %arg2 : memref<?xi32>, memref<?xi32>) {837 omp.terminator838 }839 // CHECK: %[[MAP_D:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""}840 // CHECK: %[[MAP_E:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""}841 // CHECK: omp.target map_entries(%[[MAP_D]] -> {{.*}}, %[[MAP_E]] -> {{.*}} : memref<?xi32>, memref<?xi32>) {842 %mapv3 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""}843 %mapv4 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""}844 omp.target map_entries(%mapv3 -> %arg0, %mapv4 -> %arg1 : memref<?xi32>, memref<?xi32>) {845 omp.terminator846 }847 // CHECK: omp.barrier848 omp.barrier849 850 return851}852 853func.func @omp_target_data (%if_cond : i1, %device : si32, %device_ptr: memref<i32>, %device_addr: memref<?xi32>, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () {854 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""}855 // CHECK: omp.target_data device(%[[VAL_1:.*]] : si32) if(%[[VAL_0:.*]]) map_entries(%[[MAP_A]] : memref<?xi32>)856 %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(always, from) capture(ByRef) -> memref<?xi32> {name = ""}857 omp.target_data if(%if_cond) device(%device : si32) map_entries(%mapv1 : memref<?xi32>){}858 859 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%{{.*}} : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""}860 // CHECK: %[[DEV_ADDR:.*]] = omp.map.info var_ptr(%{{.*}} : memref<?xi32>, tensor<?xi32>) map_clauses(return_param) capture(ByRef) -> memref<?xi32> {name = ""}861 // CHECK: %[[DEV_PTR:.*]] = omp.map.info var_ptr(%{{.*}} : memref<i32>, tensor<i32>) map_clauses(return_param) capture(ByRef) -> memref<i32> {name = ""}862 // CHECK: omp.target_data map_entries(%[[MAP_A]] : memref<?xi32>) use_device_addr(%[[DEV_ADDR]] -> %{{.*}} : memref<?xi32>) use_device_ptr(%[[DEV_PTR]] -> %{{.*}} : memref<i32>)863 %mapv2 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(close, present, to) capture(ByRef) -> memref<?xi32> {name = ""}864 %device_addrv1 = omp.map.info var_ptr(%device_addr : memref<?xi32>, tensor<?xi32>) map_clauses(return_param) capture(ByRef) -> memref<?xi32> {name = ""}865 %device_ptrv1 = omp.map.info var_ptr(%device_ptr : memref<i32>, tensor<i32>) map_clauses(return_param) capture(ByRef) -> memref<i32> {name = ""}866 omp.target_data map_entries(%mapv2 : memref<?xi32>) use_device_addr(%device_addrv1 -> %arg0 : memref<?xi32>) use_device_ptr(%device_ptrv1 -> %arg1 : memref<i32>) {867 omp.terminator868 }869 870 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}871 // CHECK: %[[MAP_B:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}872 // CHECK: omp.target_data map_entries(%[[MAP_A]], %[[MAP_B]] : memref<?xi32>, memref<?xi32>)873 %mapv3 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}874 %mapv4 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}875 omp.target_data map_entries(%mapv3, %mapv4 : memref<?xi32>, memref<?xi32>) {}876 877 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}878 // CHECK: omp.target_enter_data device(%[[VAL_1:.*]] : si32) if(%[[VAL_0:.*]]) map_entries(%[[MAP_A]] : memref<?xi32>) nowait879 %mapv5 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}880 omp.target_enter_data if(%if_cond) device(%device : si32) nowait map_entries(%mapv5 : memref<?xi32>)881 882 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_3:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}883 // CHECK: omp.target_exit_data device(%[[VAL_1:.*]] : si32) if(%[[VAL_0:.*]]) map_entries(%[[MAP_A]] : memref<?xi32>) nowait884 %mapv6 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}885 omp.target_exit_data if(%if_cond) device(%device : si32) nowait map_entries(%mapv6 : memref<?xi32>)886 887 // CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_2:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(ompx_hold, to) capture(ByRef) -> memref<?xi32> {name = ""}888 // CHECK: omp.target_data map_entries(%[[MAP_A]] : memref<?xi32>)889 %mapv7 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(ompx_hold, to) capture(ByRef) -> memref<?xi32> {name = ""}890 omp.target_data map_entries(%mapv7 : memref<?xi32>) {891 omp.terminator892 }893 return894}895 896// CHECK-LABEL: omp_target_pretty897func.func @omp_target_pretty(%if_cond : i1, %device : si32, %num_threads : i32) -> () {898 // CHECK: omp.target device({{.*}}) if({{.*}})899 omp.target if(%if_cond) device(%device : si32) {900 omp.terminator901 }902 903 // CHECK: omp.target device({{.*}}) if({{.*}}) nowait904 omp.target if(%if_cond) device(%device : si32) thread_limit(%num_threads : i32) nowait {905 omp.terminator906 }907 908 return909}910 911// CHECK: omp.declare_reduction912// CHECK-LABEL: @add_f32913// CHECK: : f32914// CHECK: init915// CHECK: ^{{.+}}(%{{.+}}: f32):916// CHECK: omp.yield917// CHECK: combiner918// CHECK: ^{{.+}}(%{{.+}}: f32, %{{.+}}: f32):919// CHECK: omp.yield920// CHECK: atomic921// CHECK: ^{{.+}}(%{{.+}}: !llvm.ptr, %{{.+}}: !llvm.ptr):922// CHECK: omp.yield923// CHECK: cleanup924// CHECK: omp.yield925omp.declare_reduction @add_f32 : f32926init {927^bb0(%arg: f32):928 %0 = arith.constant 0.0 : f32929 omp.yield (%0 : f32)930}931combiner {932^bb1(%arg0: f32, %arg1: f32):933 %1 = arith.addf %arg0, %arg1 : f32934 omp.yield (%1 : f32)935}936atomic {937^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):938 %2 = llvm.load %arg3 : !llvm.ptr -> f32939 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32940 omp.yield941}942cleanup {943^bb0(%arg: f32):944 omp.yield945}946 947// CHECK: omp.declare_mapper @my_mapper : !llvm.struct<"my_type", (i32)>948omp.declare_mapper @my_mapper : !llvm.struct<"my_type", (i32)> {949^bb0(%arg: !llvm.ptr):950 // CHECK: %[[DECL_MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : !llvm.ptr, !llvm.struct<"my_type", (i32)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}951 %decl_map_info = omp.map.info var_ptr(%arg : !llvm.ptr, !llvm.struct<"my_type", (i32)>) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}952 // CHECK: omp.declare_mapper.info map_entries(%[[DECL_MAP_INFO]] : !llvm.ptr)953 omp.declare_mapper.info map_entries(%decl_map_info : !llvm.ptr)954}955 956// CHECK-LABEL: func @wsloop_reduction957func.func @wsloop_reduction(%lb : index, %ub : index, %step : index) {958 %c1 = arith.constant 1 : i32959 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr960 // CHECK: reduction(@add_f32 %{{.+}} -> %[[PRV:.+]] : !llvm.ptr)961 omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {962 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {963 // CHECK: %[[CST:.+]] = arith.constant 2.0{{.*}} : f32964 %cst = arith.constant 2.0 : f32965 // CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> f32966 %lprv = llvm.load %prv : !llvm.ptr -> f32967 // CHECK: %[[RES:.+]] = llvm.fadd %[[LPRV]], %[[CST]] : f32968 %res = llvm.fadd %lprv, %cst: f32969 // CHECK: llvm.store %[[RES]], %[[PRV]] : f32, !llvm.ptr970 llvm.store %res, %prv : f32, !llvm.ptr971 omp.yield972 }973 }974 return975}976 977// CHECK-LABEL: func @wsloop_inscan_reduction978func.func @wsloop_inscan_reduction(%lb : index, %ub : index, %step : index) {979 %c1 = arith.constant 1 : i32980 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr981 // CHECK: reduction(mod: inscan, @add_f32 %{{.+}} -> %[[PRV:.+]] : !llvm.ptr)982 omp.wsloop reduction(mod:inscan, @add_f32 %0 -> %prv : !llvm.ptr) {983 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {984 // CHECK: omp.scan inclusive(%{{.*}} : !llvm.ptr)985 omp.scan inclusive(%prv : !llvm.ptr)986 omp.yield987 }988 }989 // CHECK: reduction(mod: inscan, @add_f32 %{{.+}} -> %[[PRV:.+]] : !llvm.ptr)990 omp.wsloop reduction(mod:inscan, @add_f32 %0 -> %prv : !llvm.ptr) {991 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {992 // CHECK: omp.scan exclusive(%{{.*}} : !llvm.ptr)993 omp.scan exclusive(%prv : !llvm.ptr)994 omp.yield995 }996 }997 return998}999 1000// CHECK-LABEL: func @wsloop_reduction_byref1001func.func @wsloop_reduction_byref(%lb : index, %ub : index, %step : index) {1002 %c1 = arith.constant 1 : i321003 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1004 // CHECK: reduction(byref @add_f32 %{{.+}} -> %[[PRV:.+]] : !llvm.ptr)1005 omp.wsloop reduction(byref @add_f32 %0 -> %prv : !llvm.ptr) {1006 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {1007 // CHECK: %[[CST:.+]] = arith.constant 2.0{{.*}} : f321008 %cst = arith.constant 2.0 : f321009 // CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> f321010 %lprv = llvm.load %prv : !llvm.ptr -> f321011 // CHECK: %[[RES:.+]] = llvm.fadd %[[LPRV]], %[[CST]] : f321012 %res = llvm.fadd %lprv, %cst: f321013 // CHECK: llvm.store %[[RES]], %[[PRV]] : f32, !llvm.ptr1014 llvm.store %res, %prv : f32, !llvm.ptr1015 omp.yield1016 }1017 }1018 return1019}1020 1021// CHECK-LABEL: func @parallel_reduction1022func.func @parallel_reduction() {1023 %c1 = arith.constant 1 : i321024 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1025 // CHECK: omp.parallel reduction(@add_f32 {{.+}} -> {{.+}} : !llvm.ptr)1026 omp.parallel reduction(@add_f32 %0 -> %prv : !llvm.ptr) {1027 %1 = arith.constant 2.0 : f321028 %2 = llvm.load %prv : !llvm.ptr -> f321029 // CHECK: llvm.fadd %{{.*}}, %{{.*}} : f321030 %3 = llvm.fadd %1, %2 : f321031 llvm.store %3, %prv : f32, !llvm.ptr1032 omp.terminator1033 }1034 return1035}1036 1037// CHECK-LABEL: func @parallel_reduction_byref1038func.func @parallel_reduction_byref() {1039 %c1 = arith.constant 1 : i321040 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1041 // CHECK: omp.parallel reduction(byref @add_f32 {{.+}} -> {{.+}} : !llvm.ptr)1042 omp.parallel reduction(byref @add_f32 %0 -> %prv : !llvm.ptr) {1043 %1 = arith.constant 2.0 : f321044 %2 = llvm.load %prv : !llvm.ptr -> f321045 // CHECK: llvm.fadd %{{.*}}, %{{.*}} : f321046 %3 = llvm.fadd %1, %2 : f321047 llvm.store %3, %prv : f32, !llvm.ptr1048 omp.terminator1049 }1050 return1051}1052 1053// CHECK: func @parallel_wsloop_reduction1054func.func @parallel_wsloop_reduction(%lb : index, %ub : index, %step : index) {1055 %c1 = arith.constant 1 : i321056 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1057 // CHECK: omp.parallel {1058 omp.parallel {1059 // CHECK: omp.wsloop reduction(@add_f32 %{{.*}} -> %{{.+}} : !llvm.ptr) {1060 omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {1061 // CHECK: omp.loop_nest (%{{.+}}) : index = (%{{.+}}) to (%{{.+}}) step (%{{.+}}) {1062 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {1063 %1 = arith.constant 2.0 : f321064 %2 = llvm.load %prv : !llvm.ptr -> f321065 // CHECK: llvm.fadd %{{.+}}, %{{.+}} : f321066 llvm.fadd %1, %2 : f321067 // CHECK: omp.yield1068 omp.yield1069 }1070 }1071 // CHECK: omp.terminator1072 omp.terminator1073 }1074 return1075}1076 1077// CHECK-LABEL: omp_teams1078func.func @omp_teams(%lb : i32, %ub : i32, %if_cond : i1, %num_threads : i32,1079 %data_var : memref<i32>) -> () {1080 // Test nesting inside of omp.target1081 omp.target {1082 // CHECK: omp.teams1083 omp.teams {1084 // CHECK: omp.terminator1085 omp.terminator1086 }1087 // CHECK: omp.terminator1088 omp.terminator1089 }1090 1091 // CHECK: omp.teams1092 omp.teams {1093 %0 = arith.constant 1 : i321094 // CHECK: omp.terminator1095 omp.terminator1096 }1097 1098 // Test num teams.1099 // CHECK: omp.teams num_teams(%{{.+}} : i32 to %{{.+}} : i32)1100 omp.teams num_teams(%lb : i32 to %ub : i32) {1101 // CHECK: omp.terminator1102 omp.terminator1103 }1104 1105 // CHECK: omp.teams num_teams( to %{{.+}} : i32)1106 omp.teams num_teams(to %ub : i32) {1107 // CHECK: omp.terminator1108 omp.terminator1109 }1110 1111 // Test if.1112 // CHECK: omp.teams if(%{{.+}})1113 omp.teams if(%if_cond) {1114 // CHECK: omp.terminator1115 omp.terminator1116 }1117 1118 // Test thread limit.1119 // CHECK: omp.teams thread_limit(%{{.+}} : i32)1120 omp.teams thread_limit(%num_threads : i32) {1121 // CHECK: omp.terminator1122 omp.terminator1123 }1124 1125 // Test reduction.1126 %c1 = arith.constant 1 : i321127 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1128 // CHECK: omp.teams reduction(@add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr) {1129 omp.teams reduction(@add_f32 %0 -> %arg0 : !llvm.ptr) {1130 %1 = arith.constant 2.0 : f321131 // CHECK: omp.terminator1132 omp.terminator1133 }1134 1135 // Test reduction byref1136 // CHECK: omp.teams reduction(byref @add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr) {1137 omp.teams reduction(byref @add_f32 %0 -> %arg0 : !llvm.ptr) {1138 %1 = arith.constant 2.0 : f321139 // CHECK: omp.terminator1140 omp.terminator1141 }1142 1143 // Test allocate.1144 // CHECK: omp.teams allocate(%{{.+}} : memref<i32> -> %{{.+}} : memref<i32>)1145 omp.teams allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {1146 // CHECK: omp.terminator1147 omp.terminator1148 }1149 1150 return1151}1152 1153// CHECK-LABEL: func @sections_reduction1154func.func @sections_reduction() {1155 %c1 = arith.constant 1 : i321156 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1157 // CHECK: omp.sections reduction(@add_f32 %{{.+}} -> {{.+}} : !llvm.ptr)1158 omp.sections reduction(@add_f32 %0 -> %arg0 : !llvm.ptr) {1159 // CHECK: omp.section1160 omp.section {1161 ^bb0(%arg1 : !llvm.ptr):1162 %1 = arith.constant 2.0 : f321163 omp.terminator1164 }1165 // CHECK: omp.section1166 omp.section {1167 ^bb0(%arg1 : !llvm.ptr):1168 %1 = arith.constant 3.0 : f321169 omp.terminator1170 }1171 omp.terminator1172 }1173 return1174}1175 1176// CHECK-LABEL: func @sections_reduction_byref1177func.func @sections_reduction_byref() {1178 %c1 = arith.constant 1 : i321179 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1180 // CHECK: omp.sections reduction(byref @add_f32 %{{.+}} -> {{.+}} : !llvm.ptr)1181 omp.sections reduction(byref @add_f32 %0 -> %arg0 : !llvm.ptr) {1182 // CHECK: omp.section1183 omp.section {1184 ^bb0(%arg1 : !llvm.ptr):1185 %1 = arith.constant 2.0 : f321186 omp.terminator1187 }1188 // CHECK: omp.section1189 omp.section {1190 ^bb0(%arg1 : !llvm.ptr):1191 %1 = arith.constant 3.0 : f321192 omp.terminator1193 }1194 omp.terminator1195 }1196 return1197}1198 1199// CHECK: omp.declare_reduction1200// CHECK-LABEL: @add2_f321201omp.declare_reduction @add2_f32 : f321202// CHECK: init1203init {1204^bb0(%arg: f32):1205 %0 = arith.constant 0.0 : f321206 omp.yield (%0 : f32)1207}1208// CHECK: combiner1209combiner {1210^bb1(%arg0: f32, %arg1: f32):1211 %1 = arith.addf %arg0, %arg1 : f321212 omp.yield (%1 : f32)1213}1214// CHECK-NOT: atomic1215// CHECK-NOT: cleanup1216 1217// CHECK-LABEL: func @wsloop_reduction21218func.func @wsloop_reduction2(%lb : index, %ub : index, %step : index) {1219 %0 = memref.alloca() : memref<1xf32>1220 // CHECK: omp.wsloop reduction(@add2_f32 %{{.+}} -> %{{.+}} : memref<1xf32>) {1221 omp.wsloop reduction(@add2_f32 %0 -> %prv : memref<1xf32>) {1222 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {1223 %1 = arith.constant 2.0 : f321224 %2 = arith.constant 0 : index1225 %3 = memref.load %prv[%2] : memref<1xf32>1226 // CHECK: llvm.fadd1227 %4 = llvm.fadd %1, %3 : f321228 memref.store %4, %prv[%2] : memref<1xf32>1229 omp.yield1230 }1231 }1232 return1233}1234 1235// CHECK-LABEL: func @parallel_reduction21236func.func @parallel_reduction2() {1237 %0 = memref.alloca() : memref<1xf32>1238 // CHECK: omp.parallel reduction(@add2_f32 %{{.+}} -> %{{.+}} : memref<1xf32>)1239 omp.parallel reduction(@add2_f32 %0 -> %prv : memref<1xf32>) {1240 %1 = arith.constant 2.0 : f321241 %2 = arith.constant 0 : index1242 %3 = memref.load %prv[%2] : memref<1xf32>1243 // CHECK: llvm.fadd1244 %4 = llvm.fadd %1, %3 : f321245 memref.store %4, %prv[%2] : memref<1xf32>1246 omp.terminator1247 }1248 return1249}1250 1251// CHECK: func @parallel_wsloop_reduction21252func.func @parallel_wsloop_reduction2(%lb : index, %ub : index, %step : index) {1253 %c1 = arith.constant 1 : i321254 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr1255 // CHECK: omp.parallel {1256 omp.parallel {1257 // CHECK: omp.wsloop reduction(@add2_f32 %{{.*}} -> %{{.+}} : !llvm.ptr) {1258 omp.wsloop reduction(@add2_f32 %0 -> %prv : !llvm.ptr) {1259 // CHECK: omp.loop_nest (%{{.+}}) : index = (%{{.+}}) to (%{{.+}}) step (%{{.+}}) {1260 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {1261 %1 = arith.constant 2.0 : f321262 %2 = llvm.load %prv : !llvm.ptr -> f321263 // CHECK: llvm.fadd %{{.+}}, %{{.+}} : f321264 %3 = llvm.fadd %1, %2 : f321265 // CHECK: omp.yield1266 omp.yield1267 }1268 }1269 // CHECK: omp.terminator1270 omp.terminator1271 }1272 return1273}1274 1275// CHECK-LABEL: func @sections_reduction21276func.func @sections_reduction2() {1277 %0 = memref.alloca() : memref<1xf32>1278 // CHECK: omp.sections reduction(@add2_f32 %{{.+}} -> %{{.+}} : memref<1xf32>)1279 omp.sections reduction(@add2_f32 %0 -> %arg0 : memref<1xf32>) {1280 omp.section {1281 ^bb0(%arg1 : !llvm.ptr):1282 %1 = arith.constant 2.0 : f321283 omp.terminator1284 }1285 omp.section {1286 ^bb0(%arg1 : !llvm.ptr):1287 %1 = arith.constant 2.0 : f321288 omp.terminator1289 }1290 omp.terminator1291 }1292 return1293}1294 1295// CHECK: omp.critical.declare @mutex1 hint(uncontended)1296omp.critical.declare @mutex1 hint(uncontended)1297// CHECK: omp.critical.declare @mutex2 hint(contended)1298omp.critical.declare @mutex2 hint(contended)1299// CHECK: omp.critical.declare @mutex3 hint(nonspeculative)1300omp.critical.declare @mutex3 hint(nonspeculative)1301// CHECK: omp.critical.declare @mutex4 hint(speculative)1302omp.critical.declare @mutex4 hint(speculative)1303// CHECK: omp.critical.declare @mutex5 hint(uncontended, nonspeculative)1304omp.critical.declare @mutex5 hint(uncontended, nonspeculative)1305// CHECK: omp.critical.declare @mutex6 hint(contended, nonspeculative)1306omp.critical.declare @mutex6 hint(contended, nonspeculative)1307// CHECK: omp.critical.declare @mutex7 hint(uncontended, speculative)1308omp.critical.declare @mutex7 hint(uncontended, speculative)1309// CHECK: omp.critical.declare @mutex8 hint(contended, speculative)1310omp.critical.declare @mutex8 hint(contended, speculative)1311// CHECK: omp.critical.declare @mutex91312omp.critical.declare @mutex9 hint(none)1313// CHECK: omp.critical.declare @mutex101314omp.critical.declare @mutex101315 1316 1317// CHECK-LABEL: omp_critical1318func.func @omp_critical() -> () {1319 // CHECK: omp.critical1320 omp.critical {1321 omp.terminator1322 }1323 1324 // CHECK: omp.critical(@{{.*}})1325 omp.critical(@mutex1) {1326 omp.terminator1327 }1328 return1329}1330 1331func.func @omp_ordered(%arg1 : i32, %arg2 : i32, %arg3 : i32,1332 %vec0 : i64, %vec1 : i64, %vec2 : i64, %vec3 : i64) -> () {1333 // CHECK: omp.ordered.region1334 omp.ordered.region {1335 // CHECK: omp.terminator1336 omp.terminator1337 }1338 1339 omp.wsloop ordered(0) {1340 omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {1341 // CHECK: omp.ordered.region1342 omp.ordered.region {1343 // CHECK: omp.terminator1344 omp.terminator1345 }1346 omp.yield1347 }1348 }1349 1350 omp.wsloop ordered(1) {1351 omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {1352 // Only one DEPEND(SINK: vec) clause1353 // CHECK: omp.ordered depend_type(dependsink) depend_vec(%{{.*}} : i64) {doacross_num_loops = 1 : i64}1354 omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {doacross_num_loops = 1 : i64}1355 1356 // CHECK: omp.ordered depend_type(dependsource) depend_vec(%{{.*}} : i64) {doacross_num_loops = 1 : i64}1357 omp.ordered depend_type(dependsource) depend_vec(%vec0 : i64) {doacross_num_loops = 1 : i64}1358 1359 omp.yield1360 }1361 }1362 1363 omp.wsloop ordered(2) {1364 omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {1365 // Multiple DEPEND(SINK: vec) clauses1366 // CHECK: omp.ordered depend_type(dependsink) depend_vec(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : i64, i64, i64, i64) {doacross_num_loops = 2 : i64}1367 omp.ordered depend_type(dependsink) depend_vec(%vec0, %vec1, %vec2, %vec3 : i64, i64, i64, i64) {doacross_num_loops = 2 : i64}1368 1369 // CHECK: omp.ordered depend_type(dependsource) depend_vec(%{{.*}}, %{{.*}} : i64, i64) {doacross_num_loops = 2 : i64}1370 omp.ordered depend_type(dependsource) depend_vec(%vec0, %vec1 : i64, i64) {doacross_num_loops = 2 : i64}1371 1372 omp.yield1373 }1374 }1375 1376 return1377}1378 1379// CHECK-LABEL: omp_atomic_read1380// CHECK-SAME: (%[[v:.*]]: memref<i32>, %[[x:.*]]: memref<i32>)1381func.func @omp_atomic_read(%v: memref<i32>, %x: memref<i32>) {1382 // CHECK: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321383 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321384 // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) : memref<i32>, memref<i32>, i321385 omp.atomic.read %v = %x memory_order(seq_cst) : memref<i32>, memref<i32>, i321386 // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(acquire) : memref<i32>, memref<i32>, i321387 omp.atomic.read %v = %x memory_order(acquire) : memref<i32>, memref<i32>, i321388 // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(relaxed) : memref<i32>, memref<i32>, i321389 omp.atomic.read %v = %x memory_order(relaxed) : memref<i32>, memref<i32>, i321390 // CHECK: omp.atomic.read %[[v]] = %[[x]] hint(contended, nonspeculative) : memref<i32>, memref<i32>, i321391 omp.atomic.read %v = %x hint(nonspeculative, contended) : memref<i32>, memref<i32>, i321392 // CHECK: omp.atomic.read %[[v]] = %[[x]] hint(contended, speculative) memory_order(seq_cst) : memref<i32>, memref<i32>, i321393 omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref<i32>, memref<i32>, i321394 // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) : memref<i32>, memref<i32>, i321395 omp.atomic.read %v = %x hint(none) memory_order(seq_cst) : memref<i32>, memref<i32>, i321396 return1397}1398 1399// CHECK-LABEL: omp_atomic_write1400// CHECK-SAME: (%[[ADDR:.*]]: memref<i32>, %[[VAL:.*]]: i32)1401func.func @omp_atomic_write(%addr : memref<i32>, %val : i32) {1402 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] : memref<i32>, i321403 omp.atomic.write %addr = %val : memref<i32>, i321404 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] memory_order(seq_cst) : memref<i32>, i321405 omp.atomic.write %addr = %val memory_order(seq_cst) : memref<i32>, i321406 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] memory_order(release) : memref<i32>, i321407 omp.atomic.write %addr = %val memory_order(release) : memref<i32>, i321408 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] memory_order(relaxed) : memref<i32>, i321409 omp.atomic.write %addr = %val memory_order(relaxed) : memref<i32>, i321410 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(uncontended, speculative) : memref<i32>, i321411 omp.atomic.write %addr = %val hint(speculative, uncontended) : memref<i32>, i321412 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] : memref<i32>, i321413 omp.atomic.write %addr = %val hint(none) : memref<i32>, i321414 return1415}1416 1417// CHECK-LABEL: omp_atomic_update1418// CHECK-SAME: (%[[X:.*]]: memref<i32>, %[[EXPR:.*]]: i32, %[[XBOOL:.*]]: memref<i1>, %[[EXPRBOOL:.*]]: i1)1419func.func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>, %exprBool : i1) {1420 // CHECK: omp.atomic.update %[[X]] : memref<i32>1421 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1422 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321423 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1424 omp.atomic.update %x : memref<i32> {1425 ^bb0(%xval: i32):1426 %newval = llvm.add %xval, %expr : i321427 omp.yield(%newval : i32)1428 }1429 // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>1430 // CHECK-NEXT: (%[[XVAL:.*]]: i1):1431 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.and %[[XVAL]], %[[EXPRBOOL]] : i11432 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i1)1433 omp.atomic.update %xBool : memref<i1> {1434 ^bb0(%xval: i1):1435 %newval = llvm.and %xval, %exprBool : i11436 omp.yield(%newval : i1)1437 }1438 // CHECK: omp.atomic.update %[[X]] : memref<i32>1439 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1440 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.shl %[[XVAL]], %[[EXPR]] : i321441 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1442 // CHECK-NEXT: }1443 omp.atomic.update %x : memref<i32> {1444 ^bb0(%xval: i32):1445 %newval = llvm.shl %xval, %expr : i321446 omp.yield(%newval : i32)1447 }1448 // CHECK: omp.atomic.update %[[X]] : memref<i32>1449 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1450 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.intr.smax(%[[XVAL]], %[[EXPR]]) : (i32, i32) -> i321451 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1452 // CHECK-NEXT: }1453 omp.atomic.update %x : memref<i32> {1454 ^bb0(%xval: i32):1455 %newval = llvm.intr.smax(%xval, %expr) : (i32, i32) -> i321456 omp.yield(%newval : i32)1457 }1458 1459 // CHECK: omp.atomic.update %[[XBOOL]] : memref<i1>1460 // CHECK-NEXT: (%[[XVAL:.*]]: i1):1461 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.icmp "eq" %[[XVAL]], %[[EXPRBOOL]] : i11462 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i1)1463 // CHECK-NEXT: }1464 omp.atomic.update %xBool : memref<i1> {1465 ^bb0(%xval: i1):1466 %newval = llvm.icmp "eq" %xval, %exprBool : i11467 omp.yield(%newval : i1)1468 }1469 1470 // CHECK: omp.atomic.update %[[X]] : memref<i32> {1471 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1472 // CHECK-NEXT: omp.yield(%[[XVAL]] : i32)1473 // CHECK-NEXT: }1474 omp.atomic.update %x : memref<i32> {1475 ^bb0(%xval:i32):1476 omp.yield(%xval:i32)1477 }1478 1479 // CHECK: omp.atomic.update %[[X]] : memref<i32> {1480 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1481 // CHECK-NEXT: omp.yield(%{{.+}} : i32)1482 // CHECK-NEXT: }1483 %const = arith.constant 42 : i321484 omp.atomic.update %x : memref<i32> {1485 ^bb0(%xval:i32):1486 omp.yield(%const:i32)1487 }1488 1489 // CHECK: omp.atomic.update %[[X]] : memref<i32>1490 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1491 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321492 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1493 omp.atomic.update hint(none) %x : memref<i32> {1494 ^bb0(%xval: i32):1495 %newval = llvm.add %xval, %expr : i321496 omp.yield(%newval : i32)1497 }1498 1499 // CHECK: omp.atomic.update hint(uncontended) %[[X]] : memref<i32>1500 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1501 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321502 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1503 omp.atomic.update hint(uncontended) %x : memref<i32> {1504 ^bb0(%xval: i32):1505 %newval = llvm.add %xval, %expr : i321506 omp.yield(%newval : i32)1507 }1508 1509 // CHECK: omp.atomic.update hint(contended) %[[X]] : memref<i32>1510 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1511 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321512 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1513 omp.atomic.update hint(contended) %x : memref<i32> {1514 ^bb0(%xval: i32):1515 %newval = llvm.add %xval, %expr : i321516 omp.yield(%newval : i32)1517 }1518 1519 // CHECK: omp.atomic.update hint(nonspeculative) %[[X]] : memref<i32>1520 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1521 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321522 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1523 omp.atomic.update hint(nonspeculative) %x : memref<i32> {1524 ^bb0(%xval: i32):1525 %newval = llvm.add %xval, %expr : i321526 omp.yield(%newval : i32)1527 }1528 1529 // CHECK: omp.atomic.update hint(speculative) %[[X]] : memref<i32>1530 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1531 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321532 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1533 omp.atomic.update hint(speculative) %x : memref<i32> {1534 ^bb0(%xval: i32):1535 %newval = llvm.add %xval, %expr : i321536 omp.yield(%newval : i32)1537 }1538 1539 // CHECK: omp.atomic.update hint(uncontended, nonspeculative) %[[X]] : memref<i32>1540 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1541 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321542 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1543 omp.atomic.update hint(uncontended, nonspeculative) %x : memref<i32> {1544 ^bb0(%xval: i32):1545 %newval = llvm.add %xval, %expr : i321546 omp.yield(%newval : i32)1547 }1548 1549 // CHECK: omp.atomic.update hint(contended, nonspeculative) %[[X]] : memref<i32>1550 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1551 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321552 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1553 omp.atomic.update hint(contended, nonspeculative) %x : memref<i32> {1554 ^bb0(%xval: i32):1555 %newval = llvm.add %xval, %expr : i321556 omp.yield(%newval : i32)1557 }1558 1559 // CHECK: omp.atomic.update hint(uncontended, speculative) %[[X]] : memref<i32>1560 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1561 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321562 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1563 omp.atomic.update hint(uncontended, speculative) %x : memref<i32> {1564 ^bb0(%xval: i32):1565 %newval = llvm.add %xval, %expr : i321566 omp.yield(%newval : i32)1567 }1568 1569 // CHECK: omp.atomic.update hint(contended, speculative) %[[X]] : memref<i32>1570 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1571 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321572 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1573 omp.atomic.update hint(contended, speculative) %x : memref<i32> {1574 ^bb0(%xval: i32):1575 %newval = llvm.add %xval, %expr : i321576 omp.yield(%newval : i32)1577 }1578 1579 // CHECK: omp.atomic.update memory_order(seq_cst) %[[X]] : memref<i32>1580 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1581 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321582 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1583 omp.atomic.update memory_order(seq_cst) %x : memref<i32> {1584 ^bb0(%xval: i32):1585 %newval = llvm.add %xval, %expr : i321586 omp.yield(%newval : i32)1587 }1588 1589 // CHECK: omp.atomic.update memory_order(release) %[[X]] : memref<i32>1590 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1591 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321592 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1593 omp.atomic.update memory_order(release) %x : memref<i32> {1594 ^bb0(%xval: i32):1595 %newval = llvm.add %xval, %expr : i321596 omp.yield(%newval : i32)1597 }1598 1599 // CHECK: omp.atomic.update memory_order(relaxed) %[[X]] : memref<i32>1600 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1601 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321602 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1603 omp.atomic.update memory_order(relaxed) %x : memref<i32> {1604 ^bb0(%xval: i32):1605 %newval = llvm.add %xval, %expr : i321606 omp.yield(%newval : i32)1607 }1608 1609 // CHECK: omp.atomic.update hint(uncontended, speculative) memory_order(seq_cst) %[[X]] : memref<i32>1610 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1611 // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i321612 // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32)1613 omp.atomic.update memory_order(seq_cst) hint(uncontended, speculative) %x : memref<i32> {1614 ^bb0(%xval: i32):1615 %newval = llvm.add %xval, %expr : i321616 omp.yield(%newval : i32)1617 }1618 1619 // CHECK: omp.atomic.update %[[X]] : memref<i32> {1620 // CHECK-NEXT: (%[[XVAL:.*]]: i32):1621 // CHECK-NEXT: omp.yield(%{{.+}} : i32)1622 // CHECK-NEXT: } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true, fine_grained_memory = true, remote_memory = true>}1623 omp.atomic.update %x : memref<i32> {1624 ^bb0(%xval:i32):1625 omp.yield(%const:i32)1626 } {atomic_control = #omp.atomic_control<ignore_denormal_mode = true, fine_grained_memory = true, remote_memory = true>}1627 return1628}1629 1630// CHECK-LABEL: omp_atomic_capture1631// CHECK-SAME: (%[[v:.*]]: memref<i32>, %[[x:.*]]: memref<i32>, %[[expr:.*]]: i32)1632func.func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {1633 // CHECK: omp.atomic.capture {1634 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1635 // CHECK-NEXT: (%[[xval:.*]]: i32):1636 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321637 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1638 // CHECK-NEXT: }1639 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321640 // CHECK-NEXT: }1641 omp.atomic.capture{1642 omp.atomic.update %x : memref<i32> {1643 ^bb0(%xval: i32):1644 %newval = llvm.add %xval, %expr : i321645 omp.yield(%newval : i32)1646 }1647 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321648 }1649 // CHECK: omp.atomic.capture {1650 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321651 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1652 // CHECK-NEXT: (%[[xval:.*]]: i32):1653 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321654 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1655 // CHECK-NEXT: }1656 // CHECK-NEXT: }1657 omp.atomic.capture{1658 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321659 omp.atomic.update %x : memref<i32> {1660 ^bb0(%xval: i32):1661 %newval = llvm.add %xval, %expr : i321662 omp.yield(%newval : i32)1663 }1664 }1665 // CHECK: omp.atomic.capture {1666 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321667 // CHECK-NEXT: omp.atomic.write %[[x]] = %[[expr]] : memref<i32>, i321668 // CHECK-NEXT: }1669 omp.atomic.capture{1670 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321671 omp.atomic.write %x = %expr : memref<i32>, i321672 }1673 1674 // CHECK: omp.atomic.capture {1675 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1676 // CHECK-NEXT: (%[[xval:.*]]: i32):1677 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321678 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1679 // CHECK-NEXT: }1680 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321681 // CHECK-NEXT: }1682 omp.atomic.capture hint(none) {1683 omp.atomic.update %x : memref<i32> {1684 ^bb0(%xval: i32):1685 %newval = llvm.add %xval, %expr : i321686 omp.yield(%newval : i32)1687 }1688 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321689 }1690 1691 // CHECK: omp.atomic.capture hint(uncontended) {1692 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1693 // CHECK-NEXT: (%[[xval:.*]]: i32):1694 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321695 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1696 // CHECK-NEXT: }1697 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321698 // CHECK-NEXT: }1699 omp.atomic.capture hint(uncontended) {1700 omp.atomic.update %x : memref<i32> {1701 ^bb0(%xval: i32):1702 %newval = llvm.add %xval, %expr : i321703 omp.yield(%newval : i32)1704 }1705 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321706 }1707 1708 // CHECK: omp.atomic.capture hint(contended) {1709 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1710 // CHECK-NEXT: (%[[xval:.*]]: i32):1711 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321712 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1713 // CHECK-NEXT: }1714 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321715 // CHECK-NEXT: }1716 omp.atomic.capture hint(contended) {1717 omp.atomic.update %x : memref<i32> {1718 ^bb0(%xval: i32):1719 %newval = llvm.add %xval, %expr : i321720 omp.yield(%newval : i32)1721 }1722 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321723 }1724 1725 // CHECK: omp.atomic.capture hint(nonspeculative) {1726 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1727 // CHECK-NEXT: (%[[xval:.*]]: i32):1728 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321729 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1730 // CHECK-NEXT: }1731 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321732 // CHECK-NEXT: }1733 omp.atomic.capture hint(nonspeculative) {1734 omp.atomic.update %x : memref<i32> {1735 ^bb0(%xval: i32):1736 %newval = llvm.add %xval, %expr : i321737 omp.yield(%newval : i32)1738 }1739 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321740 }1741 1742 // CHECK: omp.atomic.capture hint(speculative) {1743 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1744 // CHECK-NEXT: (%[[xval:.*]]: i32):1745 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321746 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1747 // CHECK-NEXT: }1748 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321749 // CHECK-NEXT: }1750 omp.atomic.capture hint(speculative) {1751 omp.atomic.update %x : memref<i32> {1752 ^bb0(%xval: i32):1753 %newval = llvm.add %xval, %expr : i321754 omp.yield(%newval : i32)1755 }1756 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321757 }1758 1759 // CHECK: omp.atomic.capture hint(uncontended, nonspeculative) {1760 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1761 // CHECK-NEXT: (%[[xval:.*]]: i32):1762 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321763 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1764 // CHECK-NEXT: }1765 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321766 // CHECK-NEXT: }1767 omp.atomic.capture hint(uncontended, nonspeculative) {1768 omp.atomic.update %x : memref<i32> {1769 ^bb0(%xval: i32):1770 %newval = llvm.add %xval, %expr : i321771 omp.yield(%newval : i32)1772 }1773 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321774 }1775 1776 // CHECK: omp.atomic.capture hint(contended, nonspeculative) {1777 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1778 // CHECK-NEXT: (%[[xval:.*]]: i32):1779 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321780 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1781 // CHECK-NEXT: }1782 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321783 // CHECK-NEXT: }1784 omp.atomic.capture hint(contended, nonspeculative) {1785 omp.atomic.update %x : memref<i32> {1786 ^bb0(%xval: i32):1787 %newval = llvm.add %xval, %expr : i321788 omp.yield(%newval : i32)1789 }1790 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321791 }1792 1793 // CHECK: omp.atomic.capture hint(uncontended, speculative) {1794 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1795 // CHECK-NEXT: (%[[xval:.*]]: i32):1796 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321797 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1798 // CHECK-NEXT: }1799 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321800 // CHECK-NEXT: }1801 omp.atomic.capture hint(uncontended, speculative) {1802 omp.atomic.update %x : memref<i32> {1803 ^bb0(%xval: i32):1804 %newval = llvm.add %xval, %expr : i321805 omp.yield(%newval : i32)1806 }1807 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321808 }1809 1810 // CHECK: omp.atomic.capture hint(contended, speculative) {1811 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1812 // CHECK-NEXT: (%[[xval:.*]]: i32):1813 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321814 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1815 // CHECK-NEXT: }1816 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321817 // CHECK-NEXT: }1818 omp.atomic.capture hint(contended, speculative) {1819 omp.atomic.update %x : memref<i32> {1820 ^bb0(%xval: i32):1821 %newval = llvm.add %xval, %expr : i321822 omp.yield(%newval : i32)1823 }1824 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321825 }1826 1827 // CHECK: omp.atomic.capture memory_order(seq_cst) {1828 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1829 // CHECK-NEXT: (%[[xval:.*]]: i32):1830 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321831 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1832 // CHECK-NEXT: }1833 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321834 // CHECK-NEXT: }1835 omp.atomic.capture memory_order(seq_cst) {1836 omp.atomic.update %x : memref<i32> {1837 ^bb0(%xval: i32):1838 %newval = llvm.add %xval, %expr : i321839 omp.yield(%newval : i32)1840 }1841 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321842 }1843 1844 // CHECK: omp.atomic.capture memory_order(acq_rel) {1845 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1846 // CHECK-NEXT: (%[[xval:.*]]: i32):1847 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321848 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1849 // CHECK-NEXT: }1850 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321851 // CHECK-NEXT: }1852 omp.atomic.capture memory_order(acq_rel) {1853 omp.atomic.update %x : memref<i32> {1854 ^bb0(%xval: i32):1855 %newval = llvm.add %xval, %expr : i321856 omp.yield(%newval : i32)1857 }1858 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321859 }1860 1861 // CHECK: omp.atomic.capture memory_order(acquire) {1862 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1863 // CHECK-NEXT: (%[[xval:.*]]: i32):1864 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321865 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1866 // CHECK-NEXT: }1867 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321868 // CHECK-NEXT: }1869 omp.atomic.capture memory_order(acquire) {1870 omp.atomic.update %x : memref<i32> {1871 ^bb0(%xval: i32):1872 %newval = llvm.add %xval, %expr : i321873 omp.yield(%newval : i32)1874 }1875 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321876 }1877 1878 // CHECK: omp.atomic.capture memory_order(release) {1879 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1880 // CHECK-NEXT: (%[[xval:.*]]: i32):1881 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321882 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1883 // CHECK-NEXT: }1884 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321885 // CHECK-NEXT: }1886 omp.atomic.capture memory_order(release) {1887 omp.atomic.update %x : memref<i32> {1888 ^bb0(%xval: i32):1889 %newval = llvm.add %xval, %expr : i321890 omp.yield(%newval : i32)1891 }1892 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321893 }1894 1895 // CHECK: omp.atomic.capture memory_order(relaxed) {1896 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1897 // CHECK-NEXT: (%[[xval:.*]]: i32):1898 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321899 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1900 // CHECK-NEXT: }1901 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321902 // CHECK-NEXT: }1903 omp.atomic.capture memory_order(relaxed) {1904 omp.atomic.update %x : memref<i32> {1905 ^bb0(%xval: i32):1906 %newval = llvm.add %xval, %expr : i321907 omp.yield(%newval : i32)1908 }1909 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321910 }1911 1912 // CHECK: omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) {1913 // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>1914 // CHECK-NEXT: (%[[xval:.*]]: i32):1915 // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i321916 // CHECK-NEXT: omp.yield(%[[newval]] : i32)1917 // CHECK-NEXT: }1918 // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref<i32>, memref<i32>, i321919 // CHECK-NEXT: }1920 omp.atomic.capture hint(contended, speculative) memory_order(seq_cst) {1921 omp.atomic.update %x : memref<i32> {1922 ^bb0(%xval: i32):1923 %newval = llvm.add %xval, %expr : i321924 omp.yield(%newval : i32)1925 }1926 omp.atomic.read %v = %x : memref<i32>, memref<i32>, i321927 }1928 1929 return1930}1931 1932// CHECK-LABEL: omp_sectionsop1933func.func @omp_sectionsop(%data_var1 : memref<i32>, %data_var2 : memref<i32>,1934 %data_var3 : memref<i32>, %redn_var : !llvm.ptr) {1935 // CHECK: omp.sections allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>)1936 "omp.sections" (%data_var1, %data_var1) ({1937 // CHECK: omp.terminator1938 omp.terminator1939 }) {operandSegmentSizes = array<i32: 1,1,0,0>} : (memref<i32>, memref<i32>) -> ()1940 1941 // CHECK: omp.sections reduction(@add_f32 %{{.*}} -> %{{.*}} : !llvm.ptr)1942 "omp.sections" (%redn_var) ({1943 ^bb0(%arg0: !llvm.ptr):1944 // CHECK: omp.terminator1945 omp.terminator1946 }) {operandSegmentSizes = array<i32: 0,0,0,1>, reduction_byref = array<i1: false>, reduction_syms=[@add_f32]} : (!llvm.ptr) -> ()1947 1948 // CHECK: omp.sections nowait {1949 omp.sections nowait {1950 // CHECK: omp.terminator1951 omp.terminator1952 }1953 1954 // CHECK: omp.sections reduction(@add_f32 %{{.*}} -> %{{.*}} : !llvm.ptr) {1955 omp.sections reduction(@add_f32 %redn_var -> %arg0 : !llvm.ptr) {1956 // CHECK: omp.terminator1957 omp.terminator1958 }1959 1960 // CHECK: omp.sections allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>)1961 omp.sections allocate(%data_var1 : memref<i32> -> %data_var1 : memref<i32>) {1962 // CHECK: omp.terminator1963 omp.terminator1964 }1965 1966 // CHECK: omp.sections nowait1967 omp.sections nowait {1968 // CHECK: omp.section1969 omp.section {1970 // CHECK: %{{.*}} = "test.payload"() : () -> i321971 %1 = "test.payload"() : () -> i321972 // CHECK: %{{.*}} = "test.payload"() : () -> i321973 %2 = "test.payload"() : () -> i321974 // CHECK: %{{.*}} = "test.payload"(%{{.*}}, %{{.*}}) : (i32, i32) -> i321975 %3 = "test.payload"(%1, %2) : (i32, i32) -> i321976 }1977 // CHECK: omp.section1978 omp.section {1979 // CHECK: %{{.*}} = "test.payload"(%{{.*}}) : (!llvm.ptr) -> i321980 %1 = "test.payload"(%redn_var) : (!llvm.ptr) -> i321981 }1982 // CHECK: omp.section1983 omp.section {1984 // CHECK: "test.payload"(%{{.*}}) : (!llvm.ptr) -> ()1985 "test.payload"(%redn_var) : (!llvm.ptr) -> ()1986 }1987 // CHECK: omp.terminator1988 omp.terminator1989 }1990 return1991}1992 1993// CHECK-LABEL: func @omp_single1994func.func @omp_single() {1995 omp.parallel {1996 // CHECK: omp.single {1997 omp.single {1998 "test.payload"() : () -> ()1999 // CHECK: omp.terminator2000 omp.terminator2001 }2002 // CHECK: omp.terminator2003 omp.terminator2004 }2005 return2006}2007 2008// CHECK-LABEL: func @omp_single_nowait2009func.func @omp_single_nowait() {2010 omp.parallel {2011 // CHECK: omp.single nowait {2012 omp.single nowait {2013 "test.payload"() : () -> ()2014 // CHECK: omp.terminator2015 omp.terminator2016 }2017 // CHECK: omp.terminator2018 omp.terminator2019 }2020 return2021}2022 2023// CHECK-LABEL: func @omp_single_allocate2024func.func @omp_single_allocate(%data_var: memref<i32>) {2025 omp.parallel {2026 // CHECK: omp.single allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>) {2027 omp.single allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {2028 "test.payload"() : () -> ()2029 // CHECK: omp.terminator2030 omp.terminator2031 }2032 // CHECK: omp.terminator2033 omp.terminator2034 }2035 return2036}2037 2038// CHECK-LABEL: func @omp_single_allocate_nowait2039func.func @omp_single_allocate_nowait(%data_var: memref<i32>) {2040 omp.parallel {2041 // CHECK: omp.single allocate(%{{.*}} : memref<i32> -> %{{.*}} : memref<i32>) nowait {2042 omp.single allocate(%data_var : memref<i32> -> %data_var : memref<i32>) nowait {2043 "test.payload"() : () -> ()2044 // CHECK: omp.terminator2045 omp.terminator2046 }2047 // CHECK: omp.terminator2048 omp.terminator2049 }2050 return2051}2052 2053// CHECK-LABEL: func @omp_single_multiple_blocks2054func.func @omp_single_multiple_blocks() {2055 // CHECK: omp.single {2056 omp.single {2057 cf.br ^bb22058 ^bb2:2059 // CHECK: omp.terminator2060 omp.terminator2061 }2062 return2063}2064 2065func.func private @copy_i32(memref<i32>, memref<i32>)2066 2067// CHECK-LABEL: func @omp_single_copyprivate2068func.func @omp_single_copyprivate(%data_var: memref<i32>) {2069 omp.parallel {2070 // CHECK: omp.single copyprivate(%{{.*}} -> @copy_i32 : memref<i32>) {2071 omp.single copyprivate(%data_var -> @copy_i32 : memref<i32>) {2072 "test.payload"() : () -> ()2073 // CHECK: omp.terminator2074 omp.terminator2075 }2076 // CHECK: omp.terminator2077 omp.terminator2078 }2079 return2080}2081 2082// CHECK-LABEL: @omp_task2083// CHECK-SAME: (%[[bool_var:.*]]: i1, %[[i64_var:.*]]: i64, %[[i32_var:.*]]: i32, %[[data_var:.*]]: memref<i32>, %[[event_handle:.*]]: !llvm.ptr)2084func.func @omp_task(%bool_var: i1, %i64_var: i64, %i32_var: i32, %data_var: memref<i32>, %event_handle : !llvm.ptr) {2085 2086 // Checking simple task2087 // CHECK: omp.task {2088 omp.task {2089 // CHECK: "test.foo"() : () -> ()2090 "test.foo"() : () -> ()2091 // CHECK: omp.terminator2092 omp.terminator2093 }2094 2095 // Checking `if` clause2096 // CHECK: omp.task if(%[[bool_var]]) {2097 omp.task if(%bool_var) {2098 // CHECK: "test.foo"() : () -> ()2099 "test.foo"() : () -> ()2100 // CHECK: omp.terminator2101 omp.terminator2102 }2103 2104 // Checking `final` clause2105 // CHECK: omp.task final(%[[bool_var]]) {2106 omp.task final(%bool_var) {2107 // CHECK: "test.foo"() : () -> ()2108 "test.foo"() : () -> ()2109 // CHECK: omp.terminator2110 omp.terminator2111 }2112 2113 // Checking `untied` clause2114 // CHECK: omp.task untied {2115 omp.task untied {2116 // CHECK: "test.foo"() : () -> ()2117 "test.foo"() : () -> ()2118 // CHECK: omp.terminator2119 omp.terminator2120 }2121 2122 // Checking `in_reduction` clause2123 %c1 = arith.constant 1 : i322124 // CHECK: %[[redn_var1:.*]] = llvm.alloca %{{.*}} x f32 : (i32) -> !llvm.ptr2125 %0 = llvm.alloca %c1 x f32 : (i32) -> !llvm.ptr2126 // CHECK: %[[redn_var2:.*]] = llvm.alloca %{{.*}} x f32 : (i32) -> !llvm.ptr2127 %1 = llvm.alloca %c1 x f32 : (i32) -> !llvm.ptr2128 // CHECK: omp.task in_reduction(@add_f32 %[[redn_var1]] -> %{{.+}}, @add_f32 %[[redn_var2]] -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2129 omp.task in_reduction(@add_f32 %0 -> %arg0, @add_f32 %1 -> %arg1 : !llvm.ptr, !llvm.ptr) {2130 // CHECK: "test.foo"() : () -> ()2131 "test.foo"() : () -> ()2132 // CHECK: omp.terminator2133 omp.terminator2134 }2135 2136 // Checking `in_reduction` clause (mixed) byref2137 // CHECK: omp.task in_reduction(byref @add_f32 %[[redn_var1]] -> %{{.+}}, @add_f32 %[[redn_var2]] -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2138 omp.task in_reduction(byref @add_f32 %0 -> %arg0, @add_f32 %1 -> %arg1 : !llvm.ptr, !llvm.ptr) {2139 // CHECK: "test.foo"() : () -> ()2140 "test.foo"() : () -> ()2141 // CHECK: omp.terminator2142 omp.terminator2143 }2144 2145 // Checking priority clause2146 // CHECK: omp.task priority(%[[i32_var]] : i32) {2147 omp.task priority(%i32_var : i32) {2148 // CHECK: "test.foo"() : () -> ()2149 "test.foo"() : () -> ()2150 // CHECK: omp.terminator2151 omp.terminator2152 }2153 2154 // Checking allocate clause2155 // CHECK: omp.task allocate(%[[data_var]] : memref<i32> -> %[[data_var]] : memref<i32>) {2156 omp.task allocate(%data_var : memref<i32> -> %data_var : memref<i32>) {2157 // CHECK: "test.foo"() : () -> ()2158 "test.foo"() : () -> ()2159 // CHECK: omp.terminator2160 omp.terminator2161 }2162 // Checking detach clause2163 // CHECK: omp.task detach(%[[event_handle]] : !llvm.ptr)2164 omp.task detach(%event_handle : !llvm.ptr){2165 omp.terminator2166 }2167 // Checking multiple clauses2168 // CHECK: omp.task allocate(%[[data_var]] : memref<i32> -> %[[data_var]] : memref<i32>)2169 omp.task allocate(%data_var : memref<i32> -> %data_var : memref<i32>)2170 // CHECK-SAME: final(%[[bool_var]]) if(%[[bool_var]])2171 final(%bool_var) if(%bool_var)2172 // CHECK-SAME: priority(%[[i32_var]] : i32) untied2173 priority(%i32_var : i32) untied2174 // CHECK-SAME: in_reduction(@add_f32 %[[redn_var1]] -> %{{.+}}, byref @add_f32 %[[redn_var2]] -> %{{.+}} : !llvm.ptr, !llvm.ptr)2175 in_reduction(@add_f32 %0 -> %arg0, byref @add_f32 %1 -> %arg1 : !llvm.ptr, !llvm.ptr) {2176 // CHECK: "test.foo"() : () -> ()2177 "test.foo"() : () -> ()2178 // CHECK: omp.terminator2179 omp.terminator2180 }2181 2182 return2183}2184 2185// CHECK-LABEL: @omp_task_depend2186// CHECK-SAME: (%arg0: memref<i32>, %arg1: memref<i32>) {2187func.func @omp_task_depend(%arg0: memref<i32>, %arg1: memref<i32>) {2188 // CHECK: omp.task depend(taskdependin -> %arg0 : memref<i32>, taskdependin -> %arg1 : memref<i32>, taskdependinout -> %arg0 : memref<i32>) {2189 omp.task depend(taskdependin -> %arg0 : memref<i32>, taskdependin -> %arg1 : memref<i32>, taskdependinout -> %arg0 : memref<i32>) {2190 // CHECK: "test.foo"() : () -> ()2191 "test.foo"() : () -> ()2192 // CHECK: omp.terminator2193 omp.terminator2194 }2195 return2196}2197 2198 2199// CHECK-LABEL: @omp_target_depend2200// CHECK-SAME: (%arg0: memref<i32>, %arg1: memref<i32>) {2201func.func @omp_target_depend(%arg0: memref<i32>, %arg1: memref<i32>) {2202 // CHECK: omp.target depend(taskdependin -> %arg0 : memref<i32>, taskdependin -> %arg1 : memref<i32>, taskdependinout -> %arg0 : memref<i32>) {2203 omp.target depend(taskdependin -> %arg0 : memref<i32>, taskdependin -> %arg1 : memref<i32>, taskdependinout -> %arg0 : memref<i32>) {2204 // CHECK: omp.terminator2205 omp.terminator2206 } {operandSegmentSizes = array<i32: 0,0,0,3,0,0,0,0>}2207 return2208}2209 2210func.func @omp_threadprivate() {2211 %0 = arith.constant 1 : i322212 %1 = arith.constant 2 : i322213 %2 = arith.constant 3 : i322214 2215 // CHECK: [[ARG0:%.*]] = llvm.mlir.addressof @_QFsubEx : !llvm.ptr2216 // CHECK: {{.*}} = omp.threadprivate [[ARG0]] : !llvm.ptr -> !llvm.ptr2217 %3 = llvm.mlir.addressof @_QFsubEx : !llvm.ptr2218 %4 = omp.threadprivate %3 : !llvm.ptr -> !llvm.ptr2219 llvm.store %0, %4 : i32, !llvm.ptr2220 2221 // CHECK: omp.parallel2222 // CHECK: {{.*}} = omp.threadprivate [[ARG0]] : !llvm.ptr -> !llvm.ptr2223 omp.parallel {2224 %5 = omp.threadprivate %3 : !llvm.ptr -> !llvm.ptr2225 llvm.store %1, %5 : i32, !llvm.ptr2226 omp.terminator2227 }2228 llvm.store %2, %4 : i32, !llvm.ptr2229 return2230}2231 2232llvm.mlir.global internal @_QFsubEx() : i322233 2234func.func @omp_cancel_parallel(%if_cond : i1) -> () {2235 // Test with optional operand; if_expr.2236 omp.parallel {2237 // CHECK: omp.cancel cancellation_construct_type(parallel) if(%{{.*}})2238 omp.cancel cancellation_construct_type(parallel) if(%if_cond)2239 // CHECK: omp.terminator2240 omp.terminator2241 }2242 return2243}2244 2245func.func @omp_cancel_wsloop(%lb : index, %ub : index, %step : index) {2246 omp.wsloop {2247 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {2248 // CHECK: omp.cancel cancellation_construct_type(loop)2249 omp.cancel cancellation_construct_type(loop)2250 // CHECK: omp.yield2251 omp.yield2252 }2253 }2254 return2255}2256 2257func.func @omp_cancel_sections() -> () {2258 omp.sections {2259 omp.section {2260 // CHECK: omp.cancel cancellation_construct_type(sections)2261 omp.cancel cancellation_construct_type(sections)2262 omp.terminator2263 }2264 // CHECK: omp.terminator2265 omp.terminator2266 }2267 return2268}2269 2270func.func @omp_cancel_taskgroup() -> () {2271 omp.taskgroup {2272 omp.task {2273 // CHECK: omp.cancel cancellation_construct_type(taskgroup)2274 omp.cancel cancellation_construct_type(taskgroup)2275 // CHECK: omp.terminator2276 omp.terminator2277 }2278 // CHECK: omp.terminator2279 omp.terminator2280 }2281 return2282}2283 2284func.func @omp_taskloop_cancel_taskgroup(%lb : index, %ub : index, %step : index) {2285 omp.taskloop {2286 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {2287 // CHECK: omp.cancel cancellation_construct_type(taskgroup)2288 omp.cancel cancellation_construct_type(taskgroup)2289 // CHECK: omp.yield2290 omp.yield2291 }2292 }2293 return2294}2295 2296func.func @omp_cancel_parallel_nested(%if_cond : i1) -> () {2297 omp.parallel {2298 scf.if %if_cond {2299 // CHECK: omp.cancel cancellation_construct_type(parallel)2300 omp.cancel cancellation_construct_type(parallel)2301 }2302 // CHECK: omp.terminator2303 omp.terminator2304 }2305 return2306}2307 2308func.func @omp_cancel_wsloop_nested(%lb : index, %ub : index, %step : index,2309 %if_cond : i1) {2310 omp.wsloop {2311 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {2312 scf.if %if_cond {2313 // CHECK: omp.cancel cancellation_construct_type(loop)2314 omp.cancel cancellation_construct_type(loop)2315 }2316 // CHECK: omp.yield2317 omp.yield2318 }2319 }2320 return2321}2322 2323func.func @omp_cancel_sections_nested(%if_cond : i1) -> () {2324 omp.sections {2325 omp.section {2326 scf.if %if_cond {2327 // CHECK: omp.cancel cancellation_construct_type(sections)2328 omp.cancel cancellation_construct_type(sections)2329 }2330 omp.terminator2331 }2332 // CHECK: omp.terminator2333 omp.terminator2334 }2335 return2336}2337 2338func.func @omp_cancel_taskgroup_nested(%if_cond : i1) -> () {2339 omp.taskgroup {2340 omp.task {2341 scf.if %if_cond {2342 // CHECK: omp.cancel cancellation_construct_type(taskgroup)2343 omp.cancel cancellation_construct_type(taskgroup)2344 }2345 // CHECK: omp.terminator2346 omp.terminator2347 }2348 // CHECK: omp.terminator2349 omp.terminator2350 }2351 return2352}2353 2354func.func @omp_cancellationpoint_parallel() -> () {2355 omp.parallel {2356 // CHECK: omp.cancellation_point cancellation_construct_type(parallel)2357 omp.cancellation_point cancellation_construct_type(parallel)2358 // CHECK: omp.cancel cancellation_construct_type(parallel)2359 omp.cancel cancellation_construct_type(parallel)2360 omp.terminator2361 }2362 return2363}2364 2365func.func @omp_cancellationpoint_wsloop(%lb : index, %ub : index, %step : index) {2366 omp.wsloop {2367 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {2368 // CHECK: omp.cancellation_point cancellation_construct_type(loop)2369 omp.cancellation_point cancellation_construct_type(loop)2370 // CHECK: omp.cancel cancellation_construct_type(loop)2371 omp.cancel cancellation_construct_type(loop)2372 // CHECK: omp.yield2373 omp.yield2374 }2375 }2376 return2377}2378 2379func.func @omp_cancellationpoint_sections() -> () {2380 omp.sections {2381 omp.section {2382 // CHECK: omp.cancellation_point cancellation_construct_type(sections)2383 omp.cancellation_point cancellation_construct_type(sections)2384 // CHECK: omp.cancel cancellation_construct_type(sections)2385 omp.cancel cancellation_construct_type(sections)2386 omp.terminator2387 }2388 // CHECK: omp.terminator2389 omp.terminator2390 }2391 return2392}2393 2394func.func @omp_cancellationpoint_taskgroup() -> () {2395 omp.taskgroup {2396 omp.task {2397 // CHECK: omp.cancellation_point cancellation_construct_type(taskgroup)2398 omp.cancellation_point cancellation_construct_type(taskgroup)2399 // CHECK: omp.cancel cancellation_construct_type(taskgroup)2400 omp.cancel cancellation_construct_type(taskgroup)2401 // CHECK: omp.terminator2402 omp.terminator2403 }2404 // CHECK: omp.terminator2405 omp.terminator2406 }2407 return2408}2409 2410func.func @omp_cancellationpoint_parallel_nested(%if_cond : i1) -> () {2411 omp.parallel {2412 scf.if %if_cond {2413 // CHECK: omp.cancellation_point cancellation_construct_type(parallel)2414 omp.cancellation_point cancellation_construct_type(parallel)2415 }2416 omp.terminator2417 }2418 return2419}2420 2421func.func @omp_cancellationpoint_wsloop_nested(%lb : index, %ub : index, %step : index, %if_cond : i1) {2422 omp.wsloop {2423 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {2424 scf.if %if_cond {2425 // CHECK: omp.cancellation_point cancellation_construct_type(loop)2426 omp.cancellation_point cancellation_construct_type(loop)2427 }2428 // CHECK: omp.yield2429 omp.yield2430 }2431 }2432 return2433}2434 2435func.func @omp_cancellationpoint_sections_nested(%if_cond : i1) -> () {2436 omp.sections {2437 omp.section {2438 scf.if %if_cond {2439 // CHECK: omp.cancellation_point cancellation_construct_type(sections)2440 omp.cancellation_point cancellation_construct_type(sections)2441 }2442 omp.terminator2443 }2444 // CHECK: omp.terminator2445 omp.terminator2446 }2447 return2448}2449 2450func.func @omp_cancellationpoint_taskgroup_nested(%if_cond : i1) -> () {2451 omp.taskgroup {2452 omp.task {2453 scf.if %if_cond {2454 // CHECK: omp.cancellation_point cancellation_construct_type(taskgroup)2455 omp.cancellation_point cancellation_construct_type(taskgroup)2456 }2457 omp.terminator2458 }2459 // CHECK: omp.terminator2460 omp.terminator2461 }2462 return2463}2464 2465// CHECK-LABEL: @omp_taskgroup_no_tasks2466func.func @omp_taskgroup_no_tasks() -> () {2467 2468 // CHECK: omp.taskgroup2469 omp.taskgroup {2470 // CHECK: "test.foo"() : () -> ()2471 "test.foo"() : () -> ()2472 // CHECK: omp.terminator2473 omp.terminator2474 }2475 return2476}2477 2478// CHECK-LABEL: @omp_taskgroup_multiple_tasks2479func.func @omp_taskgroup_multiple_tasks() -> () {2480 // CHECK: omp.taskgroup2481 omp.taskgroup {2482 // CHECK: omp.task2483 omp.task {2484 "test.foo"() : () -> ()2485 // CHECK: omp.terminator2486 omp.terminator2487 }2488 // CHECK: omp.task2489 omp.task {2490 "test.foo"() : () -> ()2491 // CHECK: omp.terminator2492 omp.terminator2493 }2494 // CHECK: omp.terminator2495 omp.terminator2496 }2497 return2498}2499 2500// CHECK-LABEL: @omp_taskgroup_clauses2501func.func @omp_taskgroup_clauses() -> () {2502 %testmemref = "test.memref"() : () -> (memref<i32>)2503 %testf32 = "test.f32"() : () -> (!llvm.ptr)2504 // CHECK: omp.taskgroup allocate(%{{.+}}: memref<i32> -> %{{.+}} : memref<i32>) task_reduction(@add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr)2505 omp.taskgroup allocate(%testmemref : memref<i32> -> %testmemref : memref<i32>) task_reduction(@add_f32 %testf32 -> %arg0 : !llvm.ptr) {2506 // CHECK: omp.task2507 omp.task {2508 "test.foo"() : () -> ()2509 // CHECK: omp.terminator2510 omp.terminator2511 }2512 // CHECK: omp.task2513 omp.task {2514 "test.foo"() : () -> ()2515 // CHECK: omp.terminator2516 omp.terminator2517 }2518 // CHECK: omp.terminator2519 omp.terminator2520 }2521 return2522}2523 2524// CHECK-LABEL: @omp_taskloop2525func.func @omp_taskloop(%lb: i32, %ub: i32, %step: i32) -> () {2526 2527 // CHECK: omp.taskloop {2528 omp.taskloop {2529 omp.loop_nest (%i) : i32 = (%lb) to (%ub) step (%step) {2530 // CHECK: omp.yield2531 omp.yield2532 }2533 }2534 2535 %testbool = "test.bool"() : () -> (i1)2536 2537 // CHECK: omp.taskloop if(%{{[^)]+}}) {2538 omp.taskloop if(%testbool) {2539 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2540 // CHECK: omp.yield2541 omp.yield2542 }2543 }2544 2545 // CHECK: omp.taskloop final(%{{[^)]+}}) {2546 omp.taskloop final(%testbool) {2547 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2548 // CHECK: omp.yield2549 omp.yield2550 }2551 }2552 2553 // CHECK: omp.taskloop untied {2554 omp.taskloop untied {2555 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2556 // CHECK: omp.yield2557 omp.yield2558 }2559 }2560 2561 // CHECK: omp.taskloop mergeable {2562 omp.taskloop mergeable {2563 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2564 // CHECK: omp.yield2565 omp.yield2566 }2567 }2568 2569 %testf32 = "test.f32"() : () -> (!llvm.ptr)2570 %testf32_2 = "test.f32"() : () -> (!llvm.ptr)2571 // CHECK: omp.taskloop in_reduction(@add_f32 %{{.+}} -> %{{.+}}, @add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2572 omp.taskloop in_reduction(@add_f32 %testf32 -> %arg0, @add_f32 %testf32_2 -> %arg1 : !llvm.ptr, !llvm.ptr) {2573 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2574 // CHECK: omp.yield2575 omp.yield2576 }2577 }2578 2579 // Checking byref attribute for in_reduction2580 // CHECK: omp.taskloop in_reduction(byref @add_f32 %{{.+}} -> %{{.+}}, @add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2581 omp.taskloop in_reduction(byref @add_f32 %testf32 -> %arg0, @add_f32 %testf32_2 -> %arg1 : !llvm.ptr, !llvm.ptr) {2582 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2583 // CHECK: omp.yield2584 omp.yield2585 }2586 }2587 2588 // CHECK: omp.taskloop reduction(byref @add_f32 %{{.+}} -> %{{.+}}, @add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2589 omp.taskloop reduction(byref @add_f32 %testf32 -> %arg0, @add_f32 %testf32_2 -> %arg1 : !llvm.ptr, !llvm.ptr) {2590 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2591 // CHECK: omp.yield2592 omp.yield2593 }2594 }2595 2596 // check byref attrbute for reduction2597 // CHECK: omp.taskloop reduction(byref @add_f32 %{{.+}} -> %{{.+}}, byref @add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr, !llvm.ptr) {2598 omp.taskloop reduction(byref @add_f32 %testf32 -> %arg0, byref @add_f32 %testf32_2 -> %arg1 : !llvm.ptr, !llvm.ptr) {2599 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2600 // CHECK: omp.yield2601 omp.yield2602 }2603 }2604 2605 // CHECK: omp.taskloop in_reduction(@add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr) reduction(@add_f32 %{{.+}} -> %{{.+}} : !llvm.ptr) {2606 omp.taskloop in_reduction(@add_f32 %testf32 -> %arg0 : !llvm.ptr) reduction(@add_f32 %testf32_2 -> %arg1 : !llvm.ptr) {2607 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2608 // CHECK: omp.yield2609 omp.yield2610 }2611 }2612 2613 %testi32 = "test.i32"() : () -> (i32)2614 // CHECK: omp.taskloop priority(%{{[^:]+}}: i32) {2615 omp.taskloop priority(%testi32 : i32) {2616 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2617 // CHECK: omp.yield2618 omp.yield2619 }2620 }2621 2622 %testmemref = "test.memref"() : () -> (memref<i32>)2623 // CHECK: omp.taskloop allocate(%{{.+}} : memref<i32> -> %{{.+}} : memref<i32>) {2624 omp.taskloop allocate(%testmemref : memref<i32> -> %testmemref : memref<i32>) {2625 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2626 // CHECK: omp.yield2627 omp.yield2628 }2629 }2630 2631 %testi64 = "test.i64"() : () -> (i64)2632 // CHECK: omp.taskloop grainsize(%{{[^:]+}}: i64) {2633 omp.taskloop grainsize(%testi64: i64) {2634 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2635 // CHECK: omp.yield2636 omp.yield2637 }2638 }2639 2640 // CHECK: omp.taskloop num_tasks(%{{[^:]+}}: i64) {2641 omp.taskloop num_tasks(%testi64: i64) {2642 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2643 // CHECK: omp.yield2644 omp.yield2645 }2646 }2647 2648 // CHECK: omp.taskloop grainsize(strict, %{{[^:]+}}: i64) {2649 omp.taskloop grainsize(strict, %testi64: i64) {2650 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2651 // CHECK: omp.yield2652 omp.yield2653 }2654 }2655 2656 // CHECK: omp.taskloop num_tasks(strict, %{{[^:]+}}: i64) {2657 omp.taskloop num_tasks(strict, %testi64: i64) {2658 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2659 // CHECK: omp.yield2660 omp.yield2661 }2662 }2663 2664 // CHECK: omp.taskloop nogroup {2665 omp.taskloop nogroup {2666 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2667 // CHECK: omp.yield2668 omp.yield2669 }2670 }2671 2672 // CHECK: omp.taskloop {2673 omp.taskloop {2674 omp.simd {2675 omp.loop_nest (%i, %j) : i32 = (%lb, %ub) to (%ub, %lb) step (%step, %step) {2676 // CHECK: omp.yield2677 omp.yield2678 }2679 } {omp.composite}2680 } {omp.composite}2681 2682 // CHECK: return2683 return2684}2685 2686// CHECK: func.func @omp_requires_one2687// CHECK-SAME: omp.requires = #omp<clause_requires reverse_offload>2688func.func @omp_requires_one() -> ()2689 attributes {omp.requires = #omp<clause_requires reverse_offload>} {2690 return2691}2692 2693// CHECK: func.func @omp_requires_multiple2694// CHECK-SAME: omp.requires = #omp<clause_requires unified_address|dynamic_allocators>2695func.func @omp_requires_multiple() -> ()2696 attributes {omp.requires = #omp<clause_requires unified_address|dynamic_allocators>} {2697 return2698}2699 2700// CHECK-LABEL: @opaque_pointers_atomic_rwu2701// CHECK-SAME: (%[[v:.*]]: !llvm.ptr, %[[x:.*]]: !llvm.ptr)2702func.func @opaque_pointers_atomic_rwu(%v: !llvm.ptr, %x: !llvm.ptr) {2703 // CHECK: omp.atomic.read %[[v]] = %[[x]] : !llvm.ptr, !llvm.ptr, i322704 // CHECK: %[[VAL:.*]] = llvm.load %[[x]] : !llvm.ptr -> i322705 // CHECK: omp.atomic.write %[[v]] = %[[VAL]] : !llvm.ptr, i322706 // CHECK: omp.atomic.update %[[x]] : !llvm.ptr {2707 // CHECK-NEXT: ^{{[[:alnum:]]+}}(%[[XVAL:.*]]: i32):2708 // CHECK-NEXT: omp.yield(%[[XVAL]] : i32)2709 // CHECK-NEXT: }2710 omp.atomic.read %v = %x : !llvm.ptr, !llvm.ptr, i322711 %val = llvm.load %x : !llvm.ptr -> i322712 omp.atomic.write %v = %val : !llvm.ptr, i322713 omp.atomic.update %x : !llvm.ptr {2714 ^bb0(%xval: i32):2715 omp.yield(%xval : i32)2716 }2717 return2718}2719 2720// CHECK-LABEL: @opaque_pointers_reduction2721// CHECK: atomic {2722// CHECK-NEXT: ^{{[[:alnum:]]+}}(%{{.*}}: !llvm.ptr, %{{.*}}: !llvm.ptr):2723// CHECK-NOT: cleanup2724omp.declare_reduction @opaque_pointers_reduction : f322725init {2726^bb0(%arg: f32):2727 %0 = arith.constant 0.0 : f322728 omp.yield (%0 : f32)2729}2730combiner {2731^bb1(%arg0: f32, %arg1: f32):2732 %1 = arith.addf %arg0, %arg1 : f322733 omp.yield (%1 : f32)2734}2735atomic {2736^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):2737 %2 = llvm.load %arg3 : !llvm.ptr -> f322738 llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f322739 omp.yield2740}2741 2742// CHECK-LABEL: @alloc_reduction2743// CHECK-SAME: alloc {2744// CHECK-NEXT: ^bb0(%[[ARG0:.*]]: !llvm.ptr):2745// ...2746// CHECK: omp.yield2747// CHECK-NEXT: } init {2748// CHECK: } combiner {2749// CHECK: }2750omp.declare_reduction @alloc_reduction : !llvm.ptr2751alloc {2752^bb0(%arg: !llvm.ptr):2753 %c1 = arith.constant 1 : i322754 %0 = llvm.alloca %c1 x f32 : (i32) -> !llvm.ptr2755 omp.yield (%0 : !llvm.ptr)2756}2757init {2758^bb0(%mold: !llvm.ptr, %alloc: !llvm.ptr):2759 %cst = arith.constant 1.0 : f322760 llvm.store %cst, %alloc : f32, !llvm.ptr2761 omp.yield (%alloc : !llvm.ptr)2762}2763combiner {2764^bb1(%arg0: !llvm.ptr, %arg1: !llvm.ptr):2765 %0 = llvm.load %arg0 : !llvm.ptr -> f322766 %1 = llvm.load %arg1 : !llvm.ptr -> f322767 %2 = arith.addf %0, %1 : f322768 llvm.store %2, %arg0 : f32, !llvm.ptr2769 omp.yield (%arg0 : !llvm.ptr)2770}2771 2772// CHECK-LABEL: omp_targets_with_map_bounds2773// CHECK-SAME: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr)2774func.func @omp_targets_with_map_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () {2775 // CHECK: %[[C_00:.*]] = llvm.mlir.constant(4 : index) : i642776 // CHECK: %[[C_01:.*]] = llvm.mlir.constant(1 : index) : i642777 // CHECK: %[[C_02:.*]] = llvm.mlir.constant(1 : index) : i642778 // CHECK: %[[C_03:.*]] = llvm.mlir.constant(1 : index) : i642779 // CHECK: %[[BOUNDS0:.*]] = omp.map.bounds lower_bound(%[[C_01]] : i64) upper_bound(%[[C_00]] : i64) stride(%[[C_02]] : i64) start_idx(%[[C_03]] : i64)2780 // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""}2781 %0 = llvm.mlir.constant(4 : index) : i642782 %1 = llvm.mlir.constant(1 : index) : i642783 %2 = llvm.mlir.constant(1 : index) : i642784 %3 = llvm.mlir.constant(1 : index) : i642785 %4 = omp.map.bounds lower_bound(%1 : i64) upper_bound(%0 : i64) stride(%2 : i64) start_idx(%3 : i64)2786 2787 %mapv1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(tofrom) capture(ByRef) bounds(%4) -> !llvm.ptr {name = ""}2788 // CHECK: %[[C_10:.*]] = llvm.mlir.constant(9 : index) : i642789 // CHECK: %[[C_11:.*]] = llvm.mlir.constant(1 : index) : i642790 // CHECK: %[[C_12:.*]] = llvm.mlir.constant(2 : index) : i642791 // CHECK: %[[C_13:.*]] = llvm.mlir.constant(2 : index) : i642792 // CHECK: %[[BOUNDS1:.*]] = omp.map.bounds lower_bound(%[[C_11]] : i64) upper_bound(%[[C_10]] : i64) stride(%[[C_12]] : i64) start_idx(%[[C_13]] : i64)2793 // CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(ByCopy) mapper(@my_mapper) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""}2794 %6 = llvm.mlir.constant(9 : index) : i642795 %7 = llvm.mlir.constant(1 : index) : i642796 %8 = llvm.mlir.constant(2 : index) : i642797 %9 = llvm.mlir.constant(2 : index) : i642798 %10 = omp.map.bounds lower_bound(%7 : i64) upper_bound(%6 : i64) stride(%8 : i64) start_idx(%9 : i64)2799 %mapv2 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(ByCopy) mapper(@my_mapper) bounds(%10) -> !llvm.ptr {name = ""}2800 2801 // CHECK: omp.target map_entries(%[[MAP0]] -> {{.*}}, %[[MAP1]] -> {{.*}} : !llvm.ptr, !llvm.ptr)2802 omp.target map_entries(%mapv1 -> %arg2, %mapv2 -> %arg3 : !llvm.ptr, !llvm.ptr) {2803 omp.terminator2804 }2805 2806 // CHECK: omp.target_data map_entries(%[[MAP0]], %[[MAP1]] : !llvm.ptr, !llvm.ptr)2807 omp.target_data map_entries(%mapv1, %mapv2 : !llvm.ptr, !llvm.ptr){}2808 2809 // CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(VLAType) bounds(%[[BOUNDS0]]) -> !llvm.ptr {name = ""}2810 // CHECK: omp.target_enter_data map_entries(%[[MAP2]] : !llvm.ptr)2811 %mapv3 = omp.map.info var_ptr(%arg0 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(VLAType) bounds(%4) -> !llvm.ptr {name = ""}2812 omp.target_enter_data map_entries(%mapv3 : !llvm.ptr){}2813 2814 // CHECK: %[[MAP3:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(This) bounds(%[[BOUNDS1]]) -> !llvm.ptr {name = ""}2815 // CHECK: omp.target_exit_data map_entries(%[[MAP3]] : !llvm.ptr)2816 %mapv4 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.array<10 x i32>) map_clauses(storage) capture(This) bounds(%10) -> !llvm.ptr {name = ""}2817 omp.target_exit_data map_entries(%mapv4 : !llvm.ptr){}2818 2819 return2820}2821 2822// CHECK-LABEL: omp_target_update_data2823func.func @omp_target_update_data (%if_cond : i1, %device : si32, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () {2824 %mapv_from = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""}2825 2826 %mapv_to = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(present, to) capture(ByRef) -> memref<?xi32> {name = ""}2827 2828 // CHECK: omp.target_update device(%[[VAL_1:.*]] : si32) if(%[[VAL_0:.*]]) map_entries(%{{.*}}, %{{.*}} : memref<?xi32>, memref<?xi32>) nowait2829 omp.target_update if(%if_cond) device(%device : si32) nowait map_entries(%mapv_from , %mapv_to : memref<?xi32>, memref<?xi32>)2830 return2831}2832 2833// CHECK-LABEL: omp_targets_is_allocatable2834// CHECK-SAME: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr)2835func.func @omp_targets_is_allocatable(%arg0: !llvm.ptr, %arg1: !llvm.ptr) -> () {2836 // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}2837 %mapv1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr {name = ""}2838 // CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%[[MAP0]] : [0] : !llvm.ptr) -> !llvm.ptr {name = ""}2839 %mapv2 = omp.map.info var_ptr(%arg1 : !llvm.ptr, !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) map_clauses(tofrom) capture(ByRef) members(%mapv1 : [0] : !llvm.ptr) -> !llvm.ptr {name = ""}2840 // CHECK: omp.target map_entries(%[[MAP0]] -> {{.*}}, %[[MAP1]] -> {{.*}} : !llvm.ptr, !llvm.ptr)2841 omp.target map_entries(%mapv1 -> %arg2, %mapv2 -> %arg3 : !llvm.ptr, !llvm.ptr) {2842 omp.terminator2843 }2844 return2845}2846 2847// CHECK-LABEL: func @omp_target_enter_update_exit_data_depend2848// CHECK-SAME:([[ARG0:%.*]]: memref<?xi32>, [[ARG1:%.*]]: memref<?xi32>, [[ARG2:%.*]]: memref<?xi32>) {2849func.func @omp_target_enter_update_exit_data_depend(%a: memref<?xi32>, %b: memref<?xi32>, %c: memref<?xi32>) {2850// CHECK-NEXT: [[MAP0:%.*]] = omp.map.info2851// CHECK-NEXT: [[MAP1:%.*]] = omp.map.info2852// CHECK-NEXT: [[MAP2:%.*]] = omp.map.info2853 %map_a = omp.map.info var_ptr(%a: memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32>2854 %map_b = omp.map.info var_ptr(%b: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32>2855 %map_c = omp.map.info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32>2856 2857 // Do some work on the host that writes to 'a'2858 omp.task depend(taskdependout -> %a : memref<?xi32>) {2859 "test.foo"(%a) : (memref<?xi32>) -> ()2860 omp.terminator2861 }2862 2863 // Then map that over to the target2864 // CHECK: omp.target_enter_data depend(taskdependin -> [[ARG0]] : memref<?xi32>) map_entries([[MAP0]], [[MAP2]] : memref<?xi32>, memref<?xi32>) nowait2865 omp.target_enter_data depend(taskdependin -> %a: memref<?xi32>) nowait map_entries(%map_a, %map_c: memref<?xi32>, memref<?xi32>)2866 2867 // Compute 'b' on the target and copy it back2868 // CHECK: omp.target map_entries([[MAP1]] -> {{%.*}} : memref<?xi32>) {2869 omp.target map_entries(%map_b -> %arg0 : memref<?xi32>) {2870 "test.foo"(%arg0) : (memref<?xi32>) -> ()2871 omp.terminator2872 }2873 2874 // Update 'a' on the host using 'b'2875 omp.task depend(taskdependout -> %a: memref<?xi32>){2876 "test.bar"(%a, %b) : (memref<?xi32>, memref<?xi32>) -> ()2877 }2878 2879 // Copy the updated 'a' onto the target2880 // CHECK: omp.target_update depend(taskdependin -> [[ARG0]] : memref<?xi32>) map_entries([[MAP0]] : memref<?xi32>) nowait2881 omp.target_update depend(taskdependin -> %a : memref<?xi32>) nowait map_entries(%map_a : memref<?xi32>)2882 2883 // Compute 'c' on the target and copy it back2884 %map_c_from = omp.map.info var_ptr(%c: memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32>2885 omp.target depend(taskdependout -> %c : memref<?xi32>) map_entries(%map_a -> %arg0, %map_c_from -> %arg1 : memref<?xi32>, memref<?xi32>) {2886 "test.foobar"() : ()->()2887 omp.terminator2888 }2889 // CHECK: omp.target_exit_data depend(taskdependin -> [[ARG2]] : memref<?xi32>) map_entries([[MAP2]] : memref<?xi32>)2890 omp.target_exit_data depend(taskdependin -> %c : memref<?xi32>) map_entries(%map_c : memref<?xi32>)2891 2892 return2893}2894 2895// CHECK-LABEL: omp_map_with_members2896// CHECK-SAME: (%[[ARG0:.*]]: !llvm.ptr, %[[ARG1:.*]]: !llvm.ptr, %[[ARG2:.*]]: !llvm.ptr, %[[ARG3:.*]]: !llvm.ptr, %[[ARG4:.*]]: !llvm.ptr, %[[ARG5:.*]]: !llvm.ptr)2897func.func @omp_map_with_members(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr, %arg3: !llvm.ptr, %arg4: !llvm.ptr, %arg5: !llvm.ptr) -> () {2898 // CHECK: %[[MAP0:.*]] = omp.map.info var_ptr(%[[ARG0]] : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}2899 %mapv1 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}2900 2901 // CHECK: %[[MAP1:.*]] = omp.map.info var_ptr(%[[ARG1]] : !llvm.ptr, f32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}2902 %mapv2 = omp.map.info var_ptr(%arg1 : !llvm.ptr, f32) map_clauses(to) capture(ByRef) -> !llvm.ptr {name = ""}2903 2904 // CHECK: %[[MAP2:.*]] = omp.map.info var_ptr(%[[ARG2]] : !llvm.ptr, !llvm.struct<(i32, f32)>) map_clauses(to) capture(ByRef) members(%[[MAP0]], %[[MAP1]] : [0], [1] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "", partial_map = true}2905 %mapv3 = omp.map.info var_ptr(%arg2 : !llvm.ptr, !llvm.struct<(i32, f32)>) map_clauses(to) capture(ByRef) members(%mapv1, %mapv2 : [0], [1] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "", partial_map = true}2906 2907 // CHECK: omp.target_enter_data map_entries(%[[MAP0]], %[[MAP1]], %[[MAP2]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)2908 omp.target_enter_data map_entries(%mapv1, %mapv2, %mapv3 : !llvm.ptr, !llvm.ptr, !llvm.ptr){}2909 2910 // CHECK: %[[MAP3:.*]] = omp.map.info var_ptr(%[[ARG3]] : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}2911 %mapv4 = omp.map.info var_ptr(%arg3 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}2912 2913 // CHECK: %[[MAP4:.*]] = omp.map.info var_ptr(%[[ARG4]] : !llvm.ptr, f32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}2914 %mapv5 = omp.map.info var_ptr(%arg4 : !llvm.ptr, f32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = ""}2915 2916 // CHECK: %[[MAP5:.*]] = omp.map.info var_ptr(%[[ARG5]] : !llvm.ptr, !llvm.struct<(i32, struct<(i32, f32)>)>) map_clauses(from) capture(ByRef) members(%[[MAP3]], %[[MAP4]] : [1, 0], [1, 1] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "", partial_map = true}2917 %mapv6 = omp.map.info var_ptr(%arg5 : !llvm.ptr, !llvm.struct<(i32, struct<(i32, f32)>)>) map_clauses(from) capture(ByRef) members(%mapv4, %mapv5 : [1, 0], [1, 1] : !llvm.ptr, !llvm.ptr) -> !llvm.ptr {name = "", partial_map = true}2918 2919 // CHECK: omp.target_exit_data map_entries(%[[MAP3]], %[[MAP4]], %[[MAP5]] : !llvm.ptr, !llvm.ptr, !llvm.ptr)2920 omp.target_exit_data map_entries(%mapv4, %mapv5, %mapv6 : !llvm.ptr, !llvm.ptr, !llvm.ptr){}2921 2922 return2923}2924 2925// CHECK-LABEL: parallel_op_privatizers2926// CHECK-SAME: (%[[ARG0:[^[:space:]]+]]: !llvm.ptr, %[[ARG1:[^[:space:]]+]]: !llvm.ptr)2927func.func @parallel_op_privatizers(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {2928 // CHECK: omp.parallel private(2929 // CHECK-SAME: @x.privatizer %[[ARG0]] -> %[[ARG0_PRIV:[^[:space:]]+]],2930 // CHECK-SAME: @y.privatizer %[[ARG1]] -> %[[ARG1_PRIV:[^[:space:]]+]] : !llvm.ptr, !llvm.ptr)2931 omp.parallel private(@x.privatizer %arg0 -> %arg2, @y.privatizer %arg1 -> %arg3 : !llvm.ptr, !llvm.ptr) {2932 // CHECK: llvm.load %[[ARG0_PRIV]]2933 %0 = llvm.load %arg2 : !llvm.ptr -> i322934 // CHECK: llvm.load %[[ARG1_PRIV]]2935 %1 = llvm.load %arg3 : !llvm.ptr -> i322936 omp.terminator2937 }2938 return2939}2940 2941// CHECK-LABEL: parallel_op_privatizers_barrier2942// CHECK-SAME: (%[[ARG0:[^[:space:]]+]]: !llvm.ptr, %[[ARG1:[^[:space:]]+]]: !llvm.ptr)2943func.func @parallel_op_privatizers_barrier(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {2944 // CHECK: omp.parallel private(2945 // CHECK-SAME: @x.privatizer %[[ARG0]] -> %[[ARG0_PRIV:[^[:space:]]+]],2946 // CHECK-SAME: @y.privatizer %[[ARG1]] -> %[[ARG1_PRIV:[^[:space:]]+]] : !llvm.ptr, !llvm.ptr)2947 // CHECK-SAME: private_barrier2948 omp.parallel private(@x.privatizer %arg0 -> %arg2, @y.privatizer %arg1 -> %arg3 : !llvm.ptr, !llvm.ptr) private_barrier {2949 // CHECK: llvm.load %[[ARG0_PRIV]]2950 %0 = llvm.load %arg2 : !llvm.ptr -> i322951 // CHECK: llvm.load %[[ARG1_PRIV]]2952 %1 = llvm.load %arg3 : !llvm.ptr -> i322953 omp.terminator2954 }2955 return2956}2957 2958// CHECK-LABEL: omp.private {type = private} @a.privatizer : !llvm.ptr init {2959omp.private {type = private} @a.privatizer : !llvm.ptr init {2960// CHECK: ^bb0(%{{.*}}: {{.*}}, %{{.*}}: {{.*}}):2961^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):2962 omp.yield(%arg0 : !llvm.ptr)2963}2964 2965// CHECK-LABEL: omp.private {type = private} @x.privatizer : !llvm.ptr init {2966omp.private {type = private} @x.privatizer : !llvm.ptr init {2967// CHECK: ^bb0(%{{.*}}: {{.*}}, %{{.*}}: {{.*}}):2968^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):2969 omp.yield(%arg0 : !llvm.ptr)2970// CHECK: } dealloc {2971} dealloc {2972// CHECK: ^bb0(%{{.*}}: {{.*}}):2973^bb0(%arg0: !llvm.ptr):2974 omp.yield2975}2976 2977// CHECK-LABEL: omp.private {type = firstprivate} @y.privatizer : !llvm.ptr copy {2978omp.private {type = firstprivate} @y.privatizer : !llvm.ptr copy {2979// CHECK: ^bb0(%{{.*}}: {{.*}}, %{{.*}}: {{.*}}):2980^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):2981 omp.yield(%arg0 : !llvm.ptr)2982// CHECK: } dealloc {2983} dealloc {2984// CHECK: ^bb0(%{{.*}}: {{.*}}):2985^bb0(%arg0: !llvm.ptr):2986 omp.yield2987}2988 2989// CHECK-LABEL: parallel_op_reduction_and_private2990func.func @parallel_op_reduction_and_private(%priv_var: !llvm.ptr, %priv_var2: !llvm.ptr, %reduc_var: !llvm.ptr, %reduc_var2: !llvm.ptr) {2991 // CHECK: omp.parallel2992 // CHECK-SAME: private(2993 // CHECK-SAME: @x.privatizer %[[PRIV_VAR:[^[:space:]]+]] -> %[[PRIV_ARG:[^[:space:]]+]],2994 // CHECK-SAME: @y.privatizer %[[PRIV_VAR2:[^[:space:]]+]] -> %[[PRIV_ARG2:[^[:space:]]+]] : !llvm.ptr, !llvm.ptr)2995 //2996 // CHECK-SAME: reduction(2997 // CHECK-SAME: @add_f32 %[[REDUC_VAR:[^[:space:]]+]] -> %[[REDUC_ARG:[^[:space:]]+]],2998 // CHECK-SAME: @add_f32 %[[REDUC_VAR2:[^[:space:]]+]] -> %[[REDUC_ARG2:[^[:space:]]+]] : !llvm.ptr, !llvm.ptr)2999 omp.parallel private(@x.privatizer %priv_var -> %priv_arg, @y.privatizer %priv_var2 -> %priv_arg2 : !llvm.ptr, !llvm.ptr)3000 reduction(@add_f32 %reduc_var -> %reduc_arg, @add_f32 %reduc_var2 -> %reduc_arg2 : !llvm.ptr, !llvm.ptr) {3001 // CHECK: llvm.load %[[PRIV_ARG]]3002 %0 = llvm.load %priv_arg : !llvm.ptr -> f323003 // CHECK: llvm.load %[[PRIV_ARG2]]3004 %1 = llvm.load %priv_arg2 : !llvm.ptr -> f323005 // CHECK: llvm.load %[[REDUC_ARG]]3006 %2 = llvm.load %reduc_arg : !llvm.ptr -> f323007 // CHECK: llvm.load %[[REDUC_ARG2]]3008 %3 = llvm.load %reduc_arg2 : !llvm.ptr -> f323009 omp.terminator3010 }3011 return3012}3013 3014// CHECK-LABEL: omp_target_private3015func.func @omp_target_private(%map1: memref<?xi32>, %map2: memref<?xi32>, %priv_var: !llvm.ptr) -> () {3016 %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}3017 %mapv2 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}3018 3019 // CHECK: omp.target3020 // CHECK-SAME: private(3021 // CHECK-SAME: @x.privatizer %{{[^[:space:]]+}} -> %[[PRIV_ARG:[^[:space:]]+]]3022 // CHECK-SAME: : !llvm.ptr3023 // CHECK-SAME: )3024 omp.target private(@x.privatizer %priv_var -> %priv_arg : !llvm.ptr) {3025 omp.terminator3026 }3027 3028 // CHECK: omp.target3029 3030 // CHECK-SAME: map_entries(3031 // CHECK-SAME: %{{[^[:space:]]+}} -> %[[MAP1_ARG:[^[:space:]]+]],3032 // CHECK-SAME: %{{[^[:space:]]+}} -> %[[MAP2_ARG:[^[:space:]]+]]3033 // CHECK-SAME: : memref<?xi32>, memref<?xi32>3034 // CHECK-SAME: )3035 3036 // CHECK-SAME: private(3037 // CHECK-SAME: @x.privatizer %{{[^[:space:]]+}} -> %[[PRIV_ARG:[^[:space:]]+]]3038 // CHECK-SAME: : !llvm.ptr3039 // CHECK-SAME: )3040 omp.target map_entries(%mapv1 -> %arg0, %mapv2 -> %arg1 : memref<?xi32>, memref<?xi32>) private(@x.privatizer %priv_var -> %priv_arg : !llvm.ptr) {3041 omp.terminator3042 }3043 3044 return3045}3046 3047// CHECK-LABEL: omp_target_private_with_map_idx3048func.func @omp_target_private_with_map_idx(%map1: memref<?xi32>, %map2: memref<?xi32>, %priv_var: !llvm.ptr) -> () {3049 %mapv1 = omp.map.info var_ptr(%map1 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}3050 %mapv2 = omp.map.info var_ptr(%map2 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}3051 3052 // CHECK: omp.target3053 3054 // CHECK-SAME: map_entries(3055 // CHECK-SAME: %{{[^[:space:]]+}} -> %[[MAP1_ARG:[^[:space:]]+]],3056 // CHECK-SAME: %{{[^[:space:]]+}} -> %[[MAP2_ARG:[^[:space:]]+]]3057 // CHECK-SAME: : memref<?xi32>, memref<?xi32>3058 // CHECK-SAME: )3059 3060 // CHECK-SAME: private(3061 // CHECK-SAME: @x.privatizer %{{[^[:space:]]+}} -> %[[PRIV_ARG:[^[:space:]]+]] [map_idx=1]3062 // CHECK-SAME: : !llvm.ptr3063 // CHECK-SAME: )3064 omp.target map_entries(%mapv1 -> %arg0, %mapv2 -> %arg1 : memref<?xi32>, memref<?xi32>) private(@x.privatizer %priv_var -> %priv_arg [map_idx=1] : !llvm.ptr) {3065 omp.terminator3066 }3067 3068 return3069}3070 3071func.func @omp_target_host_eval(%x : i32) {3072 // CHECK: omp.target host_eval(%{{.*}} -> %[[HOST_ARG:.*]] : i32) {3073 // CHECK: omp.teams num_teams( to %[[HOST_ARG]] : i32)3074 // CHECK-SAME: thread_limit(%[[HOST_ARG]] : i32)3075 omp.target host_eval(%x -> %arg0 : i32) {3076 omp.teams num_teams(to %arg0 : i32) thread_limit(%arg0 : i32) {3077 omp.terminator3078 }3079 omp.terminator3080 }3081 3082 // CHECK: omp.target host_eval(%{{.*}} -> %[[HOST_ARG:.*]] : i32) {3083 // CHECK: omp.teams {3084 // CHECK: omp.parallel num_threads(%[[HOST_ARG]] : i32) {3085 // CHECK: omp.distribute {3086 // CHECK: omp.wsloop {3087 // CHECK: omp.loop_nest (%{{.*}}) : i32 = (%[[HOST_ARG]]) to (%[[HOST_ARG]]) step (%[[HOST_ARG]]) {3088 omp.target host_eval(%x -> %arg0 : i32) {3089 omp.teams {3090 omp.parallel num_threads(%arg0 : i32) {3091 omp.distribute {3092 omp.wsloop {3093 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {3094 omp.yield3095 }3096 } {omp.composite}3097 } {omp.composite}3098 omp.terminator3099 } {omp.composite}3100 omp.terminator3101 }3102 omp.terminator3103 }3104 3105 // CHECK: omp.target host_eval(%{{.*}} -> %[[HOST_ARG:.*]] : i32) {3106 // CHECK: omp.parallel num_threads(%[[HOST_ARG]] : i32) {3107 // CHECK: omp.wsloop {3108 // CHECK: omp.loop_nest3109 omp.target host_eval(%x -> %arg0 : i32) {3110 %y = arith.constant 2 : i323111 omp.parallel num_threads(%arg0 : i32) {3112 omp.wsloop {3113 omp.loop_nest (%iv) : i32 = (%y) to (%y) step (%y) {3114 omp.yield3115 }3116 }3117 omp.terminator3118 }3119 omp.terminator3120 }3121 3122 // CHECK: omp.target host_eval(%{{.*}} -> %[[HOST_ARG:.*]] : i32) {3123 // CHECK: omp.teams {3124 // CHECK: omp.distribute {3125 // CHECK: omp.loop_nest (%{{.*}}) : i32 = (%[[HOST_ARG]]) to (%[[HOST_ARG]]) step (%[[HOST_ARG]]) {3126 omp.target host_eval(%x -> %arg0 : i32) {3127 omp.teams {3128 omp.distribute {3129 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {3130 omp.yield3131 }3132 }3133 omp.terminator3134 }3135 omp.terminator3136 }3137 3138 // CHECK: omp.target host_eval(%{{.*}} -> %[[HOST_ARG:.*]] : i32) {3139 // CHECK: omp.teams {3140 // CHECK: omp.loop {3141 // CHECK: omp.loop_nest (%{{.*}}) : i32 = (%[[HOST_ARG]]) to (%[[HOST_ARG]]) step (%[[HOST_ARG]]) {3142 omp.target host_eval(%x -> %arg0 : i32) {3143 omp.teams {3144 omp.loop {3145 omp.loop_nest (%iv) : i32 = (%arg0) to (%arg0) step (%arg0) {3146 omp.yield3147 }3148 }3149 omp.terminator3150 }3151 omp.terminator3152 }3153 return3154}3155 3156// CHECK-LABEL: omp_loop3157func.func @omp_loop(%lb : index, %ub : index, %step : index) {3158 // CHECK: omp.loop {3159 omp.loop {3160 // CHECK: omp.loop_nest {{.*}} {3161 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {3162 // CHECK: omp.yield3163 omp.yield3164 }3165 // CHECK: }3166 }3167 // CHECK: }3168 3169 // CHECK: omp.loop bind(teams) {3170 omp.loop bind(teams) {3171 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {3172 omp.yield3173 }3174 }3175 // CHECK: }3176 3177 // CHECK: omp.loop bind(parallel) {3178 omp.loop bind(parallel) {3179 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {3180 omp.yield3181 }3182 }3183 // CHECK: }3184 3185 // CHECK: omp.loop bind(thread) {3186 omp.loop bind(thread) {3187 omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {3188 omp.yield3189 }3190 }3191 // CHECK: }3192 3193 return3194}3195 3196// CHECK-LABEL: func @omp_workshare3197func.func @omp_workshare() {3198 // CHECK: omp.workshare {3199 omp.workshare {3200 "test.payload"() : () -> ()3201 // CHECK: omp.terminator3202 omp.terminator3203 }3204 return3205}3206 3207// CHECK-LABEL: func @omp_workshare_nowait3208func.func @omp_workshare_nowait() {3209 // CHECK: omp.workshare nowait {3210 omp.workshare nowait {3211 "test.payload"() : () -> ()3212 // CHECK: omp.terminator3213 omp.terminator3214 }3215 return3216}3217 3218// CHECK-LABEL: func @omp_workshare_multiple_blocks3219func.func @omp_workshare_multiple_blocks() {3220 // CHECK: omp.workshare {3221 omp.workshare {3222 cf.br ^bb23223 ^bb2:3224 // CHECK: omp.terminator3225 omp.terminator3226 }3227 return3228}3229 3230// CHECK-LABEL: func @omp_workshare_loop_wrapper3231func.func @omp_workshare_loop_wrapper(%idx : index) {3232 // CHECK-NEXT: omp.workshare {3233 omp.workshare {3234 // CHECK-NEXT: omp.workshare.loop_wrapper3235 omp.workshare.loop_wrapper {3236 // CHECK-NEXT: omp.loop_nest3237 omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {3238 omp.yield3239 }3240 }3241 omp.terminator3242 }3243 return3244}3245 3246// CHECK-LABEL: func @omp_workshare_loop_wrapper_attrs3247func.func @omp_workshare_loop_wrapper_attrs(%idx : index) {3248 // CHECK-NEXT: omp.workshare {3249 omp.workshare {3250 // CHECK-NEXT: omp.workshare.loop_wrapper {3251 omp.workshare.loop_wrapper {3252 // CHECK-NEXT: omp.loop_nest3253 omp.loop_nest (%iv) : index = (%idx) to (%idx) step (%idx) {3254 omp.yield3255 }3256 // CHECK: } {attr_in_dict}3257 } {attr_in_dict}3258 omp.terminator3259 }3260 return3261}3262 3263func.func @omp_init_allocator(%custom_allocator : i64) -> i64 {3264 return %custom_allocator : i643265}3266 3267// CHECK-LABEL: func.func @omp_allocate_dir(3268// CHECK-SAME: %[[ARG0:.*]]: memref<i32>,3269// CHECK-SAME: %[[ARG1:.*]]: memref<i32>) {3270func.func @omp_allocate_dir(%arg0 : memref<i32>, %arg1 : memref<i32>) -> () {3271 3272 // Test with one data var3273 // CHECK: omp.allocate_dir(%[[ARG0]] : memref<i32>)3274 omp.allocate_dir (%arg0 : memref<i32>)3275 3276 // Test with two data vars3277 // CHECK: omp.allocate_dir(%[[ARG0]], %[[ARG1]] : memref<i32>, memref<i32>)3278 omp.allocate_dir (%arg0, %arg1: memref<i32>, memref<i32>)3279 3280 // Test with one data var and align clause3281 // CHECK: omp.allocate_dir(%[[ARG0]] : memref<i32>) align(2)3282 omp.allocate_dir (%arg0 : memref<i32>) align(2)3283 3284 // Test with one data var and allocator clause3285 // CHECK: %[[VAL_1:.*]] = arith.constant 1 : i643286 %omp_default_mem_alloc = arith.constant 1 : i643287 // CHECK: omp.allocate_dir(%[[ARG0]] : memref<i32>) allocator(%[[VAL_1:.*]])3288 omp.allocate_dir (%arg0 : memref<i32>) allocator(%omp_default_mem_alloc)3289 3290 // Test with one data var, align clause and allocator clause3291 // CHECK: %[[VAL_2:.*]] = arith.constant 7 : i643292 %omp_pteam_mem_alloc = arith.constant 7 : i643293 // CHECK: omp.allocate_dir(%[[ARG0]] : memref<i32>) align(4) allocator(%[[VAL_2:.*]])3294 omp.allocate_dir (%arg0 : memref<i32>) align(4) allocator(%omp_pteam_mem_alloc)3295 3296 // Test with two data vars, align clause and allocator clause3297 // CHECK: %[[VAL_3:.*]] = arith.constant 6 : i643298 %omp_cgroup_mem_alloc = arith.constant 6 : i643299 // CHECK: omp.allocate_dir(%[[ARG0]], %[[ARG1]] : memref<i32>, memref<i32>) align(8) allocator(%[[VAL_3:.*]])3300 omp.allocate_dir (%arg0, %arg1 : memref<i32>, memref<i32>) align(8) allocator(%omp_cgroup_mem_alloc)3301 3302 // Test with one data var and user defined allocator clause3303 // CHECK: %[[VAL_4:.*]] = arith.constant 9 : i643304 %custom_allocator = arith.constant 9 : i643305 %custom_mem_alloc = func.call @omp_init_allocator(%custom_allocator) : (i64) -> (i64)3306 // CHECK: omp.allocate_dir(%[[ARG0]] : memref<i32>) allocator(%[[VAL_5:.*]])3307 omp.allocate_dir (%arg0 : memref<i32>) allocator(%custom_mem_alloc)3308 3309 return3310}3311 3312// CHECK-LABEL: func.func @omp_workdistribute3313func.func @omp_workdistribute() {3314 // CHECK: omp.teams3315 omp.teams {3316 // CHECK: omp.workdistribute3317 omp.workdistribute {3318 omp.terminator3319 }3320 omp.terminator3321 }3322 return3323}3324 3325func.func @omp_target_map_clause_type_test(%arg0 : memref<?xi32>) -> () {3326 // Test new map clause additions3327 // CHECK: %{{.*}}map_clauses(none){{.*}}3328 // CHECK: %{{.*}}map_clauses(to){{.*}}3329 // CHECK: %{{.*}}map_clauses(from){{.*}}3330 // CHECK: %{{.*}}map_clauses(tofrom){{.*}}3331 // CHECK: %{{.*}}map_clauses(storage){{.*}}3332 // CHECK: %{{.*}}map_clauses(delete){{.*}}3333 // CHECK: %{{.*}}map_clauses(return_param){{.*}}3334 // CHECK: %{{.*}}map_clauses(private){{.*}}3335 // CHECK: %{{.*}}map_clauses(literal){{.*}}3336 // CHECK: %{{.*}}map_clauses(implicit){{.*}}3337 // CHECK: %{{.*}}map_clauses(close){{.*}}3338 // CHECK: %{{.*}}map_clauses(present){{.*}}3339 // CHECK: %{{.*}}map_clauses(ompx_hold){{.*}}3340 // CHECK: %{{.*}}map_clauses(attach){{.*}}3341 // CHECK: %{{.*}}map_clauses(attach_always){{.*}}3342 // CHECK: %{{.*}}map_clauses(attach_none){{.*}}3343 // CHECK: %{{.*}}map_clauses(attach_auto){{.*}}3344 // CHECK: %{{.*}}map_clauses(ref_ptr){{.*}}3345 // CHECK: %{{.*}}map_clauses(ref_ptee){{.*}}3346 // CHECK: %{{.*}}map_clauses(ref_ptr_ptee){{.*}}3347 %mapv0 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(none) capture(ByRef) -> memref<?xi32> {name = ""}3348 %mapv1 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(to) capture(ByRef) -> memref<?xi32> {name = ""}3349 %mapv2 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(from) capture(ByRef) -> memref<?xi32> {name = ""}3350 %mapv3 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(tofrom) capture(ByRef) -> memref<?xi32> {name = ""}3351 %mapv4 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(storage) capture(ByRef) -> memref<?xi32> {name = ""}3352 %mapv5 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(delete) capture(ByRef) -> memref<?xi32> {name = ""}3353 %mapv6 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(return_param) capture(ByRef) -> memref<?xi32> {name = ""}3354 %mapv7 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(private) capture(ByRef) -> memref<?xi32> {name = ""}3355 %mapv8 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(literal) capture(ByRef) -> memref<?xi32> {name = ""}3356 %mapv9 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(implicit) capture(ByRef) -> memref<?xi32> {name = ""}3357 %mapv10 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(close) capture(ByRef) -> memref<?xi32> {name = ""}3358 %mapv11 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(present) capture(ByRef) -> memref<?xi32> {name = ""}3359 %mapv12 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(ompx_hold) capture(ByRef) -> memref<?xi32> {name = ""}3360 %mapv13 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(attach) capture(ByRef) -> memref<?xi32> {name = ""}3361 %mapv14 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(attach_always) capture(ByRef) -> memref<?xi32> {name = ""}3362 %mapv15 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(attach_none) capture(ByRef) -> memref<?xi32> {name = ""}3363 %mapv16 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(attach_auto) capture(ByRef) -> memref<?xi32> {name = ""}3364 %mapv17 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(ref_ptr) capture(ByRef) -> memref<?xi32> {name = ""}3365 %mapv18 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(ref_ptee) capture(ByRef) -> memref<?xi32> {name = ""}3366 %mapv19 = omp.map.info var_ptr(%arg0 : memref<?xi32>, tensor<?xi32>) map_clauses(ref_ptr_ptee) capture(ByRef) -> memref<?xi32> {name = ""}3367 3368 return3369}3370