1// RUN: mlir-opt -allow-unregistered-dialect %s | FileCheck %s 2 3// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0, d1, d2, d3, d4)[s0] -> (d0, d1, d2, d4, d3)> 4#map0 = affine_map<(d0, d1, d2, d3, d4)[s0] -> (d0, d1, d2, d4, d3)> 5 6// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0) -> (d0)> 7#map1 = affine_map<(d0) -> (d0)> 8 9// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0, d1, d2) -> (d0, d1, d2)> 10#map2 = affine_map<(d0, d1, d2) -> (d0, d1, d2)> 11 12// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0, d1, d2) -> (d1, d0, d2)> 13#map3 = affine_map<(d0, d1, d2) -> (d1, d0, d2)> 14 15// CHECK-DAG: #map{{[0-9]+}} = affine_map<()[s0] -> (0, s0 - 1)> 16#inline_map_minmax_loop1 = affine_map<()[s0] -> (0, s0 - 1)> 17 18// CHECK-DAG: #map{{[0-9]+}} = affine_map<()[s0] -> (100, s0 + 1)> 19#inline_map_minmax_loop2 = affine_map<()[s0] -> (100, s0 + 1)> 20 21// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0, d1)[s0] -> (d0 + d1 + s0)> 22#bound_map1 = affine_map<(i, j)[s] -> (i + j + s)> 23 24// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0, d1) -> (d0 + d1)> 25#inline_map_loop_bounds2 = affine_map<(d0, d1) -> (d0 + d1)> 26 27// CHECK-DAG: #map{{[0-9]+}} = affine_map<(d0)[s0] -> (d0 + s0, d0 - s0)> 28#bound_map2 = affine_map<(i)[s] -> (i + s, i - s)> 29 30// All maps appear in arbitrary order before all sets, in arbitrary order. 31// CHECK-NOT: Placeholder 32 33// CHECK-DAG: #set{{[0-9]+}} = affine_set<(d0)[s0, s1] : (d0 >= 0, -d0 + s0 >= 0, s0 - 5 == 0, -d0 + s1 + 1 >= 0)> 34#set0 = affine_set<(i)[N, M] : (i >= 0, -i + N >= 0, N - 5 == 0, -i + M + 1 >= 0)> 35 36// CHECK-DAG: #set{{[0-9]+}} = affine_set<(d0, d1)[s0] : (d0 >= 0, d1 >= 0)> 37#set1 = affine_set<(d0, d1)[s0] : (d0 >= 0, d1 >= 0)> 38 39// CHECK-DAG: #set{{[0-9]+}} = affine_set<(d0) : (d0 - 1 == 0)> 40#set2 = affine_set<(d0) : (d0 - 1 == 0)> 41 42// CHECK-DAG: [[$SET_TRUE:#set[0-9]+]] = affine_set<() : (0 == 0)> 43 44// CHECK-DAG: #set{{[0-9]+}} = affine_set<(d0)[s0] : (d0 - 2 >= 0, -d0 + 4 >= 0)> 45 46// CHECK: func private @foo(i32, i64) -> f32 47func.func private @foo(i32, i64) -> f32 48 49// CHECK: func private @bar() 50func.func private @bar() -> () 51 52// CHECK: func private @baz() -> (i1, index, f32) 53func.func private @baz() -> (i1, index, f32) 54 55// CHECK: func private @missingReturn() 56func.func private @missingReturn() 57 58// CHECK: func private @int_types(i0, i1, i2, i4, i7, i87) -> (i1, index, i19) 59func.func private @int_types(i0, i1, i2, i4, i7, i87) -> (i1, index, i19) 60 61// CHECK: func private @sint_types(si2, si4) -> (si7, si1023) 62func.func private @sint_types(si2, si4) -> (si7, si1023) 63 64// CHECK: func private @uint_types(ui2, ui4) -> (ui7, ui1023) 65func.func private @uint_types(ui2, ui4) -> (ui7, ui1023) 66 67// CHECK: func private @float_types(f80, f128) 68func.func private @float_types(f80, f128) 69 70// CHECK: func private @vectors(vector<f32>, vector<1xf32>, vector<2x4xf32>) 71func.func private @vectors(vector<f32>, vector<1 x f32>, vector<2x4xf32>) 72 73// CHECK: func private @tensors(tensor<*xf32>, tensor<*xvector<2x4xf32>>, tensor<1x?x4x?x?xi32>, tensor<i8>) 74func.func private @tensors(tensor<* x f32>, tensor<* x vector<2x4xf32>>, 75 tensor<1x?x4x?x?xi32>, tensor<i8>) 76 77// CHECK: func private @tensor_encoding(tensor<16x32xf64, "sparse">) 78func.func private @tensor_encoding(tensor<16x32xf64, "sparse">) 79 80// CHECK: func private @large_shape_dimension(tensor<9223372036854775807xf32>) 81func.func private @large_shape_dimension(tensor<9223372036854775807xf32>) 82 83// CHECK: func private @functions((memref<1x?x4x?x?xi32, #map0>, memref<8xi8>) -> (), () -> ()) 84func.func private @functions((memref<1x?x4x?x?xi32, #map0, 0>, memref<8xi8, #map1, 0>) -> (), ()->()) 85 86// CHECK: func private @memrefs2(memref<2x4x8xi8, 1>) 87func.func private @memrefs2(memref<2x4x8xi8, #map2, 1>) 88 89// CHECK: func private @memrefs3(memref<2x4x8xi8>) 90func.func private @memrefs3(memref<2x4x8xi8, affine_map<(d0, d1, d2) -> (d0, d1, d2)>>) 91 92// CHECK: func private @memrefs_drop_triv_id_inline(memref<2xi8>) 93func.func private @memrefs_drop_triv_id_inline(memref<2xi8, affine_map<(d0) -> (d0)>>) 94 95// CHECK: func private @memrefs_drop_triv_id_inline0(memref<2xi8>) 96func.func private @memrefs_drop_triv_id_inline0(memref<2xi8, affine_map<(d0) -> (d0)>, 0>) 97 98// CHECK: func private @memrefs_drop_triv_id_inline1(memref<2xi8, 1>) 99func.func private @memrefs_drop_triv_id_inline1(memref<2xi8, affine_map<(d0) -> (d0)>, 1>) 100 101// Test memref with custom memory space 102 103// CHECK: func private @memrefs_nomap_nospace(memref<5x6x7xf32>) 104func.func private @memrefs_nomap_nospace(memref<5x6x7xf32>) 105 106// CHECK: func private @memrefs_map_nospace(memref<5x6x7xf32, #map{{[0-9]+}}>) 107func.func private @memrefs_map_nospace(memref<5x6x7xf32, #map3>) 108 109// CHECK: func private @memrefs_nomap_intspace(memref<5x6x7xf32, 3>) 110func.func private @memrefs_nomap_intspace(memref<5x6x7xf32, 3>) 111 112// CHECK: func private @memrefs_map_intspace(memref<5x6x7xf32, #map{{[0-9]+}}, 5>) 113func.func private @memrefs_map_intspace(memref<5x6x7xf32, #map3, 5>) 114 115// CHECK: func private @memrefs_nomap_strspace(memref<5x6x7xf32, "local">) 116func.func private @memrefs_nomap_strspace(memref<5x6x7xf32, "local">) 117 118// CHECK: func private @memrefs_map_strspace(memref<5x6x7xf32, #map{{[0-9]+}}, "private">) 119func.func private @memrefs_map_strspace(memref<5x6x7xf32, #map3, "private">) 120 121// CHECK: func private @memrefs_nomap_dictspace(memref<5x6x7xf32, {memSpace = "special", subIndex = 1 : i64}>) 122func.func private @memrefs_nomap_dictspace(memref<5x6x7xf32, {memSpace = "special", subIndex = 1}>) 123 124// CHECK: func private @memrefs_map_dictspace(memref<5x6x7xf32, #map{{[0-9]+}}, {memSpace = "special", subIndex = 3 : i64}>) 125func.func private @memrefs_map_dictspace(memref<5x6x7xf32, #map3, {memSpace = "special", subIndex = 3}>) 126 127// CHECK: func private @complex_types(complex<i1>) -> complex<f32> 128func.func private @complex_types(complex<i1>) -> complex<f32> 129 130// CHECK: func private @memref_with_index_elems(memref<1x?xindex>) 131func.func private @memref_with_index_elems(memref<1x?xindex>) 132 133// CHECK: func private @memref_with_complex_elems(memref<1x?xcomplex<f32>>) 134func.func private @memref_with_complex_elems(memref<1x?xcomplex<f32>>) 135 136// CHECK: func private @memref_with_vector_elems(memref<1x?xvector<10xf32>>) 137func.func private @memref_with_vector_elems(memref<1x?xvector<10xf32>>) 138 139// CHECK: func private @memref_with_custom_elem(memref<1x?x!test.memref_element>) 140func.func private @memref_with_custom_elem(memref<1x?x!test.memref_element>) 141 142// CHECK: func private @memref_of_memref(memref<1xmemref<1xf64>>) 143func.func private @memref_of_memref(memref<1xmemref<1xf64>>) 144 145// CHECK: func private @memref_of_unranked_memref(memref<1xmemref<*xf32>>) 146func.func private @memref_of_unranked_memref(memref<1xmemref<*xf32>>) 147 148// CHECK: func private @unranked_memref_of_memref(memref<*xmemref<1xf32>>) 149func.func private @unranked_memref_of_memref(memref<*xmemref<1xf32>>) 150 151// CHECK: func private @unranked_memref_of_unranked_memref(memref<*xmemref<*xi32>>) 152func.func private @unranked_memref_of_unranked_memref(memref<*xmemref<*xi32>>) 153 154// CHECK: func private @unranked_memref_with_complex_elems(memref<*xcomplex<f32>>) 155func.func private @unranked_memref_with_complex_elems(memref<*xcomplex<f32>>) 156 157// CHECK: func private @unranked_memref_with_index_elems(memref<*xindex>) 158func.func private @unranked_memref_with_index_elems(memref<*xindex>) 159 160// CHECK: func private @unranked_memref_with_vector_elems(memref<*xvector<10xf32>>) 161func.func private @unranked_memref_with_vector_elems(memref<*xvector<10xf32>>) 162 163// CHECK-LABEL: func @simpleCFG(%{{.*}}: i32, %{{.*}}: f32) -> i1 { 164func.func @simpleCFG(%arg0: i32, %f: f32) -> i1 { 165 // CHECK: %{{.*}} = "foo"() : () -> i64 166 %1 = "foo"() : ()->i64 167 // CHECK: "bar"(%{{.*}}) : (i64) -> (i1, i1, i1) 168 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 169 // CHECK: return %{{.*}}#1 170 return %2#1 : i1 171// CHECK: } 172} 173 174// CHECK-LABEL: func @simpleCFGUsingBBArgs(%{{.*}}: i32, %{{.*}}: i64) { 175func.func @simpleCFGUsingBBArgs(i32, i64) { 176^bb42 (%arg0: i32, %f: i64): 177 // CHECK: "bar"(%{{.*}}) : (i64) -> (i1, i1, i1) 178 %2:3 = "bar"(%f) : (i64) -> (i1,i1,i1) 179 // CHECK: return{{$}} 180 return 181// CHECK: } 182} 183 184// CHECK-LABEL: func @block_label_empty_list 185func.func @block_label_empty_list() { 186^bb0(): 187 return 188} 189 190// CHECK-LABEL: func @multiblock() { 191func.func @multiblock() { 192 return // CHECK: return 193^bb1: // CHECK: ^bb1: // no predecessors 194 cf.br ^bb4 // CHECK: cf.br ^bb3 195^bb2: // CHECK: ^bb2: // pred: ^bb2 196 cf.br ^bb2 // CHECK: cf.br ^bb2 197^bb4: // CHECK: ^bb3: // pred: ^bb1 198 return // CHECK: return 199} // CHECK: } 200 201// CHECK-LABEL: func @emptyMLF() { 202func.func @emptyMLF() { 203 return // CHECK: return 204} // CHECK: } 205 206// CHECK-LABEL: func @func_with_one_arg(%{{.*}}: i1) -> i2 { 207func.func @func_with_one_arg(%c : i1) -> i2 { 208 // CHECK: %{{.*}} = "foo"(%{{.*}}) : (i1) -> i2 209 %b = "foo"(%c) : (i1) -> (i2) 210 return %b : i2 // CHECK: return %{{.*}} : i2 211} // CHECK: } 212 213// CHECK-LABEL: func @func_with_two_args(%{{.*}}: f16, %{{.*}}: i8) -> (i1, i32) { 214func.func @func_with_two_args(%a : f16, %b : i8) -> (i1, i32) { 215 // CHECK: %{{.*}}:2 = "foo"(%{{.*}}, %{{.*}}) : (f16, i8) -> (i1, i32) 216 %c:2 = "foo"(%a, %b) : (f16, i8)->(i1, i32) 217 return %c#0, %c#1 : i1, i32 // CHECK: return %{{.*}}#0, %{{.*}}#1 : i1, i32 218} // CHECK: } 219 220// CHECK-LABEL: func @second_order_func() -> (() -> ()) { 221func.func @second_order_func() -> (() -> ()) { 222// CHECK-NEXT: %{{.*}} = constant @emptyMLF : () -> () 223 %c = constant @emptyMLF : () -> () 224// CHECK-NEXT: return %{{.*}} : () -> () 225 return %c : () -> () 226} 227 228// CHECK-LABEL: func @third_order_func() -> (() -> (() -> ())) { 229func.func @third_order_func() -> (() -> (() -> ())) { 230// CHECK-NEXT: %{{.*}} = constant @second_order_func : () -> (() -> ()) 231 %c = constant @second_order_func : () -> (() -> ()) 232// CHECK-NEXT: return %{{.*}} : () -> (() -> ()) 233 return %c : () -> (() -> ()) 234} 235 236// CHECK-LABEL: func @identity_functor(%{{.*}}: () -> ()) -> (() -> ()) { 237func.func @identity_functor(%a : () -> ()) -> (() -> ()) { 238// CHECK-NEXT: return %{{.*}} : () -> () 239 return %a : () -> () 240} 241 242// CHECK-LABEL: func @func_ops_in_loop() { 243func.func @func_ops_in_loop() { 244 // CHECK: %{{.*}} = "foo"() : () -> i64 245 %a = "foo"() : ()->i64 246 // CHECK: affine.for %{{.*}} = 1 to 10 { 247 affine.for %i = 1 to 10 { 248 // CHECK: %{{.*}} = "doo"() : () -> f32 249 %b = "doo"() : ()->f32 250 // CHECK: "bar"(%{{.*}}, %{{.*}}) : (i64, f32) -> () 251 "bar"(%a, %b) : (i64, f32) -> () 252 // CHECK: } 253 } 254 // CHECK: return 255 return 256 // CHECK: } 257} 258 259 260// CHECK-LABEL: func @loops() { 261func.func @loops() { 262 // CHECK: affine.for %{{.*}} = 1 to 100 step 2 { 263 affine.for %i = 1 to 100 step 2 { 264 // CHECK: affine.for %{{.*}} = 1 to 200 { 265 affine.for %j = 1 to 200 { 266 } // CHECK: } 267 } // CHECK: } 268 return // CHECK: return 269} // CHECK: } 270 271// CHECK-LABEL: func @complex_loops() { 272func.func @complex_loops() { 273 affine.for %i1 = 1 to 100 { // CHECK: affine.for %{{.*}} = 1 to 100 { 274 affine.for %j1 = 1 to 100 { // CHECK: affine.for %{{.*}} = 1 to 100 { 275 // CHECK: "foo"(%{{.*}}, %{{.*}}) : (index, index) -> () 276 "foo"(%i1, %j1) : (index,index) -> () 277 } // CHECK: } 278 "boo"() : () -> () // CHECK: "boo"() : () -> () 279 affine.for %j2 = 1 to 10 { // CHECK: affine.for %{{.*}} = 1 to 10 { 280 affine.for %k2 = 1 to 10 { // CHECK: affine.for %{{.*}} = 1 to 10 { 281 "goo"() : () -> () // CHECK: "goo"() : () -> () 282 } // CHECK: } 283 } // CHECK: } 284 } // CHECK: } 285 return // CHECK: return 286} // CHECK: } 287 288// CHECK: func @triang_loop(%{{.*}}: index, %{{.*}}: memref<?x?xi32>) { 289func.func @triang_loop(%arg0: index, %arg1: memref<?x?xi32>) { 290 %c = arith.constant 0 : i32 // CHECK: %{{.*}} = arith.constant 0 : i32 291 affine.for %i0 = 1 to %arg0 { // CHECK: affine.for %{{.*}} = 1 to %{{.*}} { 292 affine.for %i1 = affine_map<(d0)[]->(d0)>(%i0)[] to %arg0 { // CHECK: affine.for %{{.*}} = #map{{[0-9]+}}(%{{.*}}) to %{{.*}} { 293 memref.store %c, %arg1[%i0, %i1] : memref<?x?xi32> // CHECK: memref.store %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] 294 } // CHECK: } 295 } // CHECK: } 296 return // CHECK: return 297} // CHECK: } 298 299// CHECK: func @minmax_loop(%{{.*}}: index, %{{.*}}: index, %{{.*}}: memref<100xf32>) { 300func.func @minmax_loop(%arg0: index, %arg1: index, %arg2: memref<100xf32>) { 301 // CHECK: affine.for %{{.*}} = max #map{{.*}}()[%{{.*}}] to min #map{{.*}}()[%{{.*}}] { 302 affine.for %i0 = max affine_map<()[s]->(0,s-1)>()[%arg0] to min affine_map<()[s]->(100,s+1)>()[%arg1] { 303 // CHECK: "foo"(%{{.*}}, %{{.*}}) : (memref<100xf32>, index) -> () 304 "foo"(%arg2, %i0) : (memref<100xf32>, index) -> () 305 } // CHECK: } 306 return // CHECK: return 307} // CHECK: } 308 309// CHECK-LABEL: func @loop_bounds(%{{.*}}: index) { 310func.func @loop_bounds(%N : index) { 311 // CHECK: %{{.*}} = "foo"(%{{.*}}) : (index) -> index 312 %s = "foo"(%N) : (index) -> index 313 // CHECK: affine.for %{{.*}} = %{{.*}} to %{{.*}} 314 affine.for %i = %s to %N { 315 // CHECK: affine.for %{{.*}} = #map{{[0-9]+}}(%{{.*}}) to 0 316 affine.for %j = affine_map<(d0)[]->(d0)>(%i)[] to 0 step 1 { 317 // CHECK: %{{.*}} = affine.apply #map{{.*}}(%{{.*}}, %{{.*}})[%{{.*}}] 318 %w1 = affine.apply affine_map<(d0, d1)[s0] -> (d0+d1)> (%i, %j) [%s] 319 // CHECK: %{{.*}} = affine.apply #map{{.*}}(%{{.*}}, %{{.*}})[%{{.*}}] 320 %w2 = affine.apply affine_map<(d0, d1)[s0] -> (s0+1)> (%i, %j) [%s] 321 // CHECK: affine.for %{{.*}} = #map{{.*}}(%{{.*}}, %{{.*}})[%{{.*}}] to #map{{.*}}(%{{.*}}, %{{.*}})[%{{.*}}] { 322 affine.for %k = #bound_map1 (%w1, %i)[%N] to affine_map<(i, j)[s] -> (i + j + s)> (%w2, %j)[%s] { 323 // CHECK: "foo"(%{{.*}}, %{{.*}}, %{{.*}}) : (index, index, index) -> () 324 "foo"(%i, %j, %k) : (index, index, index)->() 325 // CHECK: %{{.*}} = arith.constant 30 : index 326 %c = arith.constant 30 : index 327 // CHECK: %{{.*}} = affine.apply #map{{.*}}(%{{.*}}, %{{.*}}) 328 %u = affine.apply affine_map<(d0, d1)->(d0+d1)> (%N, %c) 329 // CHECK: affine.for %{{.*}} = max #map{{.*}}(%{{.*}})[%{{.*}}] to min #map{{.*}}(%{{.*}})[%{{.*}}] { 330 affine.for %l = max #bound_map2(%i)[%u] to min #bound_map2(%k)[%c] { 331 // CHECK: "bar"(%{{.*}}) : (index) -> () 332 "bar"(%l) : (index) -> () 333 } // CHECK: } 334 } // CHECK: } 335 } // CHECK: } 336 } // CHECK: } 337 return // CHECK: return 338} // CHECK: } 339 340// CHECK-LABEL: func @ifinst(%{{.*}}: index) { 341func.func @ifinst(%N: index) { 342 %c = arith.constant 200 : index // CHECK %{{.*}} = arith.constant 200 343 affine.for %i = 1 to 10 { // CHECK affine.for %{{.*}} = 1 to 10 { 344 affine.if #set0(%i)[%N, %c] { // CHECK affine.if #set0(%{{.*}})[%{{.*}}, %{{.*}}] { 345 %x = arith.constant 1 : i32 346 // CHECK: %{{.*}} = arith.constant 1 : i32 347 %y = "add"(%x, %i) : (i32, index) -> i32 // CHECK: %{{.*}} = "add"(%{{.*}}, %{{.*}}) : (i32, index) -> i32 348 %z = "mul"(%y, %y) : (i32, i32) -> i32 // CHECK: %{{.*}} = "mul"(%{{.*}}, %{{.*}}) : (i32, i32) -> i32 349 } else { // CHECK } else { 350 affine.if affine_set<(i)[N] : (i - 2 >= 0, 4 - i >= 0)>(%i)[%N] { // CHECK affine.if (#set1(%{{.*}})[%{{.*}}]) { 351 // CHECK: %{{.*}} = arith.constant 1 : index 352 %u = arith.constant 1 : index 353 // CHECK: %{{.*}} = affine.apply #map{{.*}}(%{{.*}}, %{{.*}})[%{{.*}}] 354 %w = affine.apply affine_map<(d0,d1)[s0] -> (d0+d1+s0)> (%i, %i) [%u] 355 } else { // CHECK } else { 356 %v = arith.constant 3 : i32 // %c3_i32 = arith.constant 3 : i32 357 } 358 } // CHECK } 359 } // CHECK } 360 return // CHECK return 361} // CHECK } 362 363// CHECK-LABEL: func @simple_ifinst(%{{.*}}: index) { 364func.func @simple_ifinst(%N: index) { 365 %c = arith.constant 200 : index // CHECK %{{.*}} = arith.constant 200 366 affine.for %i = 1 to 10 { // CHECK affine.for %{{.*}} = 1 to 10 { 367 affine.if #set0(%i)[%N, %c] { // CHECK affine.if #set0(%{{.*}})[%{{.*}}, %{{.*}}] { 368 %x = arith.constant 1 : i32 369 // CHECK: %{{.*}} = arith.constant 1 : i32 370 %y = "add"(%x, %i) : (i32, index) -> i32 // CHECK: %{{.*}} = "add"(%{{.*}}, %{{.*}}) : (i32, index) -> i32 371 %z = "mul"(%y, %y) : (i32, i32) -> i32 // CHECK: %{{.*}} = "mul"(%{{.*}}, %{{.*}}) : (i32, i32) -> i32 372 } // CHECK } 373 } // CHECK } 374 return // CHECK return 375} // CHECK } 376 377// CHECK-LABEL: func @attributes() { 378func.func @attributes() { 379 // CHECK: "foo"() 380 "foo"(){} : ()->() 381 382 // CHECK: "foo"() {a = 1 : i64, b = -423 : i64, c = [true, false], d = 1.600000e+01 : f64} : () -> () 383 "foo"() {a = 1, b = -423, c = [true, false], d = 16.0 } : () -> () 384 385 // CHECK: "foo"() {map1 = #map{{[0-9]+}}} 386 "foo"() {map1 = #map1} : () -> () 387 388 // CHECK: "foo"() {map2 = #map{{[0-9]+}}} 389 "foo"() {map2 = affine_map<(d0, d1, d2) -> (d0, d1, d2)>} : () -> () 390 391 // CHECK: "foo"() {map12 = [#map{{[0-9]+}}, #map{{[0-9]+}}]} 392 "foo"() {map12 = [#map1, #map2]} : () -> () 393 394 // CHECK: "foo"() {set1 = #set{{[0-9]+}}} 395 "foo"() {set1 = #set1} : () -> () 396 397 // CHECK: "foo"() {set2 = #set{{[0-9]+}}} 398 "foo"() {set2 = affine_set<(d0, d1, d2) : (d0 >= 0, d1 >= 0, d2 - d1 == 0)>} : () -> () 399 400 // CHECK: "foo"() {set12 = [#set{{[0-9]+}}, #set{{[0-9]+}}]} 401 "foo"() {set12 = [#set1, #set2]} : () -> () 402 403 // CHECK: "foo"() {dictionary = {bool = true, fn = @ifinst}} 404 "foo"() {dictionary = {bool = true, fn = @ifinst}} : () -> () 405 406 // Check that the dictionary attribute elements are sorted. 407 // CHECK: "foo"() {dictionary = {bar = false, bool = true, fn = @ifinst}} 408 "foo"() {dictionary = {fn = @ifinst, bar = false, bool = true}} : () -> () 409 410 // CHECK: "foo"() {d = 1.000000e-09 : f64, func = [], i123 = 7 : i64, if = "foo"} : () -> () 411 "foo"() {if = "foo", func = [], i123 = 7, d = 1.e-9} : () -> () 412 413 // CHECK: "foo"() {fn = @attributes, if = @ifinst} : () -> () 414 "foo"() {fn = @attributes, if = @ifinst} : () -> () 415 416 // CHECK: "foo"() {int = 0 : i42} : () -> () 417 "foo"() {int = 0 : i42} : () -> () 418 return 419} 420 421// CHECK-LABEL: func @ssa_values() -> (i16, i8) { 422func.func @ssa_values() -> (i16, i8) { 423 // CHECK: %{{.*}}:2 = "foo"() : () -> (i1, i17) 424 %0:2 = "foo"() : () -> (i1, i17) 425 cf.br ^bb2 426 427^bb1: // CHECK: ^bb1: // pred: ^bb2 428 // CHECK: %{{.*}}:2 = "baz"(%{{.*}}#1, %{{.*}}#0, %{{.*}}#1) : (f32, i11, i17) -> (i16, i8) 429 %1:2 = "baz"(%2#1, %2#0, %0#1) : (f32, i11, i17) -> (i16, i8) 430 431 // CHECK: return %{{.*}}#0, %{{.*}}#1 : i16, i8 432 return %1#0, %1#1 : i16, i8 433 434^bb2: // CHECK: ^bb2: // pred: ^bb0 435 // CHECK: %{{.*}}:2 = "bar"(%{{.*}}#0, %{{.*}}#1) : (i1, i17) -> (i11, f32) 436 %2:2 = "bar"(%0#0, %0#1) : (i1, i17) -> (i11, f32) 437 cf.br ^bb1 438} 439 440// CHECK-LABEL: func @bbargs() -> (i16, i8) { 441func.func @bbargs() -> (i16, i8) { 442 // CHECK: %{{.*}}:2 = "foo"() : () -> (i1, i17) 443 %0:2 = "foo"() : () -> (i1, i17) 444 cf.br ^bb1(%0#1, %0#0 : i17, i1) 445 446^bb1(%x: i17, %y: i1): // CHECK: ^bb1(%{{.*}}: i17, %{{.*}}: i1): 447 // CHECK: %{{.*}}:2 = "baz"(%{{.*}}, %{{.*}}, %{{.*}}#1) : (i17, i1, i17) -> (i16, i8) 448 %1:2 = "baz"(%x, %y, %0#1) : (i17, i1, i17) -> (i16, i8) 449 return %1#0, %1#1 : i16, i8 450} 451 452// CHECK-LABEL: func @verbose_terminators() -> (i1, i17) 453func.func @verbose_terminators() -> (i1, i17) { 454 %0:2 = "foo"() : () -> (i1, i17) 455// CHECK: cf.br ^bb1(%{{.*}}#0, %{{.*}}#1 : i1, i17) 456 "cf.br"(%0#0, %0#1)[^bb1] : (i1, i17) -> () 457 458^bb1(%x : i1, %y : i17): 459// CHECK: cf.cond_br %{{.*}}, ^bb2(%{{.*}} : i17), ^bb3(%{{.*}}, %{{.*}} : i1, i17) 460 "cf.cond_br"(%x, %y, %x, %y) [^bb2, ^bb3] {operand_segment_sizes = dense<[1, 1, 2]>: vector<3xi32>} : (i1, i17, i1, i17) -> () 461 462^bb2(%a : i17): 463 %true = arith.constant true 464// CHECK: return %{{.*}}, %{{.*}} : i1, i17 465 "func.return"(%true, %a) : (i1, i17) -> () 466 467^bb3(%b : i1, %c : i17): 468// CHECK: return %{{.*}}, %{{.*}} : i1, i17 469 "func.return"(%b, %c) : (i1, i17) -> () 470} 471 472// CHECK-LABEL: func @condbr_simple 473func.func @condbr_simple() -> (i32) { 474 %cond = "foo"() : () -> i1 475 %a = "bar"() : () -> i32 476 %b = "bar"() : () -> i64 477 // CHECK: cf.cond_br %{{.*}}, ^bb1(%{{.*}} : i32), ^bb2(%{{.*}} : i64) 478 cf.cond_br %cond, ^bb1(%a : i32), ^bb2(%b : i64) 479 480// CHECK: ^bb1({{.*}}: i32): // pred: ^bb0 481^bb1(%x : i32): 482 cf.br ^bb2(%b: i64) 483 484// CHECK: ^bb2({{.*}}: i64): // 2 preds: ^bb0, ^bb1 485^bb2(%y : i64): 486 %z = "foo"() : () -> i32 487 return %z : i32 488} 489 490// CHECK-LABEL: func @condbr_moarargs 491func.func @condbr_moarargs() -> (i32) { 492 %cond = "foo"() : () -> i1 493 %a = "bar"() : () -> i32 494 %b = "bar"() : () -> i64 495 // CHECK: cf.cond_br %{{.*}}, ^bb1(%{{.*}}, %{{.*}} : i32, i64), ^bb2(%{{.*}}, %{{.*}}, %{{.*}} : i64, i32, i32) 496 cf.cond_br %cond, ^bb1(%a, %b : i32, i64), ^bb2(%b, %a, %a : i64, i32, i32) 497 498^bb1(%x : i32, %y : i64): 499 return %x : i32 500 501^bb2(%x2 : i64, %y2 : i32, %z2 : i32): 502 %z = "foo"() : () -> i32 503 return %z : i32 504} 505 506 507// Test pretty printing of constant names. 508// CHECK-LABEL: func @constants 509func.func @constants() -> (i32, i23, i23, i1, i1) { 510 // CHECK: %{{.*}} = arith.constant 42 : i32 511 %x = arith.constant 42 : i32 512 // CHECK: %{{.*}} = arith.constant 17 : i23 513 %y = arith.constant 17 : i23 514 515 // This is a redundant definition of 17, the asmprinter gives it a unique name 516 // CHECK: %{{.*}} = arith.constant 17 : i23 517 %z = arith.constant 17 : i23 518 519 // CHECK: %{{.*}} = arith.constant true 520 %t = arith.constant true 521 // CHECK: %{{.*}} = arith.constant false 522 %f = arith.constant false 523 524 // The trick to parse type declarations should not interfere with hex 525 // literals. 526 // CHECK: %{{.*}} = arith.constant 3890 : i32 527 %h = arith.constant 0xf32 : i32 528 529 // CHECK: return %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} 530 return %x, %y, %z, %t, %f : i32, i23, i23, i1, i1 531} 532 533// CHECK-LABEL: func @typeattr 534func.func @typeattr() -> () { 535^bb0: 536// CHECK: "foo"() {bar = tensor<*xf32>} : () -> () 537 "foo"(){bar = tensor<*xf32>} : () -> () 538 return 539} 540 541// CHECK-LABEL: func @stringquote 542func.func @stringquote() -> () { 543^bb0: 544 // CHECK: "foo"() {bar = "a\22quoted\22string"} : () -> () 545 "foo"(){bar = "a\"quoted\"string"} : () -> () 546 547 // CHECK-NEXT: "typed_string" : !foo.string 548 "foo"(){bar = "typed_string" : !foo.string} : () -> () 549 return 550} 551 552// CHECK-LABEL: func @unitAttrs 553func.func @unitAttrs() -> () { 554 // CHECK-NEXT: "foo"() {unitAttr} 555 "foo"() {unitAttr = unit} : () -> () 556 557 // CHECK-NEXT: "foo"() {unitAttr} 558 "foo"() {unitAttr} : () -> () 559 560 // CHECK-NEXT: "foo"() {nested = {unitAttr}} 561 "foo"() {nested = {unitAttr}} : () -> () 562 return 563} 564 565// CHECK-LABEL: func @floatAttrs 566func.func @floatAttrs() -> () { 567^bb0: 568 // CHECK: "foo"() {a = 4.000000e+00 : f64, b = 2.000000e+00 : f64, c = 7.100000e+00 : f64, d = -0.000000e+00 : f64} : () -> () 569 "foo"(){a = 4.0, b = 2.0, c = 7.1, d = -0.0} : () -> () 570 return 571} 572 573// CHECK-LABEL: func private @externalfuncattr 574func.func private @externalfuncattr() -> () 575 // CHECK: attributes {dialect.a = "a\22quoted\22string", dialect.b = 4.000000e+00 : f64, dialect.c = tensor<*xf32>} 576 attributes {dialect.a = "a\"quoted\"string", dialect.b = 4.0, dialect.c = tensor<*xf32>} 577 578// CHECK-LABEL: func private @funcattrempty 579func.func private @funcattrempty() -> () 580 attributes {} 581 582// CHECK-LABEL: func private @funcattr 583func.func private @funcattr() -> () 584 // CHECK: attributes {dialect.a = "a\22quoted\22string", dialect.b = 4.000000e+00 : f64, dialect.c = tensor<*xf32>} 585 attributes {dialect.a = "a\"quoted\"string", dialect.b = 4.0, dialect.c = tensor<*xf32>} { 586^bb0: 587 return 588} 589 590// CHECK-LABEL: func @funcattrwithblock 591func.func @funcattrwithblock() -> () 592 attributes {} { 593^bb0: 594 return 595} 596 597// CHECK-label func @funcsimplemap 598#map_simple0 = affine_map<()[] -> (10)> 599#map_simple1 = affine_map<()[s0] -> (s0)> 600#map_non_simple0 = affine_map<(d0)[] -> (d0)> 601#map_non_simple1 = affine_map<(d0)[s0] -> (d0 + s0)> 602#map_non_simple2 = affine_map<()[s0, s1] -> (s0 + s1)> 603#map_non_simple3 = affine_map<()[s0] -> (s0 + 3)> 604func.func @funcsimplemap(%arg0: index, %arg1: index) -> () { 605 affine.for %i0 = 0 to #map_simple0()[] { 606 // CHECK: affine.for %{{.*}} = 0 to 10 { 607 affine.for %i1 = 0 to #map_simple1()[%arg1] { 608 // CHECK: affine.for %{{.*}} = 0 to %{{.*}} { 609 affine.for %i2 = 0 to #map_non_simple0(%i0)[] { 610 // CHECK: affine.for %{{.*}} = 0 to #map{{[a-z_0-9]*}}(%{{.*}}) { 611 affine.for %i3 = 0 to #map_non_simple1(%i0)[%arg1] { 612 // CHECK: affine.for %{{.*}} = 0 to #map{{[a-z_0-9]*}}(%{{.*}})[%{{.*}}] { 613 affine.for %i4 = 0 to #map_non_simple2()[%arg1, %arg0] { 614 // CHECK: affine.for %{{.*}} = 0 to #map{{[a-z_0-9]*}}()[%{{.*}}, %{{.*}}] { 615 affine.for %i5 = 0 to #map_non_simple3()[%arg0] { 616 // CHECK: affine.for %{{.*}} = 0 to #map{{[a-z_0-9]*}}()[%{{.*}}] { 617 %c42_i32 = arith.constant 42 : i32 618 } 619 } 620 } 621 } 622 } 623 } 624 return 625} 626 627// CHECK-LABEL: func @splattensorattr 628func.func @splattensorattr() -> () { 629^bb0: 630 // CHECK: "splatBoolTensor"() {bar = dense<false> : tensor<i1>} : () -> () 631 "splatBoolTensor"(){bar = dense<false> : tensor<i1>} : () -> () 632 633 // CHECK: "splatUIntTensor"() {bar = dense<222> : tensor<2x1x4xui8>} : () -> () 634 "splatUIntTensor"(){bar = dense<222> : tensor<2x1x4xui8>} : () -> () 635 636 // CHECK: "splatIntTensor"() {bar = dense<5> : tensor<2x1x4xi32>} : () -> () 637 "splatIntTensor"(){bar = dense<5> : tensor<2x1x4xi32>} : () -> () 638 639 // CHECK: "splatFloatTensor"() {bar = dense<-5.000000e+00> : tensor<2x1x4xf32>} : () -> () 640 "splatFloatTensor"(){bar = dense<-5.0> : tensor<2x1x4xf32>} : () -> () 641 642 // CHECK: "splatIntVector"() {bar = dense<5> : vector<2x1x4xi64>} : () -> () 643 "splatIntVector"(){bar = dense<5> : vector<2x1x4xi64>} : () -> () 644 645 // CHECK: "splatFloatVector"() {bar = dense<-5.000000e+00> : vector<2x1x4xf16>} : () -> () 646 "splatFloatVector"(){bar = dense<-5.0> : vector<2x1x4xf16>} : () -> () 647 648 // CHECK: "splatIntScalar"() {bar = dense<5> : tensor<i9>} : () -> () 649 "splatIntScalar"() {bar = dense<5> : tensor<i9>} : () -> () 650 // CHECK: "splatFloatScalar"() {bar = dense<-5.000000e+00> : tensor<f16>} : () -> () 651 "splatFloatScalar"() {bar = dense<-5.0> : tensor<f16>} : () -> () 652 return 653} 654 655// CHECK-LABEL: func @densetensorattr 656func.func @densetensorattr() -> () { 657^bb0: 658 659// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck. 660// CHECK: "fooi3"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi3>} : () -> () 661 "fooi3"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi3>} : () -> () 662// CHECK: "fooi6"() {bar = dense<{{\[\[\[}}5, -6, 1, 2]], {{\[\[}}7, 8, 3, 4]]]> : tensor<2x1x4xi6>} : () -> () 663 "fooi6"(){bar = dense<[[[5, -6, 1, 2]], [[7, 8, 3, 4]]]> : tensor<2x1x4xi6>} : () -> () 664// CHECK: "fooi8"() {bar = dense<5> : tensor<1x1x1xi8>} : () -> () 665 "fooi8"(){bar = dense<[[[5]]]> : tensor<1x1x1xi8>} : () -> () 666// CHECK: "fooi13"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi13>} : () -> () 667 "fooi13"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi13>} : () -> () 668// CHECK: "fooi16"() {bar = dense<-5> : tensor<1x1x1xi16>} : () -> () 669 "fooi16"(){bar = dense<[[[-5]]]> : tensor<1x1x1xi16>} : () -> () 670// CHECK: "fooi23"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi23>} : () -> () 671 "fooi23"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi23>} : () -> () 672// CHECK: "fooi32"() {bar = dense<5> : tensor<1x1x1xi32>} : () -> () 673 "fooi32"(){bar = dense<[[[5]]]> : tensor<1x1x1xi32>} : () -> () 674// CHECK: "fooi33"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi33>} : () -> () 675 "fooi33"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi33>} : () -> () 676// CHECK: "fooi43"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi43>} : () -> () 677 "fooi43"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi43>} : () -> () 678// CHECK: "fooi53"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 2, -1, 2]]]> : tensor<2x1x4xi53>} : () -> () 679 "fooi53"(){bar = dense<[[[1, -2, 1, 2]], [[0, 2, -1, 2]]]> : tensor<2x1x4xi53>} : () -> () 680// CHECK: "fooi64"() {bar = dense<{{\[\[\[}}1, -2, 1, 2]], {{\[\[}}0, 3, -1, 2]]]> : tensor<2x1x4xi64>} : () -> () 681 "fooi64"(){bar = dense<[[[1, -2, 1, 2]], [[0, 3, -1, 2]]]> : tensor<2x1x4xi64>} : () -> () 682// CHECK: "fooi64"() {bar = dense<-5> : tensor<1x1x1xi64>} : () -> () 683 "fooi64"(){bar = dense<[[[-5]]]> : tensor<1x1x1xi64>} : () -> () 684// CHECK: "fooi67"() {bar = dense<{{\[\[\[}}-5, 4, 6, 2]]]> : vector<1x1x4xi67>} : () -> () 685 "fooi67"(){bar = dense<[[[-5, 4, 6, 2]]]> : vector<1x1x4xi67>} : () -> () 686 687// CHECK: "foo2"() {bar = dense<> : tensor<0xi32>} : () -> () 688 "foo2"(){bar = dense<> : tensor<0xi32>} : () -> () 689// CHECK: "foo2"() {bar = dense<> : tensor<1x0xi32>} : () -> () 690 "foo2"(){bar = dense<> : tensor<1x0xi32>} : () -> () 691// CHECK: dense<> : tensor<0x512x512xi32> 692 "foo2"(){bar = dense<> : tensor<0x512x512xi32>} : () -> () 693// CHECK: "foo3"() {bar = dense<{{\[\[\[}}5, -6, 1, 2]], {{\[\[}}7, 8, 3, 4]]]> : tensor<2x1x4xi32>} : () -> () 694 "foo3"(){bar = dense<[[[5, -6, 1, 2]], [[7, 8, 3, 4]]]> : tensor<2x1x4xi32>} : () -> () 695 696// CHECK: "float1"() {bar = dense<5.000000e+00> : tensor<1x1x1xf32>} : () -> () 697 "float1"(){bar = dense<[[[5.0]]]> : tensor<1x1x1xf32>} : () -> () 698// CHECK: "float2"() {bar = dense<> : tensor<0xf32>} : () -> () 699 "float2"(){bar = dense<> : tensor<0xf32>} : () -> () 700// CHECK: "float2"() {bar = dense<> : tensor<1x0xf32>} : () -> () 701 "float2"(){bar = dense<> : tensor<1x0xf32>} : () -> () 702 703// CHECK: "bfloat16"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : tensor<2x1x4xbf16>} : () -> () 704 "bfloat16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : tensor<2x1x4xbf16>} : () -> () 705// CHECK: "float16"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : tensor<2x1x4xf16>} : () -> () 706 "float16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : tensor<2x1x4xf16>} : () -> () 707// CHECK: "float32"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : tensor<2x1x4xf32>} : () -> () 708 "float32"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : tensor<2x1x4xf32>} : () -> () 709// CHECK: "float64"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : tensor<2x1x4xf64>} : () -> () 710 "float64"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : tensor<2x1x4xf64>} : () -> () 711 712// CHECK: "intscalar"() {bar = dense<1> : tensor<i32>} : () -> () 713 "intscalar"(){bar = dense<1> : tensor<i32>} : () -> () 714// CHECK: "floatscalar"() {bar = dense<5.000000e+00> : tensor<f32>} : () -> () 715 "floatscalar"(){bar = dense<5.0> : tensor<f32>} : () -> () 716 717// CHECK: "index"() {bar = dense<1> : tensor<index>} : () -> () 718 "index"(){bar = dense<1> : tensor<index>} : () -> () 719// CHECK: "index"() {bar = dense<[1, 2]> : tensor<2xindex>} : () -> () 720 "index"(){bar = dense<[1, 2]> : tensor<2xindex>} : () -> () 721 722 // CHECK: dense<(1,1)> : tensor<complex<i64>> 723 "complex_attr"(){bar = dense<(1,1)> : tensor<complex<i64>>} : () -> () 724 // CHECK: dense<[(1,1), (2,2)]> : tensor<2xcomplex<i64>> 725 "complex_attr"(){bar = dense<[(1,1), (2,2)]> : tensor<2xcomplex<i64>>} : () -> () 726 // CHECK: dense<(1.000000e+00,0.000000e+00)> : tensor<complex<f32>> 727 "complex_attr"(){bar = dense<(1.000000e+00,0.000000e+00)> : tensor<complex<f32>>} : () -> () 728 // CHECK: dense<[(1.000000e+00,0.000000e+00), (2.000000e+00,2.000000e+00)]> : tensor<2xcomplex<f32>> 729 "complex_attr"(){bar = dense<[(1.000000e+00,0.000000e+00), (2.000000e+00,2.000000e+00)]> : tensor<2xcomplex<f32>>} : () -> () 730 return 731} 732 733// CHECK-LABEL: func @densevectorattr 734func.func @densevectorattr() -> () { 735^bb0: 736// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck. 737// CHECK: "fooi8"() {bar = dense<5> : vector<1x1x1xi8>} : () -> () 738 "fooi8"(){bar = dense<[[[5]]]> : vector<1x1x1xi8>} : () -> () 739// CHECK: "fooi16"() {bar = dense<-5> : vector<1x1x1xi16>} : () -> () 740 "fooi16"(){bar = dense<[[[-5]]]> : vector<1x1x1xi16>} : () -> () 741// CHECK: "foo32"() {bar = dense<5> : vector<1x1x1xi32>} : () -> () 742 "foo32"(){bar = dense<[[[5]]]> : vector<1x1x1xi32>} : () -> () 743// CHECK: "fooi64"() {bar = dense<-5> : vector<1x1x1xi64>} : () -> () 744 "fooi64"(){bar = dense<[[[-5]]]> : vector<1x1x1xi64>} : () -> () 745 746// CHECK: "foo3"() {bar = dense<{{\[\[\[}}5, -6, 1, 2]], {{\[\[}}7, 8, 3, 4]]]> : vector<2x1x4xi32>} : () -> () 747 "foo3"(){bar = dense<[[[5, -6, 1, 2]], [[7, 8, 3, 4]]]> : vector<2x1x4xi32>} : () -> () 748 749// CHECK: "float1"() {bar = dense<5.000000e+00> : vector<1x1x1xf32>} : () -> () 750 "float1"(){bar = dense<[[[5.0]]]> : vector<1x1x1xf32>} : () -> () 751 752// CHECK: "bfloat16"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : vector<2x1x4xbf16>} : () -> () 753 "bfloat16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xbf16>} : () -> () 754// CHECK: "float16"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : vector<2x1x4xf16>} : () -> () 755 "float16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf16>} : () -> () 756// CHECK: "float32"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : vector<2x1x4xf32>} : () -> () 757 "float32"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf32>} : () -> () 758// CHECK: "float64"() {bar = dense<{{\[\[\[}}-5.000000e+00, 6.000000e+00, 1.000000e+00, 2.000000e+00]], {{\[\[}}7.000000e+00, -8.000000e+00, 3.000000e+00, 4.000000e+00]]]> : vector<2x1x4xf64>} : () -> () 759 "float64"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf64>} : () -> () 760 return 761} 762 763// CHECK-LABEL: func @sparsetensorattr 764func.func @sparsetensorattr() -> () { 765^bb0: 766// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck. 767// CHECK: "fooi8"() {bar = sparse<0, -2> : tensor<1x1x1xi8>} : () -> () 768 "fooi8"(){bar = sparse<0, -2> : tensor<1x1x1xi8>} : () -> () 769// CHECK: "fooi16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2, -1, 5]> : tensor<2x2x2xi16>} : () -> () 770 "fooi16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2, -1, 5]> : tensor<2x2x2xi16>} : () -> () 771// CHECK: "fooi32"() {bar = sparse<> : tensor<1x1xi32>} : () -> () 772 "fooi32"(){bar = sparse<> : tensor<1x1xi32>} : () -> () 773// CHECK: "fooi64"() {bar = sparse<0, -1> : tensor<1xi64>} : () -> () 774 "fooi64"(){bar = sparse<[0], [-1]> : tensor<1xi64>} : () -> () 775// CHECK: "foo2"() {bar = sparse<> : tensor<0xi32>} : () -> () 776 "foo2"(){bar = sparse<> : tensor<0xi32>} : () -> () 777// CHECK: "foo3"() {bar = sparse<> : tensor<i32>} : () -> () 778 "foo3"(){bar = sparse<> : tensor<i32>} : () -> () 779 780// CHECK: "foof16"() {bar = sparse<0, -2.000000e+00> : tensor<1x1x1xf16>} : () -> () 781 "foof16"(){bar = sparse<0, -2.0> : tensor<1x1x1xf16>} : () -> () 782// CHECK: "foobf16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2.000000e+00, -1.000000e+00, 5.000000e+00]> : tensor<2x2x2xbf16>} : () -> () 783 "foobf16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2.0, -1.0, 5.0]> : tensor<2x2x2xbf16>} : () -> () 784// CHECK: "foof32"() {bar = sparse<> : tensor<1x0x1xf32>} : () -> () 785 "foof32"(){bar = sparse<> : tensor<1x0x1xf32>} : () -> () 786// CHECK: "foof64"() {bar = sparse<0, -1.000000e+00> : tensor<1xf64>} : () -> () 787 "foof64"(){bar = sparse<[[0]], [-1.0]> : tensor<1xf64>} : () -> () 788// CHECK: "foof320"() {bar = sparse<> : tensor<0xf32>} : () -> () 789 "foof320"(){bar = sparse<> : tensor<0xf32>} : () -> () 790// CHECK: "foof321"() {bar = sparse<> : tensor<f32>} : () -> () 791 "foof321"(){bar = sparse<> : tensor<f32>} : () -> () 792 793// CHECK: "foostr"() {bar = sparse<0, "foo"> : tensor<1x1x1x!unknown<>>} : () -> () 794 "foostr"(){bar = sparse<0, "foo"> : tensor<1x1x1x!unknown<>>} : () -> () 795// CHECK: "foostr"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}"a", "b", "c"]> : tensor<2x2x2x!unknown<>>} : () -> () 796 "foostr"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], ["a", "b", "c"]> : tensor<2x2x2x!unknown<>>} : () -> () 797 return 798} 799 800// CHECK-LABEL: func @sparsevectorattr 801func.func @sparsevectorattr() -> () { 802^bb0: 803// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck. 804// CHECK: "fooi8"() {bar = sparse<0, -2> : vector<1x1x1xi8>} : () -> () 805 "fooi8"(){bar = sparse<0, -2> : vector<1x1x1xi8>} : () -> () 806// CHECK: "fooi16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2, -1, 5]> : vector<2x2x2xi16>} : () -> () 807 "fooi16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2, -1, 5]> : vector<2x2x2xi16>} : () -> () 808// CHECK: "fooi32"() {bar = sparse<> : vector<1x1xi32>} : () -> () 809 "fooi32"(){bar = sparse<> : vector<1x1xi32>} : () -> () 810// CHECK: "fooi64"() {bar = sparse<0, -1> : vector<1xi64>} : () -> () 811 "fooi64"(){bar = sparse<[[0]], [-1]> : vector<1xi64>} : () -> () 812 813// CHECK: "foof16"() {bar = sparse<0, -2.000000e+00> : vector<1x1x1xf16>} : () -> () 814 "foof16"(){bar = sparse<0, -2.0> : vector<1x1x1xf16>} : () -> () 815// CHECK: "foobf16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2.000000e+00, -1.000000e+00, 5.000000e+00]> : vector<2x2x2xbf16>} : () -> () 816 "foobf16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2.0, -1.0, 5.0]> : vector<2x2x2xbf16>} : () -> () 817// CHECK: "foof64"() {bar = sparse<0, -1.000000e+00> : vector<1xf64>} : () -> () 818 "foof64"(){bar = sparse<0, [-1.0]> : vector<1xf64>} : () -> () 819 return 820} 821 822// CHECK-LABEL: func @unknown_dialect_type() -> !bar<> { 823func.func @unknown_dialect_type() -> !bar<> { 824 // Unregistered dialect 'bar'. 825 // CHECK: "foo"() : () -> !bar<> 826 %0 = "foo"() : () -> !bar<> 827 828 // CHECK: "foo"() : () -> !bar.baz 829 %1 = "foo"() : () -> !bar<baz> 830 831 return %0 : !bar<> 832} 833 834// CHECK-LABEL: func @type_alias() -> i32 { 835!i32_type_alias = i32 836func.func @type_alias() -> !i32_type_alias { 837 838 // Return a non-aliased i32 type. 839 %0 = "foo"() : () -> i32 840 return %0 : i32 841} 842 843// CHECK-LABEL: func @no_integer_set_constraints( 844func.func @no_integer_set_constraints() { 845 // CHECK: affine.if [[$SET_TRUE]]() { 846 affine.if affine_set<() : ()> () { 847 } 848 return 849} 850 851// CHECK-LABEL: func @verbose_if( 852func.func @verbose_if(%N: index) { 853 %c = arith.constant 200 : index 854 855 // CHECK: affine.if #set{{.*}}(%{{.*}})[%{{.*}}, %{{.*}}] { 856 "affine.if"(%c, %N, %c) ({ 857 // CHECK-NEXT: "add" 858 %y = "add"(%c, %N) : (index, index) -> index 859 "affine.yield"() : () -> () 860 // CHECK-NEXT: } else { 861 }, { // The else region. 862 // CHECK-NEXT: "add" 863 %z = "add"(%c, %c) : (index, index) -> index 864 "affine.yield"() : () -> () 865 }) 866 { condition = #set0 } : (index, index, index) -> () 867 return 868} 869 870// CHECK-LABEL: func @terminator_with_regions 871func.func @terminator_with_regions() { 872 // Combine successors and regions in the same operation. 873 // CHECK: "region"()[^bb1] ({ 874 // CHECK: }) : () -> () 875 "region"()[^bb2] ({}) : () -> () 876^bb2: 877 return 878} 879 880// CHECK-LABEL: func @unregistered_term 881func.func @unregistered_term(%arg0 : i1) -> i1 { 882 // CHECK-NEXT: "unregistered_br"(%{{.*}})[^bb1] : (i1) -> () 883 "unregistered_br"(%arg0)[^bb1] : (i1) -> () 884 885^bb1(%arg1 : i1): 886 return %arg1 : i1 887} 888 889// CHECK-LABEL: func @dialect_attrs 890func.func @dialect_attrs() 891 // CHECK: attributes {dialect.attr = 10 892 attributes {dialect.attr = 10} { 893 return 894} 895 896// CHECK-LABEL: func private @_valid.function$name 897func.func private @_valid.function$name() 898 899// CHECK-LABEL: func private @external_func_arg_attrs(i32, i1 {dialect.attr = 10 : i64}, i32) 900func.func private @external_func_arg_attrs(i32, i1 {dialect.attr = 10 : i64}, i32) 901 902// CHECK-LABEL: func @func_arg_attrs(%{{.*}}: i1 {dialect.attr = 10 : i64}) 903func.func @func_arg_attrs(%arg0: i1 {dialect.attr = 10 : i64}) { 904 return 905} 906 907// CHECK-LABEL: func @func_result_attrs({{.*}}) -> (f32 {dialect.attr = 1 : i64}) 908func.func @func_result_attrs(%arg0: f32) -> (f32 {dialect.attr = 1}) { 909 return %arg0 : f32 910} 911 912// CHECK-LABEL: func private @empty_tuple(tuple<>) 913func.func private @empty_tuple(tuple<>) 914 915// CHECK-LABEL: func private @tuple_single_element(tuple<i32>) 916func.func private @tuple_single_element(tuple<i32>) 917 918// CHECK-LABEL: func private @tuple_multi_element(tuple<i32, i16, f32>) 919func.func private @tuple_multi_element(tuple<i32, i16, f32>) 920 921// CHECK-LABEL: func private @tuple_nested(tuple<tuple<tuple<i32>>>) 922func.func private @tuple_nested(tuple<tuple<tuple<i32>>>) 923 924// CHECK-LABEL: func @pretty_form_multi_result 925func.func @pretty_form_multi_result() -> (i16, i16) { 926 // CHECK: %{{.*}}:2 = "foo_div"() : () -> (i16, i16) 927 %quot, %rem = "foo_div"() : () -> (i16, i16) 928 return %quot, %rem : i16, i16 929} 930 931// CHECK-LABEL: func @pretty_form_multi_result_groups 932func.func @pretty_form_multi_result_groups() -> (i16, i16, i16, i16, i16) { 933 // CHECK: %[[RES:.*]]:5 = 934 // CHECK: return %[[RES]]#0, %[[RES]]#1, %[[RES]]#2, %[[RES]]#3, %[[RES]]#4 935 %group_1:2, %group_2, %group_3:2 = "foo_test"() : () -> (i16, i16, i16, i16, i16) 936 return %group_1#0, %group_1#1, %group_2, %group_3#0, %group_3#1 : i16, i16, i16, i16, i16 937} 938 939// CHECK-LABEL: func @pretty_dialect_attribute() 940func.func @pretty_dialect_attribute() { 941 // CHECK: "foo.unknown_op"() {foo = #foo.simple_attr} : () -> () 942 "foo.unknown_op"() {foo = #foo.simple_attr} : () -> () 943 944 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd>} : () -> () 945 "foo.unknown_op"() {foo = #foo.complexattr<abcd>} : () -> () 946 947 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd<f32>>} : () -> () 948 "foo.unknown_op"() {foo = #foo.complexattr<abcd<f32>>} : () -> () 949 950 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd<[f]$$[32]>>} : () -> () 951 "foo.unknown_op"() {foo = #foo.complexattr<abcd<[f]$$[32]>>} : () -> () 952 953 // CHECK: "foo.unknown_op"() {foo = #foo.dialect<!x@#!@#>} : () -> () 954 "foo.unknown_op"() {foo = #foo.dialect<!x@#!@#>} : () -> () 955 956 return 957} 958 959// CHECK-LABEL: func @pretty_dialect_type() 960func.func @pretty_dialect_type() { 961 962 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.simpletype 963 %0 = "foo.unknown_op"() : () -> !foo.simpletype 964 965 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd> 966 %1 = "foo.unknown_op"() : () -> !foo.complextype<abcd> 967 968 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>> 969 %2 = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>> 970 971 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd<[f]$$[32]>> 972 %3 = "foo.unknown_op"() : () -> !foo.complextype<abcd<[f]$$[32]>> 973 974 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.dialect<!x@#!@#> 975 %4 = "foo.unknown_op"() : () -> !foo.dialect<!x@#!@#> 976 977 return 978} 979 980// CHECK-LABEL: func @none_type 981func.func @none_type() { 982 // CHECK: "foo.unknown_op"() : () -> none 983 %none_val = "foo.unknown_op"() : () -> none 984 return 985} 986 987// CHECK-LABEL: func @scoped_names 988func.func @scoped_names() { 989 // CHECK-NEXT: "foo.region_op" 990 "foo.region_op"() ({ 991 // CHECK-NEXT: "foo.unknown_op" 992 %scoped_name = "foo.unknown_op"() : () -> none 993 "foo.terminator"() : () -> () 994 }, { 995 // CHECK: "foo.unknown_op" 996 %scoped_name = "foo.unknown_op"() : () -> none 997 "foo.terminator"() : () -> () 998 }) : () -> () 999 return 1000} 1001 1002// CHECK-LABEL: func @dialect_attribute_with_type 1003func.func @dialect_attribute_with_type() { 1004 // CHECK-NEXT: foo = #foo.attr : i32 1005 "foo.unknown_op"() {foo = #foo.attr : i32} : () -> () 1006} 1007 1008// CHECK-LABEL: @f16_special_values 1009func.func @f16_special_values() { 1010 // F16 NaNs. 1011 // CHECK: arith.constant 0x7C01 : f16 1012 %0 = arith.constant 0x7C01 : f16 1013 // CHECK: arith.constant 0x7FFF : f16 1014 %1 = arith.constant 0x7FFF : f16 1015 // CHECK: arith.constant 0xFFFF : f16 1016 %2 = arith.constant 0xFFFF : f16 1017 1018 // F16 positive infinity. 1019 // CHECK: arith.constant 0x7C00 : f16 1020 %3 = arith.constant 0x7C00 : f16 1021 // F16 negative infinity. 1022 // CHECK: arith.constant 0xFC00 : f16 1023 %4 = arith.constant 0xFC00 : f16 1024 1025 return 1026} 1027 1028// CHECK-LABEL: @f32_special_values 1029func.func @f32_special_values() { 1030 // F32 signaling NaNs. 1031 // CHECK: arith.constant 0x7F800001 : f32 1032 %0 = arith.constant 0x7F800001 : f32 1033 // CHECK: arith.constant 0x7FBFFFFF : f32 1034 %1 = arith.constant 0x7FBFFFFF : f32 1035 1036 // F32 quiet NaNs. 1037 // CHECK: arith.constant 0x7FC00000 : f32 1038 %2 = arith.constant 0x7FC00000 : f32 1039 // CHECK: arith.constant 0xFFFFFFFF : f32 1040 %3 = arith.constant 0xFFFFFFFF : f32 1041 1042 // F32 positive infinity. 1043 // CHECK: arith.constant 0x7F800000 : f32 1044 %4 = arith.constant 0x7F800000 : f32 1045 // F32 negative infinity. 1046 // CHECK: arith.constant 0xFF800000 : f32 1047 %5 = arith.constant 0xFF800000 : f32 1048 1049 return 1050} 1051 1052// CHECK-LABEL: @f64_special_values 1053func.func @f64_special_values() { 1054 // F64 signaling NaNs. 1055 // CHECK: arith.constant 0x7FF0000000000001 : f64 1056 %0 = arith.constant 0x7FF0000000000001 : f64 1057 // CHECK: arith.constant 0x7FF8000000000000 : f64 1058 %1 = arith.constant 0x7FF8000000000000 : f64 1059 1060 // F64 quiet NaNs. 1061 // CHECK: arith.constant 0x7FF0000001000000 : f64 1062 %2 = arith.constant 0x7FF0000001000000 : f64 1063 // CHECK: arith.constant 0xFFF0000001000000 : f64 1064 %3 = arith.constant 0xFFF0000001000000 : f64 1065 1066 // F64 positive infinity. 1067 // CHECK: arith.constant 0x7FF0000000000000 : f64 1068 %4 = arith.constant 0x7FF0000000000000 : f64 1069 // F64 negative infinity. 1070 // CHECK: arith.constant 0xFFF0000000000000 : f64 1071 %5 = arith.constant 0xFFF0000000000000 : f64 1072 1073 // Check that values that can't be represented with the default format, use 1074 // hex instead. 1075 // CHECK: arith.constant 0xC1CDC00000000000 : f64 1076 %6 = arith.constant 0xC1CDC00000000000 : f64 1077 1078 return 1079} 1080 1081// CHECK-LABEL: @bfloat16_special_values 1082func.func @bfloat16_special_values() { 1083 // bfloat16 signaling NaNs. 1084 // CHECK: arith.constant 0x7F81 : bf16 1085 %0 = arith.constant 0x7F81 : bf16 1086 // CHECK: arith.constant 0xFF81 : bf16 1087 %1 = arith.constant 0xFF81 : bf16 1088 1089 // bfloat16 quiet NaNs. 1090 // CHECK: arith.constant 0x7FC0 : bf16 1091 %2 = arith.constant 0x7FC0 : bf16 1092 // CHECK: arith.constant 0xFFC0 : bf16 1093 %3 = arith.constant 0xFFC0 : bf16 1094 1095 // bfloat16 positive infinity. 1096 // CHECK: arith.constant 0x7F80 : bf16 1097 %4 = arith.constant 0x7F80 : bf16 1098 // bfloat16 negative infinity. 1099 // CHECK: arith.constant 0xFF80 : bf16 1100 %5 = arith.constant 0xFF80 : bf16 1101 1102 return 1103} 1104 1105// We want to print floats in exponential notation with 6 significant digits, 1106// but it may lead to precision loss when parsing back, in which case we print 1107// the decimal form instead. 1108// CHECK-LABEL: @f32_potential_precision_loss() 1109func.func @f32_potential_precision_loss() { 1110 // CHECK: arith.constant -1.23697901 : f32 1111 %0 = arith.constant -1.23697901 : f32 1112 return 1113} 1114 1115// CHECK-LABEL: @special_float_values_in_tensors 1116func.func @special_float_values_in_tensors() { 1117 // CHECK: dense<0xFFFFFFFF> : tensor<4x4xf32> 1118 "foo"(){bar = dense<0xFFFFFFFF> : tensor<4x4xf32>} : () -> () 1119 // CHECK: dense<[{{\[}}0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32> 1120 "foo"(){bar = dense<[[0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32>} : () -> () 1121 // CHECK: dense<[0xFFFFFFFF, 0.000000e+00]> : tensor<2xf32> 1122 "foo"(){bar = dense<[0xFFFFFFFF, 0.0]> : tensor<2xf32>} : () -> () 1123 1124 // CHECK: sparse<[{{\[}}1, 1, 0], [0, 1, 1]], [0xFFFFFFFF, 0x7F800001]> 1125 "foo"(){bar = sparse<[[1,1,0],[0,1,1]], [0xFFFFFFFF, 0x7F800001]> : tensor<2x2x2xf32>} : () -> () 1126} 1127 1128// Test parsing of an op with multiple region arguments, and without a 1129// delimiter. 1130 1131// CHECK-LABEL: func @op_with_region_args 1132func.func @op_with_region_args() { 1133 // CHECK: "test.polyfor"() ({ 1134 // CHECK-NEXT: ^bb{{.*}}(%{{.*}}: index, %{{.*}}: index, %{{.*}}: index): 1135 test.polyfor %i, %j, %k { 1136 "foo"() : () -> () 1137 } 1138 return 1139} 1140 1141// Test allowing different name scopes for regions isolated from above. 1142 1143// CHECK-LABEL: func @op_with_passthrough_region_args 1144func.func @op_with_passthrough_region_args() { 1145 // CHECK: [[VAL:%.*]] = arith.constant 1146 %0 = arith.constant 10 : index 1147 1148 // CHECK: test.isolated_region [[VAL]] { 1149 // CHECK-NEXT: "foo.consumer"([[VAL]]) : (index) 1150 // CHECK-NEXT: } 1151 test.isolated_region %0 { 1152 "foo.consumer"(%0) : (index) -> () 1153 } 1154 1155 // CHECK: [[VAL:%.*]]:2 = "foo.op" 1156 %result:2 = "foo.op"() : () -> (index, index) 1157 1158 // CHECK: test.isolated_region [[VAL]]#1 { 1159 // CHECK-NEXT: "foo.consumer"([[VAL]]#1) : (index) 1160 // CHECK-NEXT: } 1161 test.isolated_region %result#1 { 1162 "foo.consumer"(%result#1) : (index) -> () 1163 } 1164 1165 return 1166} 1167 1168// CHECK-LABEL: func private @ptr_to_function() -> !unreg.ptr<() -> ()> 1169func.func private @ptr_to_function() -> !unreg.ptr<() -> ()> 1170 1171// CHECK-LABEL: func private @escaped_string_char(i1 {foo.value = "\0A"}) 1172func.func private @escaped_string_char(i1 {foo.value = "\n"}) 1173 1174// CHECK-LABEL: func @parse_integer_literal_test 1175func.func @parse_integer_literal_test() { 1176 // CHECK: test.parse_integer_literal : 5 1177 test.parse_integer_literal : 5 1178 return 1179} 1180 1181// CHECK-LABEL: func @parse_wrapped_keyword_test 1182func.func @parse_wrapped_keyword_test() { 1183 // CHECK: test.parse_wrapped_keyword foo.keyword 1184 test.parse_wrapped_keyword foo.keyword 1185 return 1186} 1187 1188// CHECK-LABEL: func @"\22_string_symbol_reference\22" 1189func.func @"\"_string_symbol_reference\""() { 1190 // CHECK: ref = @"\22_string_symbol_reference\22" 1191 "foo.symbol_reference"() {ref = @"\"_string_symbol_reference\""} : () -> () 1192 return 1193} 1194 1195// CHECK-LABEL: func private @parse_opaque_attr_escape 1196func.func private @parse_opaque_attr_escape() { 1197 // CHECK: value = #foo<"\"escaped\\\n\""> 1198 "foo.constant"() {value = #foo<"\"escaped\\\n\"">} : () -> () 1199} 1200 1201// CHECK-LABEL: func private @string_attr_name 1202// CHECK-SAME: {"0 . 0", nested = {"0 . 0"}} 1203func.func private @string_attr_name() attributes {"0 . 0", nested = {"0 . 0"}} 1204 1205// CHECK-LABEL: func private @nested_reference 1206// CHECK: ref = @some_symbol::@some_nested_symbol 1207func.func private @nested_reference() attributes {test.ref = @some_symbol::@some_nested_symbol } 1208 1209// CHECK-LABEL: func @custom_asm_names 1210func.func @custom_asm_names() -> (i32, i32, i32, i32, i32, i32) { 1211 // CHECK: %[[FIRST:first.*]], %[[MIDDLE:middle_results.*]]:2, %[[LAST:[0-9]+]] 1212 %0, %1:2, %2 = "test.asm_interface_op"() : () -> (i32, i32, i32, i32) 1213 1214 // CHECK: %[[FIRST_2:first.*]], %[[LAST_2:[0-9]+]] 1215 %3, %4 = "test.asm_interface_op"() : () -> (i32, i32) 1216 1217 // CHECK: return %[[FIRST]], %[[MIDDLE]]#0, %[[MIDDLE]]#1, %[[LAST]], %[[FIRST_2]], %[[LAST_2]] 1218 return %0, %1#0, %1#1, %2, %3, %4 : i32, i32, i32, i32, i32, i32 1219} 1220 1221 1222// CHECK-LABEL: func @pretty_names 1223 1224// This tests the behavior 1225func.func @pretty_names() { 1226 // Simple case, should parse and print as %x being an implied 'name' 1227 // attribute. 1228 %x = test.string_attr_pretty_name 1229 // CHECK: %x = test.string_attr_pretty_name 1230 // CHECK-NOT: attributes 1231 1232 // This specifies an explicit name, which should override the result. 1233 %YY = test.string_attr_pretty_name attributes { names = ["y"] } 1234 // CHECK: %y = test.string_attr_pretty_name 1235 // CHECK-NOT: attributes 1236 1237 // Conflicts with the 'y' name, so need an explicit attribute. 1238 %0 = "test.string_attr_pretty_name"() { names = ["y"]} : () -> i32 1239 // CHECK: %y_0 = test.string_attr_pretty_name attributes {names = ["y"]} 1240 1241 // Name contains a space. 1242 %1 = "test.string_attr_pretty_name"() { names = ["space name"]} : () -> i32 1243 // CHECK: %space_name = test.string_attr_pretty_name attributes {names = ["space name"]} 1244 1245 "unknown.use"(%x, %YY, %0, %1) : (i32, i32, i32, i32) -> () 1246 1247 // Multi-result support. 1248 1249 %a, %b, %c = test.string_attr_pretty_name 1250 // CHECK: %a, %b, %c = test.string_attr_pretty_name 1251 // CHECK-NOT: attributes 1252 1253 %q:3, %r = test.string_attr_pretty_name 1254 // CHECK: %q, %q_1, %q_2, %r = test.string_attr_pretty_name attributes {names = ["q", "q", "q", "r"]} 1255 1256 // CHECK: return 1257 return 1258} 1259 1260 1261// This tests the behavior of "default dialect": 1262// operations like `test.default_dialect` can define a default dialect 1263// used in nested region. 1264// CHECK-LABEL: func @default_dialect 1265func.func @default_dialect(%bool : i1) { 1266 test.default_dialect { 1267 // The test dialect is the default in this region, the following two 1268 // operations are parsed identically. 1269 // CHECK-NOT: test.parse_integer_literal 1270 parse_integer_literal : 5 1271 // CHECK: parse_integer_literal : 6 1272 test.parse_integer_literal : 6 1273 // Verify that only an op prefix is stripped, not an attribute value for 1274 // example. 1275 // CHECK: "test.op_with_attr"() {test.attr = "test.value"} : () -> () 1276 "test.op_with_attr"() {test.attr = "test.value"} : () -> () 1277 // Verify that the prefix is not stripped when it can lead to ambiguity. 1278 // CHECK: test.op.with_dot_in_name 1279 test.op.with_dot_in_name 1280 // This is an unregistered operation, the printing/parsing is handled by the 1281 // dialect, and the dialect prefix should not be stripped while printing 1282 // because of potential ambiguity. 1283 // CHECK: test.dialect_custom_printer.with.dot 1284 test.dialect_custom_printer.with.dot 1285 "test.terminator"() : ()->() 1286 } 1287 // The same operation outside of the region does not have an func. prefix. 1288 // CHECK: return 1289 func.return 1290} 1291 1292// CHECK-LABEL: func @unreachable_dominance_violation_ok 1293func.func @unreachable_dominance_violation_ok() -> i1 { 1294// CHECK: [[VAL:%.*]] = arith.constant false 1295// CHECK: return [[VAL]] : i1 1296// CHECK: ^bb1: // no predecessors 1297// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1) 1298// CHECK: cf.br ^bb3 1299// CHECK: ^bb2: // pred: ^bb2 1300// CHECK: cf.br ^bb2 1301// CHECK: ^bb3: // pred: ^bb1 1302// CHECK: [[VAL3]] = "foo"() : () -> i64 1303// CHECK: return [[VAL2]]#1 : i1 1304// CHECK: } 1305 %c = arith.constant false 1306 return %c : i1 1307^bb1: 1308 // %1 is not dominated by it's definition, but block is not reachable. 1309 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 1310 cf.br ^bb3 1311^bb2: 1312 cf.br ^bb2 1313^bb3: 1314 %1 = "foo"() : ()->i64 1315 return %2#1 : i1 1316} 1317 1318// CHECK-LABEL: func @graph_region_in_hierarchy_ok 1319func.func @graph_region_in_hierarchy_ok() -> i64 { 1320// CHECK: cf.br ^bb2 1321// CHECK: ^bb1: 1322// CHECK: test.graph_region { 1323// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1) 1324// CHECK: } 1325// CHECK: cf.br ^bb3 1326// CHECK: ^bb2: // pred: ^bb0 1327// CHECK: [[VAL3]] = "foo"() : () -> i64 1328// CHECK: cf.br ^bb1 1329// CHECK: ^bb3: // pred: ^bb1 1330// CHECK: return [[VAL3]] : i64 1331// CHECK: } 1332 cf.br ^bb2 1333^bb1: 1334 test.graph_region { 1335 // %1 is well-defined here, since bb2 dominates bb1. 1336 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 1337 } 1338 cf.br ^bb4 1339^bb2: 1340 %1 = "foo"() : ()->i64 1341 cf.br ^bb1 1342^bb4: 1343 return %1 : i64 1344} 1345 1346// CHECK-LABEL: func @graph_region_kind 1347func.func @graph_region_kind() -> () { 1348// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1) 1349// CHECK: [[VAL3]] = "baz"([[VAL2]]#0) : (i1) -> i64 1350 test.graph_region { 1351 // %1 OK here in in graph region. 1352 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 1353 %1 = "baz"(%2#0) : (i1) -> (i64) 1354 } 1355 return 1356} 1357 1358// CHECK-LABEL: func @graph_region_inside_ssacfg_region 1359func.func @graph_region_inside_ssacfg_region() -> () { 1360// CHECK: "test.ssacfg_region" 1361// CHECK: [[VAL3:%.*]] = "baz"() : () -> i64 1362// CHECK: test.graph_region { 1363// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3]]) : (i64) -> (i1, i1, i1) 1364// CHECK: } 1365// CHECK: [[VAL4:.*]] = "baz"() : () -> i64 1366 "test.ssacfg_region"() ({ 1367 %1 = "baz"() : () -> (i64) 1368 test.graph_region { 1369 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 1370 } 1371 %3 = "baz"() : () -> (i64) 1372 }) : () -> () 1373 return 1374} 1375 1376// CHECK-LABEL: func @graph_region_in_graph_region_ok 1377func.func @graph_region_in_graph_region_ok() -> () { 1378// CHECK: test.graph_region { 1379// CHECK: test.graph_region { 1380// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1) 1381// CHECK: } 1382// CHECK: [[VAL3]] = "foo"() : () -> i64 1383// CHECK: } 1384test.graph_region { 1385 test.graph_region { 1386 // %1 is well-defined here since defined in graph region 1387 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1) 1388 } 1389 %1 = "foo"() : ()->i64 1390 "test.terminator"() : ()->() 1391 } 1392 return 1393} 1394 1395// CHECK: test.graph_region { 1396test.graph_region { 1397// CHECK: [[VAL1:%.*]] = "op1"([[VAL3:%.*]]) : (i32) -> i32 1398// CHECK: [[VAL2:%.*]] = "test.ssacfg_region"([[VAL1]], [[VAL2]], [[VAL3]], [[VAL4:%.*]]) ({ 1399// CHECK: [[VAL5:%.*]] = "op2"([[VAL1]], [[VAL2]], [[VAL3]], [[VAL4]]) : (i32, i32, i32, i32) -> i32 1400// CHECK: }) : (i32, i32, i32, i32) -> i32 1401// CHECK: [[VAL3]] = "op2"([[VAL1]], [[VAL4]]) : (i32, i32) -> i32 1402// CHECK: [[VAL4]] = "op3"([[VAL1]]) : (i32) -> i32 1403 %1 = "op1"(%3) : (i32) -> (i32) 1404 %2 = "test.ssacfg_region"(%1, %2, %3, %4) ({ 1405 %5 = "op2"(%1, %2, %3, %4) : 1406 (i32, i32, i32, i32) -> (i32) 1407 }) : (i32, i32, i32, i32) -> (i32) 1408 %3 = "op2"(%1, %4) : (i32, i32) -> (i32) 1409 %4 = "op3"(%1) : (i32) -> (i32) 1410} 1411 1412// CHECK: "unregistered_func_might_have_graph_region"() ({ 1413// CHECK: [[VAL1:%.*]] = "foo"([[VAL1]], [[VAL2:%.*]]) : (i64, i64) -> i64 1414// CHECK: [[VAL2]] = "bar"([[VAL1]]) 1415"unregistered_func_might_have_graph_region"() ({ 1416 %1 = "foo"(%1, %2) : (i64, i64) -> i64 1417 %2 = "bar"(%1) : (i64) -> i64 1418 "unregistered_terminator"() : () -> () 1419}) {sym_name = "unregistered_op_dominance_violation_ok", function_type = () -> i1} : () -> () 1420 1421// This is an unregister operation, the printing/parsing is handled by the dialect. 1422// CHECK: test.dialect_custom_printer custom_format 1423test.dialect_custom_printer custom_format 1424 1425// This is a registered operation with no custom parser and printer, and should 1426// be handled by the dialect. 1427// CHECK: test.dialect_custom_format_fallback custom_format_fallback 1428test.dialect_custom_format_fallback custom_format_fallback 1429 1430// Check that an op with an optional result parses f80 as type. 1431// CHECK: test.format_optional_result_d_op : f80 1432test.format_optional_result_d_op : f80 1433