1// RUN: mlir-opt -split-input-file -verify-diagnostics %s 2 3func.func @unknown_clause() { 4 // expected-error@+1 {{expected '{' to begin a region}} 5 omp.parallel invalid { 6 } 7 8 return 9} 10 11// ----- 12 13func.func @if_once(%n : i1) { 14 // expected-error@+1 {{`if` clause can appear at most once in the expansion of the oilist directive}} 15 omp.parallel if(%n : i1) if(%n : i1) { 16 } 17 18 return 19} 20 21// ----- 22 23func.func @num_threads_once(%n : si32) { 24 // expected-error@+1 {{`num_threads` clause can appear at most once in the expansion of the oilist directive}} 25 omp.parallel num_threads(%n : si32) num_threads(%n : si32) { 26 } 27 28 return 29} 30 31// ----- 32 33func.func @nowait_not_allowed(%n : memref<i32>) { 34 // expected-error@+1 {{expected '{' to begin a region}} 35 omp.parallel nowait {} 36 return 37} 38 39// ----- 40 41func.func @linear_not_allowed(%data_var : memref<i32>, %linear_var : i32) { 42 // expected-error@+1 {{expected '{' to begin a region}} 43 omp.parallel linear(%data_var = %linear_var : memref<i32>) {} 44 return 45} 46 47// ----- 48 49func.func @schedule_not_allowed() { 50 // expected-error@+1 {{expected '{' to begin a region}} 51 omp.parallel schedule(static) {} 52 return 53} 54 55// ----- 56 57func.func @collapse_not_allowed() { 58 // expected-error@+1 {{expected '{' to begin a region}} 59 omp.parallel collapse(3) {} 60 return 61} 62 63// ----- 64 65func.func @order_not_allowed() { 66 // expected-error@+1 {{expected '{' to begin a region}} 67 omp.parallel order(concurrent) {} 68 return 69} 70 71// ----- 72 73func.func @ordered_not_allowed() { 74 // expected-error@+1 {{expected '{' to begin a region}} 75 omp.parallel ordered(2) {} 76} 77 78// ----- 79 80func.func @proc_bind_once() { 81 // expected-error@+1 {{`proc_bind` clause can appear at most once in the expansion of the oilist directive}} 82 omp.parallel proc_bind(close) proc_bind(spread) { 83 } 84 85 return 86} 87 88// ----- 89 90func.func @inclusive_not_a_clause(%lb : index, %ub : index, %step : index) { 91 // expected-error @below {{expected 'for'}} 92 omp.wsloop nowait inclusive 93 for (%iv) : index = (%lb) to (%ub) step (%step) { 94 omp.yield 95 } 96} 97 98// ----- 99 100func.func @order_value(%lb : index, %ub : index, %step : index) { 101 // expected-error @below {{invalid clause value: 'default'}} 102 omp.wsloop order(default) 103 for (%iv) : index = (%lb) to (%ub) step (%step) { 104 omp.yield 105 } 106} 107 108// ----- 109 110func.func @if_not_allowed(%lb : index, %ub : index, %step : index, %bool_var : i1) { 111 // expected-error @below {{expected 'for'}} 112 omp.wsloop if(%bool_var: i1) 113 for (%iv) : index = (%lb) to (%ub) step (%step) { 114 omp.yield 115 } 116} 117 118// ----- 119 120func.func @num_threads_not_allowed(%lb : index, %ub : index, %step : index, %int_var : i32) { 121 // expected-error @below {{expected 'for'}} 122 omp.wsloop num_threads(%int_var: i32) 123 for (%iv) : index = (%lb) to (%ub) step (%step) { 124 omp.yield 125 } 126} 127 128// ----- 129 130func.func @proc_bind_not_allowed(%lb : index, %ub : index, %step : index) { 131 // expected-error @below {{expected 'for'}} 132 omp.wsloop proc_bind(close) 133 for (%iv) : index = (%lb) to (%ub) step (%step) { 134 omp.yield 135 } 136} 137 138// ----- 139 140llvm.func @test_omp_wsloop_dynamic_bad_modifier(%lb : i64, %ub : i64, %step : i64) -> () { 141 // expected-error @+1 {{unknown modifier type: ginandtonic}} 142 omp.wsloop schedule(dynamic, ginandtonic) 143 for (%iv) : i64 = (%lb) to (%ub) step (%step) { 144 omp.yield 145 } 146 llvm.return 147} 148 149// ----- 150 151llvm.func @test_omp_wsloop_dynamic_many_modifier(%lb : i64, %ub : i64, %step : i64) -> () { 152 // expected-error @+1 {{unexpected modifier(s)}} 153 omp.wsloop schedule(dynamic, monotonic, monotonic, monotonic) 154 for (%iv) : i64 = (%lb) to (%ub) step (%step) { 155 omp.yield 156 } 157 llvm.return 158} 159 160// ----- 161 162llvm.func @test_omp_wsloop_dynamic_wrong_modifier(%lb : i64, %ub : i64, %step : i64) -> () { 163 // expected-error @+1 {{incorrect modifier order}} 164 omp.wsloop schedule(dynamic, simd, monotonic) 165 for (%iv) : i64 = (%lb) to (%ub) step (%step) { 166 omp.yield 167 } 168 llvm.return 169} 170 171// ----- 172 173llvm.func @test_omp_wsloop_dynamic_wrong_modifier2(%lb : i64, %ub : i64, %step : i64) -> () { 174 // expected-error @+1 {{incorrect modifier order}} 175 omp.wsloop schedule(dynamic, monotonic, monotonic) 176 for (%iv) : i64 = (%lb) to (%ub) step (%step) { 177 omp.yield 178 } 179 llvm.return 180} 181 182// ----- 183 184llvm.func @test_omp_wsloop_dynamic_wrong_modifier3(%lb : i64, %ub : i64, %step : i64) -> () { 185 // expected-error @+1 {{incorrect modifier order}} 186 omp.wsloop schedule(dynamic, simd, simd) 187 for (%iv) : i64 = (%lb) to (%ub) step (%step) { 188 omp.yield 189 } 190 llvm.return 191} 192 193// ----- 194 195func.func @omp_simdloop(%lb : index, %ub : index, %step : i32) -> () { 196 // expected-error @below {{op failed to verify that all of {lowerBound, upperBound, step} have same type}} 197 "omp.simdloop" (%lb, %ub, %step) ({ 198 ^bb0(%iv: index): 199 omp.yield 200 }) {operand_segment_sizes = dense<[1,1,1]> : vector<3xi32>} : 201 (index, index, i32) -> () 202 203 return 204} 205 206// ----- 207 208// expected-error @below {{op expects initializer region with one argument of the reduction type}} 209omp.reduction.declare @add_f32 : f64 210init { 211^bb0(%arg: f32): 212 %0 = arith.constant 0.0 : f32 213 omp.yield (%0 : f32) 214} 215combiner { 216^bb1(%arg0: f32, %arg1: f32): 217 %1 = arith.addf %arg0, %arg1 : f32 218 omp.yield (%1 : f32) 219} 220 221// ----- 222 223// expected-error @below {{expects initializer region to yield a value of the reduction type}} 224omp.reduction.declare @add_f32 : f32 225init { 226^bb0(%arg: f32): 227 %0 = arith.constant 0.0 : f64 228 omp.yield (%0 : f64) 229} 230combiner { 231^bb1(%arg0: f32, %arg1: f32): 232 %1 = arith.addf %arg0, %arg1 : f32 233 omp.yield (%1 : f32) 234} 235 236// ----- 237 238// expected-error @below {{expects reduction region with two arguments of the reduction type}} 239omp.reduction.declare @add_f32 : f32 240init { 241^bb0(%arg: f32): 242 %0 = arith.constant 0.0 : f32 243 omp.yield (%0 : f32) 244} 245combiner { 246^bb1(%arg0: f64, %arg1: f64): 247 %1 = arith.addf %arg0, %arg1 : f64 248 omp.yield (%1 : f64) 249} 250 251// ----- 252 253// expected-error @below {{expects reduction region to yield a value of the reduction type}} 254omp.reduction.declare @add_f32 : f32 255init { 256^bb0(%arg: f32): 257 %0 = arith.constant 0.0 : f32 258 omp.yield (%0 : f32) 259} 260combiner { 261^bb1(%arg0: f32, %arg1: f32): 262 %1 = arith.addf %arg0, %arg1 : f32 263 %2 = arith.extf %1 : f32 to f64 264 omp.yield (%2 : f64) 265} 266 267// ----- 268 269// expected-error @below {{expects atomic reduction region with two arguments of the same type}} 270omp.reduction.declare @add_f32 : f32 271init { 272^bb0(%arg: f32): 273 %0 = arith.constant 0.0 : f32 274 omp.yield (%0 : f32) 275} 276combiner { 277^bb1(%arg0: f32, %arg1: f32): 278 %1 = arith.addf %arg0, %arg1 : f32 279 omp.yield (%1 : f32) 280} 281atomic { 282^bb2(%arg0: memref<f32>, %arg1: memref<f64>): 283 omp.yield 284} 285 286// ----- 287 288// expected-error @below {{expects atomic reduction region arguments to be accumulators containing the reduction type}} 289omp.reduction.declare @add_f32 : f32 290init { 291^bb0(%arg: f32): 292 %0 = arith.constant 0.0 : f32 293 omp.yield (%0 : f32) 294} 295combiner { 296^bb1(%arg0: f32, %arg1: f32): 297 %1 = arith.addf %arg0, %arg1 : f32 298 omp.yield (%1 : f32) 299} 300atomic { 301^bb2(%arg0: memref<f64>, %arg1: memref<f64>): 302 omp.yield 303} 304 305// ----- 306 307omp.reduction.declare @add_f32 : f32 308init { 309^bb0(%arg: f32): 310 %0 = arith.constant 0.0 : f32 311 omp.yield (%0 : f32) 312} 313combiner { 314^bb1(%arg0: f32, %arg1: f32): 315 %1 = arith.addf %arg0, %arg1 : f32 316 omp.yield (%1 : f32) 317} 318 319func.func @foo(%lb : index, %ub : index, %step : index) { 320 %c1 = arith.constant 1 : i32 321 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<f32> 322 %1 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<f32> 323 324 omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr<f32>) 325 for (%iv) : index = (%lb) to (%ub) step (%step) { 326 %2 = arith.constant 2.0 : f32 327 // expected-error @below {{accumulator is not used by the parent}} 328 omp.reduction %2, %1 : !llvm.ptr<f32> 329 omp.yield 330 } 331 return 332} 333 334// ----- 335 336func.func @foo(%lb : index, %ub : index, %step : index) { 337 %c1 = arith.constant 1 : i32 338 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<f32> 339 %1 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<f32> 340 341 // expected-error @below {{expected symbol reference @foo to point to a reduction declaration}} 342 omp.wsloop reduction(@foo -> %0 : !llvm.ptr<f32>) 343 for (%iv) : index = (%lb) to (%ub) step (%step) { 344 %2 = arith.constant 2.0 : f32 345 omp.reduction %2, %1 : !llvm.ptr<f32> 346 omp.yield 347 } 348 return 349} 350 351// ----- 352 353omp.reduction.declare @add_f32 : f32 354init { 355^bb0(%arg: f32): 356 %0 = arith.constant 0.0 : f32 357 omp.yield (%0 : f32) 358} 359combiner { 360^bb1(%arg0: f32, %arg1: f32): 361 %1 = arith.addf %arg0, %arg1 : f32 362 omp.yield (%1 : f32) 363} 364 365func.func @foo(%lb : index, %ub : index, %step : index) { 366 %c1 = arith.constant 1 : i32 367 %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr<f32> 368 369 // expected-error @below {{accumulator variable used more than once}} 370 omp.wsloop reduction(@add_f32 -> %0 : !llvm.ptr<f32>, @add_f32 -> %0 : !llvm.ptr<f32>) 371 for (%iv) : index = (%lb) to (%ub) step (%step) { 372 %2 = arith.constant 2.0 : f32 373 omp.reduction %2, %0 : !llvm.ptr<f32> 374 omp.yield 375 } 376 return 377} 378 379// ----- 380 381omp.reduction.declare @add_f32 : f32 382init { 383^bb0(%arg: f32): 384 %0 = arith.constant 0.0 : f32 385 omp.yield (%0 : f32) 386} 387combiner { 388^bb1(%arg0: f32, %arg1: f32): 389 %1 = arith.addf %arg0, %arg1 : f32 390 omp.yield (%1 : f32) 391} 392atomic { 393^bb2(%arg2: !llvm.ptr<f32>, %arg3: !llvm.ptr<f32>): 394 %2 = llvm.load %arg3 : !llvm.ptr<f32> 395 llvm.atomicrmw fadd %arg2, %2 monotonic : f32 396 omp.yield 397} 398 399func.func @foo(%lb : index, %ub : index, %step : index, %mem : memref<1xf32>) { 400 %c1 = arith.constant 1 : i32 401 402 // expected-error @below {{expected accumulator ('memref<1xf32>') to be the same type as reduction declaration ('!llvm.ptr<f32>')}} 403 omp.wsloop reduction(@add_f32 -> %mem : memref<1xf32>) 404 for (%iv) : index = (%lb) to (%ub) step (%step) { 405 %2 = arith.constant 2.0 : f32 406 omp.reduction %2, %mem : memref<1xf32> 407 omp.yield 408 } 409 return 410} 411 412// ----- 413 414func.func @omp_critical2() -> () { 415 // expected-error @below {{expected symbol reference @excl to point to a critical declaration}} 416 omp.critical(@excl) { 417 omp.terminator 418 } 419 return 420} 421 422// ----- 423 424// expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} 425omp.critical.declare @mutex hint(uncontended, contended) 426 427// ----- 428 429// expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined}} 430omp.critical.declare @mutex hint(nonspeculative, speculative) 431 432// ----- 433 434// expected-error @below {{invalid_hint is not a valid hint}} 435omp.critical.declare @mutex hint(invalid_hint) 436 437// ----- 438 439func.func @omp_ordered1(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { 440 omp.wsloop ordered(1) 441 for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 442 // expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}} 443 omp.ordered_region { 444 omp.terminator 445 } 446 omp.yield 447 } 448 return 449} 450 451// ----- 452 453func.func @omp_ordered2(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { 454 omp.wsloop for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 455 // expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}} 456 omp.ordered_region { 457 omp.terminator 458 } 459 omp.yield 460 } 461 return 462} 463 464// ----- 465 466func.func @omp_ordered3(%vec0 : i64) -> () { 467 // expected-error @below {{ordered depend directive must be closely nested inside a worksharing-loop with ordered clause with parameter present}} 468 omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64} 469 return 470} 471 472// ----- 473 474func.func @omp_ordered4(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64) -> () { 475 omp.wsloop ordered(0) 476 for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 477 // expected-error @below {{ordered depend directive must be closely nested inside a worksharing-loop with ordered clause with parameter present}} 478 omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64} 479 480 omp.yield 481 } 482 return 483} 484// ----- 485 486func.func @omp_ordered5(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64, %vec1 : i64) -> () { 487 omp.wsloop ordered(1) 488 for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 489 // expected-error @below {{number of variables in depend clause does not match number of iteration variables in the doacross loop}} 490 omp.ordered depend_type(dependsource) depend_vec(%vec0, %vec1 : i64, i64) {num_loops_val = 2 : i64} 491 492 omp.yield 493 } 494 return 495} 496 497// ----- 498 499func.func @omp_atomic_read1(%x: memref<i32>, %v: memref<i32>) { 500 // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined.}} 501 omp.atomic.read %v = %x hint(speculative, nonspeculative) : memref<i32> 502 return 503} 504 505// ----- 506 507func.func @omp_atomic_read2(%x: memref<i32>, %v: memref<i32>) { 508 // expected-error @below {{invalid clause value: 'xyz'}} 509 omp.atomic.read %v = %x memory_order(xyz) : memref<i32> 510 return 511} 512 513// ----- 514 515func.func @omp_atomic_read3(%x: memref<i32>, %v: memref<i32>) { 516 // expected-error @below {{memory-order must not be acq_rel or release for atomic reads}} 517 omp.atomic.read %v = %x memory_order(acq_rel) : memref<i32> 518 return 519} 520 521// ----- 522 523func.func @omp_atomic_read4(%x: memref<i32>, %v: memref<i32>) { 524 // expected-error @below {{memory-order must not be acq_rel or release for atomic reads}} 525 omp.atomic.read %v = %x memory_order(release) : memref<i32> 526 return 527} 528 529// ----- 530 531func.func @omp_atomic_read5(%x: memref<i32>, %v: memref<i32>) { 532 // expected-error @below {{`memory_order` clause can appear at most once in the expansion of the oilist directive}} 533 omp.atomic.read %v = %x memory_order(acquire) memory_order(relaxed) : memref<i32> 534 return 535} 536 537// ----- 538 539func.func @omp_atomic_read6(%x: memref<i32>, %v: memref<i32>) { 540 // expected-error @below {{`hint` clause can appear at most once in the expansion of the oilist directive}} 541 omp.atomic.read %v = %x hint(speculative) hint(contended) : memref<i32> 542 return 543} 544 545// ----- 546 547func.func @omp_atomic_read6(%x: memref<i32>, %v: memref<i32>) { 548 // expected-error @below {{read and write must not be to the same location for atomic reads}} 549 omp.atomic.read %x = %x hint(speculative) : memref<i32> 550 return 551} 552 553// ----- 554 555func.func @omp_atomic_write1(%addr : memref<i32>, %val : i32) { 556 // expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} 557 omp.atomic.write %addr = %val hint(contended, uncontended) : memref<i32>, i32 558 return 559} 560 561// ----- 562 563func.func @omp_atomic_write2(%addr : memref<i32>, %val : i32) { 564 // expected-error @below {{memory-order must not be acq_rel or acquire for atomic writes}} 565 omp.atomic.write %addr = %val memory_order(acq_rel) : memref<i32>, i32 566 return 567} 568 569// ----- 570 571func.func @omp_atomic_write3(%addr : memref<i32>, %val : i32) { 572 // expected-error @below {{memory-order must not be acq_rel or acquire for atomic writes}} 573 omp.atomic.write %addr = %val memory_order(acquire) : memref<i32>, i32 574 return 575} 576 577// ----- 578 579func.func @omp_atomic_write4(%addr : memref<i32>, %val : i32) { 580 // expected-error @below {{`memory_order` clause can appear at most once in the expansion of the oilist directive}} 581 omp.atomic.write %addr = %val memory_order(release) memory_order(seq_cst) : memref<i32>, i32 582 return 583} 584 585// ----- 586 587func.func @omp_atomic_write5(%addr : memref<i32>, %val : i32) { 588 // expected-error @below {{`hint` clause can appear at most once in the expansion of the oilist directive}} 589 omp.atomic.write %addr = %val hint(contended) hint(speculative) : memref<i32>, i32 590 return 591} 592 593// ----- 594 595func.func @omp_atomic_write6(%addr : memref<i32>, %val : i32) { 596 // expected-error @below {{invalid clause value: 'xyz'}} 597 omp.atomic.write %addr = %val memory_order(xyz) : memref<i32>, i32 598 return 599} 600 601// ----- 602 603func.func @omp_atomic_update1(%x: memref<i32>, %expr: f32) { 604 // expected-error @below {{the type of the operand must be a pointer type whose element type is the same as that of the region argument}} 605 omp.atomic.update %x : memref<i32> { 606 ^bb0(%xval: f32): 607 %newval = llvm.fadd %xval, %expr : f32 608 omp.yield (%newval : f32) 609 } 610 return 611} 612 613// ----- 614 615func.func @omp_atomic_update2(%x: memref<i32>, %expr: i32) { 616 // expected-error @+2 {{op expects regions to end with 'omp.yield', found 'omp.terminator'}} 617 // expected-note @below {{in custom textual format, the absence of terminator implies 'omp.yield'}} 618 omp.atomic.update %x : memref<i32> { 619 ^bb0(%xval: i32): 620 %newval = llvm.add %xval, %expr : i32 621 omp.terminator 622 } 623 return 624} 625 626// ----- 627 628func.func @omp_atomic_update3(%x: memref<i32>, %expr: i32) { 629 // expected-error @below {{memory-order must not be acq_rel or acquire for atomic updates}} 630 omp.atomic.update memory_order(acq_rel) %x : memref<i32> { 631 ^bb0(%xval: i32): 632 %newval = llvm.add %xval, %expr : i32 633 omp.yield (%newval : i32) 634 } 635 return 636} 637 638// ----- 639 640func.func @omp_atomic_update4(%x: memref<i32>, %expr: i32) { 641 // expected-error @below {{memory-order must not be acq_rel or acquire for atomic updates}} 642 omp.atomic.update memory_order(acquire) %x : memref<i32> { 643 ^bb0(%xval: i32): 644 %newval = llvm.add %xval, %expr : i32 645 omp.yield (%newval : i32) 646 } 647 return 648} 649 650// ----- 651 652func.func @omp_atomic_update5(%x: memref<i32>, %expr: i32) { 653 // expected-error @below {{invalid kind of type specified}} 654 omp.atomic.update %x : i32 { 655 ^bb0(%xval: i32): 656 %newval = llvm.add %xval, %expr : i32 657 omp.yield (%newval : i32) 658 } 659 return 660} 661 662// ----- 663 664func.func @omp_atomic_update6(%x: memref<i32>, %expr: i32) { 665 // expected-error @below {{only updated value must be returned}} 666 omp.atomic.update %x : memref<i32> { 667 ^bb0(%xval: i32): 668 %newval = llvm.add %xval, %expr : i32 669 omp.yield (%newval, %expr : i32, i32) 670 } 671 return 672} 673 674// ----- 675 676func.func @omp_atomic_update7(%x: memref<i32>, %expr: i32, %y: f32) { 677 // expected-error @below {{input and yielded value must have the same type}} 678 omp.atomic.update %x : memref<i32> { 679 ^bb0(%xval: i32): 680 %newval = llvm.add %xval, %expr : i32 681 omp.yield (%y: f32) 682 } 683 return 684} 685 686// ----- 687 688func.func @omp_atomic_update8(%x: memref<i32>, %expr: i32) { 689 // expected-error @below {{the region must accept exactly one argument}} 690 omp.atomic.update %x : memref<i32> { 691 ^bb0(%xval: i32, %tmp: i32): 692 %newval = llvm.add %xval, %expr : i32 693 omp.yield (%newval : i32) 694 } 695 return 696} 697 698// ----- 699 700func.func @omp_atomic_update9(%x: memref<i32>, %expr: i32) { 701 // expected-error @below {{the update region must have at least two operations (binop and terminator)}} 702 omp.atomic.update %x : memref<i32> { 703 ^bb0(%xval: i32): 704 omp.yield (%xval : i32) 705 } 706 return 707} 708 709// ----- 710 711func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) { 712 // expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} 713 omp.atomic.update hint(uncontended, contended) %x : memref<i32> { 714 ^bb0(%xval: i32): 715 %newval = llvm.add %xval, %expr : i32 716 omp.yield (%newval : i32) 717 } 718 return 719} 720 721// ----- 722 723func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) { 724 // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined}} 725 omp.atomic.update hint(nonspeculative, speculative) %x : memref<i32> { 726 ^bb0(%xval: i32): 727 %newval = llvm.add %xval, %expr : i32 728 omp.yield (%newval : i32) 729 } 730 return 731} 732 733// ----- 734 735func.func @omp_atomic_update(%x: memref<i32>, %expr: i32) { 736 // expected-error @below {{invalid_hint is not a valid hint}} 737 omp.atomic.update hint(invalid_hint) %x : memref<i32> { 738 ^bb0(%xval: i32): 739 %newval = llvm.add %xval, %expr : i32 740 omp.yield (%newval : i32) 741 } 742 return 743} 744 745// ----- 746 747func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 748 // expected-error @below {{expected three operations in omp.atomic.capture region}} 749 omp.atomic.capture { 750 omp.atomic.read %v = %x : memref<i32> 751 omp.terminator 752 } 753 return 754} 755 756// ----- 757 758func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 759 omp.atomic.capture { 760 // expected-error @below {{invalid sequence of operations in the capture region}} 761 omp.atomic.read %v = %x : memref<i32> 762 omp.atomic.read %v = %x : memref<i32> 763 omp.terminator 764 } 765 return 766} 767 768// ----- 769 770func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 771 omp.atomic.capture { 772 // expected-error @below {{invalid sequence of operations in the capture region}} 773 omp.atomic.update %x : memref<i32> { 774 ^bb0(%xval: i32): 775 %newval = llvm.add %xval, %expr : i32 776 omp.yield (%newval : i32) 777 } 778 omp.atomic.update %x : memref<i32> { 779 ^bb0(%xval: i32): 780 %newval = llvm.add %xval, %expr : i32 781 omp.yield (%newval : i32) 782 } 783 omp.terminator 784 } 785 return 786} 787 788// ----- 789 790func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 791 omp.atomic.capture { 792 // expected-error @below {{invalid sequence of operations in the capture region}} 793 omp.atomic.write %x = %expr : memref<i32>, i32 794 omp.atomic.write %x = %expr : memref<i32>, i32 795 omp.terminator 796 } 797 return 798} 799 800// ----- 801 802func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 803 omp.atomic.capture { 804 // expected-error @below {{invalid sequence of operations in the capture region}} 805 omp.atomic.write %x = %expr : memref<i32>, i32 806 omp.atomic.update %x : memref<i32> { 807 ^bb0(%xval: i32): 808 %newval = llvm.add %xval, %expr : i32 809 omp.yield (%newval : i32) 810 } 811 omp.terminator 812 } 813 return 814} 815 816// ----- 817 818func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 819 omp.atomic.capture { 820 // expected-error @below {{invalid sequence of operations in the capture region}} 821 omp.atomic.update %x : memref<i32> { 822 ^bb0(%xval: i32): 823 %newval = llvm.add %xval, %expr : i32 824 omp.yield (%newval : i32) 825 } 826 omp.atomic.write %x = %expr : memref<i32>, i32 827 omp.terminator 828 } 829 return 830} 831 832// ----- 833 834func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 835 omp.atomic.capture { 836 // expected-error @below {{invalid sequence of operations in the capture region}} 837 omp.atomic.write %x = %expr : memref<i32>, i32 838 omp.atomic.read %v = %x : memref<i32> 839 omp.terminator 840 } 841 return 842} 843 844// ----- 845 846func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) { 847 omp.atomic.capture { 848 // expected-error @below {{updated variable in omp.atomic.update must be captured in second operation}} 849 omp.atomic.update %x : memref<i32> { 850 ^bb0(%xval: i32): 851 %newval = llvm.add %xval, %expr : i32 852 omp.yield (%newval : i32) 853 } 854 omp.atomic.read %v = %y : memref<i32> 855 omp.terminator 856 } 857} 858 859// ----- 860 861func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) { 862 omp.atomic.capture { 863 // expected-error @below {{captured variable in omp.atomic.read must be updated in second operation}} 864 omp.atomic.read %v = %y : memref<i32> 865 omp.atomic.update %x : memref<i32> { 866 ^bb0(%xval: i32): 867 %newval = llvm.add %xval, %expr : i32 868 omp.yield (%newval : i32) 869 } 870 omp.terminator 871 } 872} 873 874// ----- 875 876func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) { 877 omp.atomic.capture { 878 // expected-error @below {{captured variable in omp.atomic.read must be updated in second operation}} 879 omp.atomic.read %v = %x : memref<i32> 880 omp.atomic.write %y = %expr : memref<i32>, i32 881 omp.terminator 882 } 883} 884 885// ----- 886 887func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 888 // expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} 889 omp.atomic.capture hint(contended, uncontended) { 890 omp.atomic.update %x : memref<i32> { 891 ^bb0(%xval: i32): 892 %newval = llvm.add %xval, %expr : i32 893 omp.yield(%newval : i32) 894 } 895 omp.atomic.read %v = %x : memref<i32> 896 } 897 return 898} 899 900// ----- 901 902func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 903 // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined}} 904 omp.atomic.capture hint(nonspeculative, speculative) { 905 omp.atomic.update %x : memref<i32> { 906 ^bb0(%xval: i32): 907 %newval = llvm.add %xval, %expr : i32 908 omp.yield(%newval : i32) 909 } 910 omp.atomic.read %v = %x : memref<i32> 911 } 912 return 913} 914 915// ----- 916 917func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 918 // expected-error @below {{invalid_hint is not a valid hint}} 919 omp.atomic.capture hint(invalid_hint) { 920 omp.atomic.update %x : memref<i32> { 921 ^bb0(%xval: i32): 922 %newval = llvm.add %xval, %expr : i32 923 omp.yield(%newval : i32) 924 } 925 omp.atomic.read %v = %x : memref<i32> 926 } 927 return 928} 929 930// ----- 931 932func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) { 933 // expected-error @below {{operations inside capture region must not have hint clause}} 934 omp.atomic.capture { 935 omp.atomic.update hint(uncontended) %x : memref<i32> { 936 ^bb0(%xval: i32): 937 %newval = llvm.add %xval, %expr : i32 938 omp.yield(%newval : i32) 939 } 940 omp.atomic.read %v = %x : memref<i32> 941 } 942 return 943} 944 945// ----- 946 947func.func @omp_sections(%data_var : memref<i32>) -> () { 948 // expected-error @below {{expected equal sizes for allocate and allocator variables}} 949 "omp.sections" (%data_var) ({ 950 omp.terminator 951 }) {operand_segment_sizes = dense<[0,1,0]> : vector<3xi32>} : (memref<i32>) -> () 952 return 953} 954 955// ----- 956 957func.func @omp_sections(%data_var : memref<i32>) -> () { 958 // expected-error @below {{expected as many reduction symbol references as reduction variables}} 959 "omp.sections" (%data_var) ({ 960 omp.terminator 961 }) {operand_segment_sizes = dense<[1,0,0]> : vector<3xi32>} : (memref<i32>) -> () 962 return 963} 964 965// ----- 966 967func.func @omp_sections(%data_var : memref<i32>) -> () { 968 // expected-error @below {{expected omp.section op or terminator op inside region}} 969 omp.sections { 970 "test.payload" () : () -> () 971 } 972 return 973} 974 975// ----- 976 977func.func @omp_sections(%cond : i1) { 978 // expected-error @below {{expected '{' to begin a region}} 979 omp.sections if(%cond) { 980 omp.terminator 981 } 982 return 983} 984 985// ----- 986 987func.func @omp_sections() { 988 // expected-error @below {{expected '{' to begin a region}} 989 omp.sections num_threads(10) { 990 omp.terminator 991 } 992 return 993} 994 995// ----- 996 997func.func @omp_sections() { 998 // expected-error @below {{expected '{' to begin a region}} 999 omp.sections proc_bind(close) { 1000 omp.terminator 1001 } 1002 return 1003} 1004 1005// ----- 1006 1007func.func @omp_sections(%data_var : memref<i32>, %linear_var : i32) { 1008 // expected-error @below {{expected '{' to begin a region}} 1009 omp.sections linear(%data_var = %linear_var : memref<i32>) { 1010 omp.terminator 1011 } 1012 return 1013} 1014 1015// ----- 1016 1017func.func @omp_sections() { 1018 // expected-error @below {{expected '{' to begin a region}} 1019 omp.sections schedule(static, none) { 1020 omp.terminator 1021 } 1022 return 1023} 1024 1025// ----- 1026 1027func.func @omp_sections() { 1028 // expected-error @below {{expected '{' to begin a region}} 1029 omp.sections collapse(3) { 1030 omp.terminator 1031 } 1032 return 1033} 1034 1035// ----- 1036 1037func.func @omp_sections() { 1038 // expected-error @below {{expected '{' to begin a region}} 1039 omp.sections ordered(2) { 1040 omp.terminator 1041 } 1042 return 1043} 1044 1045// ----- 1046 1047func.func @omp_sections() { 1048 // expected-error @below {{expected '{' to begin a region}} 1049 omp.sections order(concurrent) { 1050 omp.terminator 1051 } 1052 return 1053} 1054 1055// ----- 1056 1057func.func @omp_sections() { 1058 // expected-error @below {{failed to verify constraint: region with 1 blocks}} 1059 omp.sections { 1060 omp.section { 1061 omp.terminator 1062 } 1063 omp.terminator 1064 ^bb2: 1065 omp.terminator 1066 } 1067 return 1068} 1069 1070// ----- 1071 1072func.func @omp_single(%data_var : memref<i32>) -> () { 1073 // expected-error @below {{expected equal sizes for allocate and allocator variables}} 1074 "omp.single" (%data_var) ({ 1075 omp.barrier 1076 }) {operand_segment_sizes = dense<[1,0]> : vector<2xi32>} : (memref<i32>) -> () 1077 return 1078} 1079 1080// ----- 1081 1082func.func @omp_task(%ptr: !llvm.ptr<f32>) { 1083 // expected-error @below {{op expected symbol reference @add_f32 to point to a reduction declaration}} 1084 omp.task in_reduction(@add_f32 -> %ptr : !llvm.ptr<f32>) { 1085 // CHECK: "test.foo"() : () -> () 1086 "test.foo"() : () -> () 1087 // CHECK: omp.terminator 1088 omp.terminator 1089 } 1090} 1091 1092// ----- 1093 1094omp.reduction.declare @add_f32 : f32 1095init { 1096^bb0(%arg: f32): 1097 %0 = arith.constant 0.0 : f32 1098 omp.yield (%0 : f32) 1099} 1100combiner { 1101^bb1(%arg0: f32, %arg1: f32): 1102 %1 = arith.addf %arg0, %arg1 : f32 1103 omp.yield (%1 : f32) 1104} 1105 1106func.func @omp_task(%ptr: !llvm.ptr<f32>) { 1107 // expected-error @below {{op accumulator variable used more than once}} 1108 omp.task in_reduction(@add_f32 -> %ptr : !llvm.ptr<f32>, @add_f32 -> %ptr : !llvm.ptr<f32>) { 1109 // CHECK: "test.foo"() : () -> () 1110 "test.foo"() : () -> () 1111 // CHECK: omp.terminator 1112 omp.terminator 1113 } 1114} 1115 1116// ----- 1117 1118omp.reduction.declare @add_i32 : i32 1119init { 1120^bb0(%arg: i32): 1121 %0 = arith.constant 0 : i32 1122 omp.yield (%0 : i32) 1123} 1124combiner { 1125^bb1(%arg0: i32, %arg1: i32): 1126 %1 = arith.addi %arg0, %arg1 : i32 1127 omp.yield (%1 : i32) 1128} 1129atomic { 1130^bb2(%arg2: !llvm.ptr<i32>, %arg3: !llvm.ptr<i32>): 1131 %2 = llvm.load %arg3 : !llvm.ptr<i32> 1132 llvm.atomicrmw add %arg2, %2 monotonic : i32 1133 omp.yield 1134} 1135 1136func.func @omp_task(%mem: memref<1xf32>) { 1137 // expected-error @below {{op expected accumulator ('memref<1xf32>') to be the same type as reduction declaration ('!llvm.ptr<i32>')}} 1138 omp.task in_reduction(@add_i32 -> %mem : memref<1xf32>) { 1139 // CHECK: "test.foo"() : () -> () 1140 "test.foo"() : () -> () 1141 // CHECK: omp.terminator 1142 omp.terminator 1143 } 1144 return 1145} 1146 1147// ----- 1148 1149func.func @omp_cancel() { 1150 omp.sections { 1151 // expected-error @below {{cancel parallel must appear inside a parallel region}} 1152 omp.cancel cancellation_construct_type(parallel) 1153 // CHECK: omp.terminator 1154 omp.terminator 1155 } 1156 return 1157} 1158 1159// ----- 1160 1161func.func @omp_cancel1() { 1162 omp.parallel { 1163 // expected-error @below {{cancel sections must appear inside a sections region}} 1164 omp.cancel cancellation_construct_type(sections) 1165 // CHECK: omp.terminator 1166 omp.terminator 1167 } 1168 return 1169} 1170 1171// ----- 1172 1173func.func @omp_cancel2() { 1174 omp.sections { 1175 // expected-error @below {{cancel loop must appear inside a worksharing-loop region}} 1176 omp.cancel cancellation_construct_type(loop) 1177 // CHECK: omp.terminator 1178 omp.terminator 1179 } 1180 return 1181} 1182 1183// ----- 1184 1185func.func @omp_cancel3(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { 1186 omp.wsloop nowait 1187 for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 1188 // expected-error @below {{A worksharing construct that is canceled must not have a nowait clause}} 1189 omp.cancel cancellation_construct_type(loop) 1190 // CHECK: omp.terminator 1191 omp.terminator 1192 } 1193 return 1194} 1195 1196// ----- 1197 1198func.func @omp_cancel4(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () { 1199 omp.wsloop ordered(1) 1200 for (%0) : i32 = (%arg1) to (%arg2) step (%arg3) { 1201 // expected-error @below {{A worksharing construct that is canceled must not have an ordered clause}} 1202 omp.cancel cancellation_construct_type(loop) 1203 // CHECK: omp.terminator 1204 omp.terminator 1205 } 1206 return 1207} 1208 1209// ----- 1210 1211func.func @omp_cancel5() -> () { 1212 omp.sections nowait { 1213 omp.section { 1214 // expected-error @below {{A sections construct that is canceled must not have a nowait clause}} 1215 omp.cancel cancellation_construct_type(sections) 1216 omp.terminator 1217 } 1218 // CHECK: omp.terminator 1219 omp.terminator 1220 } 1221 return 1222} 1223 1224// ----- 1225 1226func.func @omp_cancellationpoint() { 1227 omp.sections { 1228 // expected-error @below {{cancellation point parallel must appear inside a parallel region}} 1229 omp.cancellationpoint cancellation_construct_type(parallel) 1230 // CHECK: omp.terminator 1231 omp.terminator 1232 } 1233 return 1234} 1235 1236// ----- 1237 1238func.func @omp_cancellationpoint1() { 1239 omp.parallel { 1240 // expected-error @below {{cancellation point sections must appear inside a sections region}} 1241 omp.cancellationpoint cancellation_construct_type(sections) 1242 // CHECK: omp.terminator 1243 omp.terminator 1244 } 1245 return 1246} 1247 1248// ----- 1249 1250func.func @omp_cancellationpoint2() { 1251 omp.sections { 1252 // expected-error @below {{cancellation point loop must appear inside a worksharing-loop region}} 1253 omp.cancellationpoint cancellation_construct_type(loop) 1254 // CHECK: omp.terminator 1255 omp.terminator 1256 } 1257 return 1258} 1259