1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics 2 3// ----- 4 5func.func @affine_apply_operand_non_index(%arg0 : i32) { 6 // Custom parser automatically assigns all arguments the `index` so we must 7 // use the generic syntax here to exercise the verifier. 8 // expected-error@+1 {{op operand #0 must be variadic of index, but got 'i32'}} 9 %0 = "affine.apply"(%arg0) {map = affine_map<(d0) -> (d0)>} : (i32) -> (index) 10 return 11} 12 13// ----- 14 15func.func @affine_apply_resul_non_index(%arg0 : index) { 16 // Custom parser automatically assigns `index` as the result type so we must 17 // use the generic syntax here to exercise the verifier. 18 // expected-error@+1 {{op result #0 must be index, but got 'i32'}} 19 %0 = "affine.apply"(%arg0) {map = affine_map<(d0) -> (d0)>} : (index) -> (i32) 20 return 21} 22 23// ----- 24func.func @affine_load_invalid_dim(%M : memref<10xi32>) { 25 "unknown"() ({ 26 ^bb0(%arg: index): 27 affine.load %M[%arg] : memref<10xi32> 28 // expected-error@-1 {{index must be a valid dimension or symbol identifier}} 29 cf.br ^bb1 30 ^bb1: 31 cf.br ^bb1 32 }) : () -> () 33 return 34} 35 36// ----- 37 38#map0 = affine_map<(d0)[s0] -> (d0 + s0)> 39 40func.func @affine_for_lower_bound_invalid_sym() { 41 affine.for %i0 = 0 to 7 { 42 // expected-error@+1 {{operand cannot be used as a symbol}} 43 affine.for %n0 = #map0(%i0)[%i0] to 7 { 44 } 45 } 46 return 47} 48 49// ----- 50 51#map0 = affine_map<(d0)[s0] -> (d0 + s0)> 52 53func.func @affine_for_upper_bound_invalid_sym() { 54 affine.for %i0 = 0 to 7 { 55 // expected-error@+1 {{operand cannot be used as a symbol}} 56 affine.for %n0 = 0 to #map0(%i0)[%i0] { 57 } 58 } 59 return 60} 61 62// ----- 63 64#set0 = affine_set<(i)[N] : (i >= 0, N - i >= 0)> 65 66func.func @affine_if_invalid_sym() { 67 affine.for %i0 = 0 to 7 { 68 // expected-error@+1 {{operand cannot be used as a symbol}} 69 affine.if #set0(%i0)[%i0] {} 70 } 71 return 72} 73 74// ----- 75 76#set0 = affine_set<(i)[N] : (i >= 0, N - i >= 0)> 77 78func.func @affine_if_invalid_dimop_dim(%arg0: index, %arg1: index, %arg2: index, %arg3: index) { 79 affine.for %n0 = 0 to 7 { 80 %0 = memref.alloc(%arg0, %arg1, %arg2, %arg3) : memref<?x?x?x?xf32> 81 %c0 = arith.constant 0 : index 82 %dim = memref.dim %0, %c0 : memref<?x?x?x?xf32> 83 84 // expected-error@+1 {{operand cannot be used as a symbol}} 85 affine.if #set0(%dim)[%n0] {} 86 } 87 return 88} 89 90// ----- 91 92func.func @affine_store_missing_l_square(%C: memref<4096x4096xf32>) { 93 %9 = arith.constant 0.0 : f32 94 // expected-error@+1 {{expected '['}} 95 affine.store %9, %C : memref<4096x4096xf32> 96 return 97} 98 99// ----- 100 101func.func @affine_store_wrong_value_type(%C: memref<f32>) { 102 %c0 = arith.constant 0 : i32 103 // expected-error@+1 {{value to store must have the same type as memref element type}} 104 "affine.store"(%c0, %C) <{map = affine_map<(i) -> (i)>}> : (i32, memref<f32>) -> () 105 return 106} 107 108// ----- 109 110func.func @affine_min(%arg0 : index, %arg1 : index, %arg2 : index) { 111 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 112 %0 = affine.min affine_map<(d0) -> (d0)> (%arg0, %arg1) 113 114 return 115} 116 117// ----- 118 119func.func @affine_min(%arg0 : index, %arg1 : index, %arg2 : index) { 120 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 121 %0 = affine.min affine_map<()[s0] -> (s0)> (%arg0, %arg1) 122 123 return 124} 125 126// ----- 127 128func.func @affine_min(%arg0 : index, %arg1 : index, %arg2 : index) { 129 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 130 %0 = affine.min affine_map<(d0) -> (d0)> () 131 132 return 133} 134 135// ----- 136 137func.func @affine_min() { 138 // expected-error@+1 {{'affine.min' op affine map expect at least one result}} 139 %0 = affine.min affine_map<() -> ()> () 140 return 141} 142 143// ----- 144 145func.func @affine_min(%arg0 : index) { 146 // expected-error@+1 {{'affine.min' op affine map expect at least one result}} 147 %0 = affine.min affine_map<(d0) -> ()> (%arg0) 148 return 149} 150 151// ----- 152 153func.func @affine_max(%arg0 : index, %arg1 : index, %arg2 : index) { 154 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 155 %0 = affine.max affine_map<(d0) -> (d0)> (%arg0, %arg1) 156 157 return 158} 159 160// ----- 161 162func.func @affine_max(%arg0 : index, %arg1 : index, %arg2 : index) { 163 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 164 %0 = affine.max affine_map<()[s0] -> (s0)> (%arg0, %arg1) 165 166 return 167} 168 169// ----- 170 171func.func @affine_max(%arg0 : index, %arg1 : index, %arg2 : index) { 172 // expected-error@+1 {{operand count and affine map dimension and symbol count must match}} 173 %0 = affine.max affine_map<(d0) -> (d0)> () 174 175 return 176} 177 178// ----- 179 180func.func @affine_max() { 181 // expected-error@+1 {{'affine.max' op affine map expect at least one result}} 182 %0 = affine.max affine_map<() -> ()> () 183 return 184} 185 186// ----- 187 188func.func @affine_max(%arg0 : index) { 189 // expected-error@+1 {{'affine.max' op affine map expect at least one result}} 190 %0 = affine.max affine_map<(d0) -> ()> (%arg0) 191 return 192} 193 194// ----- 195 196func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 197 // expected-error@+1 {{the number of region arguments (1) and the number of map groups for lower (2) and upper bound (2), and the number of steps (2) must all match}} 198 affine.parallel (%i) = (0, 0) to (100, 100) step (10, 10) { 199 } 200} 201 202// ----- 203 204func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 205 // expected-error@+1 {{the number of region arguments (2) and the number of map groups for lower (1) and upper bound (2), and the number of steps (2) must all match}} 206 affine.parallel (%i, %j) = (0) to (100, 100) step (10, 10) { 207 } 208} 209 210// ----- 211 212func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 213 // expected-error@+1 {{the number of region arguments (2) and the number of map groups for lower (2) and upper bound (1), and the number of steps (2) must all match}} 214 affine.parallel (%i, %j) = (0, 0) to (100) step (10, 10) { 215 } 216} 217 218// ----- 219 220func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 221 // expected-error@+1 {{the number of region arguments (2) and the number of map groups for lower (2) and upper bound (2), and the number of steps (1) must all match}} 222 affine.parallel (%i, %j) = (0, 0) to (100, 100) step (10) { 223 } 224} 225 226// ----- 227 228func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 229 affine.for %x = 0 to 7 { 230 %y = arith.addi %x, %x : index 231 // expected-error@+1 {{operand cannot be used as a dimension id}} 232 affine.parallel (%i, %j) = (0, 0) to (%y, 100) step (10, 10) { 233 } 234 } 235 return 236} 237 238// ----- 239 240func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 241 affine.for %x = 0 to 7 { 242 %y = arith.addi %x, %x : index 243 // expected-error@+1 {{operand cannot be used as a symbol}} 244 affine.parallel (%i, %j) = (0, 0) to (symbol(%y), 100) step (10, 10) { 245 } 246 } 247 return 248} 249 250// ----- 251 252func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 253 %0 = memref.alloc() : memref<100x100xf32> 254 // expected-error@+1 {{reduction must be specified for each output}} 255 %1 = affine.parallel (%i, %j) = (0, 0) to (100, 100) step (10, 10) -> (f32) { 256 %2 = affine.load %0[%i, %j] : memref<100x100xf32> 257 affine.yield %2 : f32 258 } 259 return 260} 261 262// ----- 263 264func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 265 %0 = memref.alloc() : memref<100x100xf32> 266 // expected-error@+1 {{invalid reduction value: "bad"}} 267 %1 = affine.parallel (%i, %j) = (0, 0) to (100, 100) step (10, 10) reduce ("bad") -> (f32) { 268 %2 = affine.load %0[%i, %j] : memref<100x100xf32> 269 affine.yield %2 : f32 270 } 271 return 272} 273 274// ----- 275 276func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 277 %0 = memref.alloc() : memref<100x100xi32> 278 %1 = affine.parallel (%i, %j) = (0, 0) to (100, 100) step (10, 10) reduce ("minimumf") -> (f32) { 279 %2 = affine.load %0[%i, %j] : memref<100x100xi32> 280 // expected-error@+1 {{types mismatch between yield op and its parent}} 281 affine.yield %2 : i32 282 } 283 return 284} 285 286// ----- 287 288func.func @affine_parallel(%arg0 : index, %arg1 : index, %arg2 : index) { 289 %0 = memref.alloc() : memref<100x100xi32> 290 // expected-error@+1 {{result type cannot match reduction attribute}} 291 %1 = affine.parallel (%i, %j) = (0, 0) to (100, 100) step (10, 10) reduce ("minimumf") -> (i32) { 292 %2 = affine.load %0[%i, %j] : memref<100x100xi32> 293 affine.yield %2 : i32 294 } 295 return 296} 297 298// ----- 299 300func.func @vector_load_invalid_vector_type() { 301 %0 = memref.alloc() : memref<100xf32> 302 affine.for %i0 = 0 to 16 step 8 { 303 // expected-error@+1 {{requires memref and vector types of the same elemental type}} 304 %1 = affine.vector_load %0[%i0] : memref<100xf32>, vector<8xf64> 305 } 306 return 307} 308 309// ----- 310 311func.func @vector_store_invalid_vector_type() { 312 %0 = memref.alloc() : memref<100xf32> 313 %1 = arith.constant dense<7.0> : vector<8xf64> 314 affine.for %i0 = 0 to 16 step 8 { 315 // expected-error@+1 {{requires memref and vector types of the same elemental type}} 316 affine.vector_store %1, %0[%i0] : memref<100xf32>, vector<8xf64> 317 } 318 return 319} 320 321// ----- 322 323func.func @vector_load_vector_memref() { 324 %0 = memref.alloc() : memref<100xvector<8xf32>> 325 affine.for %i0 = 0 to 4 { 326 // expected-error@+1 {{requires memref and vector types of the same elemental type}} 327 %1 = affine.vector_load %0[%i0] : memref<100xvector<8xf32>>, vector<8xf32> 328 } 329 return 330} 331 332// ----- 333 334func.func @vector_store_vector_memref() { 335 %0 = memref.alloc() : memref<100xvector<8xf32>> 336 %1 = arith.constant dense<7.0> : vector<8xf32> 337 affine.for %i0 = 0 to 4 { 338 // expected-error@+1 {{requires memref and vector types of the same elemental type}} 339 affine.vector_store %1, %0[%i0] : memref<100xvector<8xf32>>, vector<8xf32> 340 } 341 return 342} 343 344// ----- 345 346func.func @affine_if_with_then_region_args(%N: index) { 347 %c = arith.constant 200 : index 348 %i = arith.constant 20: index 349 // expected-error@+1 {{affine.if' op region #0 should have no arguments}} 350 affine.if affine_set<(i)[N] : (i - 2 >= 0, 4 - i >= 0)>(%i)[%c] { 351 ^bb0(%arg:i32): 352 %w = affine.apply affine_map<(d0,d1)[s0] -> (d0+d1+s0)> (%i, %i) [%N] 353 } 354 return 355} 356 357// ----- 358 359func.func @affine_if_with_else_region_args(%N: index) { 360 %c = arith.constant 200 : index 361 %i = arith.constant 20: index 362 // expected-error@+1 {{affine.if' op region #1 should have no arguments}} 363 affine.if affine_set<(i)[N] : (i - 2 >= 0, 4 - i >= 0)>(%i)[%c] { 364 %w = affine.apply affine_map<(d0,d1)[s0] -> (d0+d1+s0)> (%i, %i) [%N] 365 } else { 366 ^bb0(%arg:i32): 367 %w = affine.apply affine_map<(d0,d1)[s0] -> (d0-d1+s0)> (%i, %i) [%N] 368 } 369 return 370} 371 372// ----- 373 374func.func @affine_for_iter_args_mismatch(%buffer: memref<1024xf32>) -> f32 { 375 %sum_0 = arith.constant 0.0 : f32 376 // expected-error@+1 {{mismatch between the number of loop-carried values and results}} 377 %res = affine.for %i = 0 to 10 step 2 iter_args(%sum_iter = %sum_0) -> (f32, f32) { 378 %t = affine.load %buffer[%i] : memref<1024xf32> 379 affine.yield %t : f32 380 } 381 return %res : f32 382} 383 384 385// ----- 386 387func.func @result_number() { 388 // expected-error@+1 {{result number not allowed}} 389 affine.for %n0#0 = 0 to 7 { 390 } 391 return 392} 393 394// ----- 395 396func.func @malformed_for_percent() { 397 affine.for i = 1 to 10 { // expected-error {{expected SSA operand}} 398 399// ----- 400 401func.func @malformed_for_equal() { 402 affine.for %i 1 to 10 { // expected-error {{expected '='}} 403 404// ----- 405 406func.func @malformed_for_to() { 407 affine.for %i = 1 too 10 { // expected-error {{expected 'to' between bounds}} 408 } 409} 410 411// ----- 412 413func.func @incomplete_for() { 414 affine.for %i = 1 to 10 step 2 415} // expected-error @-1 {{expected '{' to begin a region}} 416 417// ----- 418 419#map0 = affine_map<(d0) -> (d0 floordiv 4)> 420 421func.func @reference_to_iv_in_bound() { 422 // expected-error@+2 {{region entry argument '%i0' is already in use}} 423 // expected-note@+1 {{previously referenced here}} 424 affine.for %i0 = #map0(%i0) to 10 { 425 } 426} 427 428// ----- 429 430func.func @nonconstant_step(%1 : i32) { 431 affine.for %2 = 1 to 5 step %1 { // expected-error {{expected attribute value}} 432 433// ----- 434 435func.func @for_negative_stride() { 436 affine.for %i = 1 to 10 step -1 437} // expected-error@-1 {{expected step to be representable as a positive signed integer}} 438 439// ----- 440 441func.func @invalid_if_conditional2() { 442 affine.for %i = 1 to 10 { 443 affine.if affine_set<(i)[N] : (i >= )> // expected-error {{expected affine expression}} 444 } 445} 446 447// ----- 448 449func.func @invalid_if_conditional3() { 450 affine.for %i = 1 to 10 { 451 affine.if affine_set<(i)[N] : (i == )> // expected-error {{expected affine expression}} 452 } 453} 454 455// ----- 456 457func.func @invalid_if_conditional6() { 458 affine.for %i = 1 to 10 { 459 affine.if affine_set<(i) : (i)> // expected-error {{expected '== affine-expr' or '>= affine-expr' at end of affine constraint}} 460 } 461} 462 463// ----- 464// TODO: support affine.if (1)? 465func.func @invalid_if_conditional7() { 466 affine.for %i = 1 to 10 { 467 affine.if affine_set<(i) : (1)> // expected-error {{expected '== affine-expr' or '>= affine-expr' at end of affine constraint}} 468 } 469} 470 471// ----- 472 473func.func @missing_for_max(%arg0: index, %arg1: index, %arg2: memref<100xf32>) { 474 // expected-error @+1 {{lower loop bound affine map with multiple results requires 'max' prefix}} 475 affine.for %i0 = affine_map<()[s]->(0,s-1)>()[%arg0] to %arg1 { 476 } 477 return 478} 479 480// ----- 481 482func.func @missing_for_min(%arg0: index, %arg1: index, %arg2: memref<100xf32>) { 483 // expected-error @+1 {{upper loop bound affine map with multiple results requires 'min' prefix}} 484 affine.for %i0 = %arg0 to affine_map<()[s]->(100,s+1)>()[%arg1] { 485 } 486 return 487} 488 489// ----- 490 491func.func @delinearize(%idx: index, %basis0: index, %basis1 :index) { 492 // expected-error@+1 {{'affine.delinearize_index' op should return an index for each basis element and up to one extra index}} 493 %1 = affine.delinearize_index %idx into (%basis0, %basis1) : index 494 return 495} 496 497// ----- 498 499func.func @delinearize(%idx: index) { 500 // expected-error@+1 {{'affine.delinearize_index' op no basis element may be statically non-positive}} 501 %1:2 = affine.delinearize_index %idx into (2, -2) : index, index 502 return 503} 504 505// ----- 506 507func.func @linearize(%idx: index, %basis0: index, %basis1 :index) -> index { 508 // expected-error@+1 {{'affine.linearize_index' op should be passed a basis element for each index except possibly the first}} 509 %0 = affine.linearize_index [%idx] by (%basis0, %basis1) : index 510 return %0 : index 511} 512 513// ----- 514 515func.func @dynamic_dimension_index() { 516 "unknown.region"() ({ 517 %idx = "unknown.test"() : () -> (index) 518 %memref = "unknown.test"() : () -> memref<?x?xf32> 519 %dim = memref.dim %memref, %idx : memref<?x?xf32> 520 // expected-error @below {{op index must be a valid dimension or symbol identifier}} 521 affine.load %memref[%dim, %dim] : memref<?x?xf32> 522 "unknown.terminator"() : () -> () 523 }) : () -> () 524 return 525} 526