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