1487 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect %s | FileCheck %s2// RUN: mlir-opt -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect | FileCheck %s3// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-op-generic %s | FileCheck %s -check-prefix GENERIC4// RUN: mlir-opt -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect -mlir-print-op-generic | FileCheck %s -check-prefix GENERIC5 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: Placeholder35 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) -> f3250func.func private @foo(i32, i64) -> f3251 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 space105 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"() : () -> i64169 %1 = "foo"() : ()->i64170 // CHECK: "bar"(%{{.*}}) : (i64) -> (i1, i1, i1)171 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)172 // CHECK: return %{{.*}}#1173 return %2#1 : i1174// 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 return184// CHECK: }185}186 187// CHECK-LABEL: func @block_label_empty_list188func.func @block_label_empty_list() {189^bb0():190 return191}192 193// CHECK-LABEL: func @multiblock() {194func.func @multiblock() {195 return // CHECK: return196^bb1: // CHECK: ^bb1: // no predecessors197 cf.br ^bb4 // CHECK: cf.br ^bb3198^bb2: // CHECK: ^bb2: // pred: ^bb2199 cf.br ^bb2 // CHECK: cf.br ^bb2200^bb4: // CHECK: ^bb3: // pred: ^bb1201 return // CHECK: return202} // CHECK: }203 204// CHECK-LABEL: func @emptyMLF() {205func.func @emptyMLF() {206 return // CHECK: return207} // 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) -> i2212 %b = "foo"(%c) : (i1) -> (i2)213 return %b : i2 // CHECK: return %{{.*}} : i2214} // 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, i32221} // 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"() : () -> i64248 %a = "foo"() : ()->i64249 // CHECK: affine.for %{{.*}} = 1 to 10 {250 affine.for %i = 1 to 10 {251 // CHECK: %{{.*}} = "doo"() : () -> f32252 %b = "doo"() : ()->f32253 // CHECK: "bar"(%{{.*}}, %{{.*}}) : (i64, f32) -> ()254 "bar"(%a, %b) : (i64, f32) -> ()255 // CHECK: }256 }257 // CHECK: return258 return259 // 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: return272} // 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: return289} // 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 : i32294 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: return300} // 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: return310} // CHECK: }311 312// CHECK-LABEL: func @loop_bounds(%{{.*}}: index) {313func.func @loop_bounds(%N : index) {314 // CHECK: %{{.*}} = "foo"(%{{.*}}) : (index) -> index315 %s = "foo"(%N) : (index) -> index316 // CHECK: affine.for %{{.*}} = %{{.*}} to %{{.*}}317 affine.for %i = %s to %N {318 // CHECK: affine.for %{{.*}} = #map{{[0-9]*}}(%{{.*}}) to 0319 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 : index329 %c = arith.constant 30 : index330 // 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: return341} // CHECK: }342 343// CHECK-LABEL: func @ifinst(%{{.*}}: index) {344func.func @ifinst(%N: index) {345 %c = arith.constant 200 : index // CHECK: %{{.*}} = arith.constant 200346 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 : i32349 // CHECK: %{{.*}} = arith.constant 1 : i32350 %y = "add"(%x, %i) : (i32, index) -> i32 // CHECK: %{{.*}} = "add"(%{{.*}}, %{{.*}}) : (i32, index) -> i32351 %z = "mul"(%y, %y) : (i32, i32) -> i32 // CHECK: %{{.*}} = "mul"(%{{.*}}, %{{.*}}) : (i32, i32) -> i32352 } 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 : index355 %u = arith.constant 1 : index356 // 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 : i32360 }361 } // CHECK: }362 } // CHECK: }363 return // CHECK: return364} // CHECK:}365 366// CHECK-LABEL: func @simple_ifinst(%{{.*}}: index) {367func.func @simple_ifinst(%N: index) {368 %c = arith.constant 200 : index // CHECK: %{{.*}} = arith.constant 200369 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 : i32372 // CHECK: %{{.*}} = arith.constant 1 : i32373 %y = "add"(%x, %i) : (i32, index) -> i32 // CHECK: %{{.*}} = "add"(%{{.*}}, %{{.*}}) : (i32, index) -> i32374 %z = "mul"(%y, %y) : (i32, i32) -> i32 // CHECK: %{{.*}} = "mul"(%{{.*}}, %{{.*}}) : (i32, i32) -> i32375 } // CHECK: }376 } // CHECK: }377 return // CHECK: return378} // 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 return422}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 ^bb2429 430^bb1: // CHECK: ^bb1: // pred: ^bb2431 // 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, i8435 return %1#0, %1#1 : i16, i8436 437^bb2: // CHECK: ^bb2: // pred: ^bb0438 // CHECK: %{{.*}}:2 = "bar"(%{{.*}}#0, %{{.*}}#1) : (i1, i17) -> (i11, f32)439 %2:2 = "bar"(%0#0, %0#1) : (i1, i17) -> (i11, f32)440 cf.br ^bb1441}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, i8453}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 true467// CHECK: return %{{.*}}, %{{.*}} : i1, i17468 "func.return"(%true, %a) : (i1, i17) -> ()469 470^bb3(%b : i1, %c : i17):471// CHECK: return %{{.*}}, %{{.*}} : i1, i17472 "func.return"(%b, %c) : (i1, i17) -> ()473}474 475// CHECK-LABEL: func @condbr_simple476func.func @condbr_simple() -> (i32) {477 %cond = "foo"() : () -> i1478 %a = "bar"() : () -> i32479 %b = "bar"() : () -> i64480 // 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: ^bb0484^bb1(%x : i32):485 cf.br ^bb2(%b: i64)486 487// CHECK: ^bb2({{.*}}: i64): // 2 preds: ^bb0, ^bb1488^bb2(%y : i64):489 %z = "foo"() : () -> i32490 return %z : i32491}492 493// CHECK-LABEL: func @condbr_moarargs494func.func @condbr_moarargs() -> (i32) {495 %cond = "foo"() : () -> i1496 %a = "bar"() : () -> i32497 %b = "bar"() : () -> i64498 // 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 : i32503 504^bb2(%x2 : i64, %y2 : i32, %z2 : i32):505 %z = "foo"() : () -> i32506 return %z : i32507}508 509 510// Test pretty printing of constant names.511// CHECK-LABEL: func @constants512func.func @constants() -> (i32, i23, i23, i1, i1) {513 // CHECK: %{{.*}} = arith.constant 42 : i32514 %x = arith.constant 42 : i32515 // CHECK: %{{.*}} = arith.constant 17 : i23516 %y = arith.constant 17 : i23517 518 // This is a redundant definition of 17, the asmprinter gives it a unique name519 // CHECK: %{{.*}} = arith.constant 17 : i23520 %z = arith.constant 17 : i23521 522 // CHECK: %{{.*}} = arith.constant true523 %t = arith.constant true524 // CHECK: %{{.*}} = arith.constant false525 %f = arith.constant false526 527 // The trick to parse type declarations should not interfere with hex528 // literals.529 // CHECK: %{{.*}} = arith.constant 3890 : i32530 %h = arith.constant 0xf32 : i32531 532 // CHECK: return %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}533 return %x, %y, %z, %t, %f : i32, i23, i23, i1, i1534}535 536// CHECK-LABEL: func @typeattr537func.func @typeattr() -> () {538^bb0:539// CHECK: "foo"() {bar = tensor<*xf32>} : () -> ()540 "foo"(){bar = tensor<*xf32>} : () -> ()541 return542}543 544// CHECK-LABEL: func @stringquote545func.func @stringquote() -> () {546^bb0:547 // CHECK: "foo"() {bar = "a\22quoted\22string"} : () -> ()548 "foo"(){bar = "a\"quoted\"string"} : () -> ()549 550 // CHECK-NEXT: "typed_string" : !foo.string551 "foo"(){bar = "typed_string" : !foo.string} : () -> ()552 return553}554 555// CHECK-LABEL: func @unitAttrs556func.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 return566}567 568// CHECK-LABEL: func @floatAttrs569func.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 return574}575 576// CHECK-LABEL: func private @externalfuncattr577func.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 @funcattrempty582func.func private @funcattrempty() -> ()583 attributes {}584 585// CHECK-LABEL: func private @funcattr586func.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 return591}592 593// CHECK-LABEL: func @funcattrwithblock594func.func @funcattrwithblock() -> ()595 attributes {} {596^bb0:597 return598}599 600// CHECK-LABEL: func @funcsimplemap601#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 : i32621 }622 }623 }624 }625 }626 }627 return628}629 630// CHECK-LABEL: func @splattensorattr631func.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 return656}657 658// CHECK-LABEL: func @densetensorattr659func.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 // CHECK: dense<> : tensor<0xcomplex<i64>>734 "complex_attr"(){bar = dense<> : tensor<0xcomplex<i64>>} : () -> ()735 // CHECK: dense<> : tensor<2x0xcomplex<i64>>736 "complex_attr"(){bar = dense<> : tensor<2x0xcomplex<i64>>} : () -> ()737 return738}739 740// CHECK-LABEL: func @densevectorattr741func.func @densevectorattr() -> () {742^bb0:743// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck.744// CHECK: "fooi8"() {bar = dense<5> : vector<1x1x1xi8>} : () -> ()745 "fooi8"(){bar = dense<[[[5]]]> : vector<1x1x1xi8>} : () -> ()746// CHECK: "fooi16"() {bar = dense<-5> : vector<1x1x1xi16>} : () -> ()747 "fooi16"(){bar = dense<[[[-5]]]> : vector<1x1x1xi16>} : () -> ()748// CHECK: "foo32"() {bar = dense<5> : vector<1x1x1xi32>} : () -> ()749 "foo32"(){bar = dense<[[[5]]]> : vector<1x1x1xi32>} : () -> ()750// CHECK: "fooi64"() {bar = dense<-5> : vector<1x1x1xi64>} : () -> ()751 "fooi64"(){bar = dense<[[[-5]]]> : vector<1x1x1xi64>} : () -> ()752 753// CHECK: "foo3"() {bar = dense<{{\[\[\[}}5, -6, 1, 2]], {{\[\[}}7, 8, 3, 4]]]> : vector<2x1x4xi32>} : () -> ()754 "foo3"(){bar = dense<[[[5, -6, 1, 2]], [[7, 8, 3, 4]]]> : vector<2x1x4xi32>} : () -> ()755 756// CHECK: "float1"() {bar = dense<5.000000e+00> : vector<1x1x1xf32>} : () -> ()757 "float1"(){bar = dense<[[[5.0]]]> : vector<1x1x1xf32>} : () -> ()758 759// 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>} : () -> ()760 "bfloat16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xbf16>} : () -> ()761// 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>} : () -> ()762 "float16"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf16>} : () -> ()763// 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>} : () -> ()764 "float32"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf32>} : () -> ()765// 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>} : () -> ()766 "float64"(){bar = dense<[[[-5.0, 6.0, 1.0, 2.0]], [[7.0, -8.0, 3.0, 4.0]]]> : vector<2x1x4xf64>} : () -> ()767 return768}769 770// CHECK-LABEL: func @sparsetensorattr771func.func @sparsetensorattr() -> () {772^bb0:773// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck.774// CHECK: "fooi8"() {bar = sparse<0, -2> : tensor<1x1x1xi8>} : () -> ()775 "fooi8"(){bar = sparse<0, -2> : tensor<1x1x1xi8>} : () -> ()776// CHECK: "fooi16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2, -1, 5]> : tensor<2x2x2xi16>} : () -> ()777 "fooi16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2, -1, 5]> : tensor<2x2x2xi16>} : () -> ()778// CHECK: "fooi32"() {bar = sparse<> : tensor<1x1xi32>} : () -> ()779 "fooi32"(){bar = sparse<> : tensor<1x1xi32>} : () -> ()780// CHECK: "fooi64"() {bar = sparse<0, -1> : tensor<1xi64>} : () -> ()781 "fooi64"(){bar = sparse<[0], [-1]> : tensor<1xi64>} : () -> ()782// CHECK: "foo2"() {bar = sparse<> : tensor<0xi32>} : () -> ()783 "foo2"(){bar = sparse<> : tensor<0xi32>} : () -> ()784// CHECK: "foo3"() {bar = sparse<> : tensor<i32>} : () -> ()785 "foo3"(){bar = sparse<> : tensor<i32>} : () -> ()786 787// CHECK: "foof16"() {bar = sparse<0, -2.000000e+00> : tensor<1x1x1xf16>} : () -> ()788 "foof16"(){bar = sparse<0, -2.0> : tensor<1x1x1xf16>} : () -> ()789// CHECK: "foobf16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2.000000e+00, -1.000000e+00, 5.000000e+00]> : tensor<2x2x2xbf16>} : () -> ()790 "foobf16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2.0, -1.0, 5.0]> : tensor<2x2x2xbf16>} : () -> ()791// CHECK: "foof32"() {bar = sparse<> : tensor<1x0x1xf32>} : () -> ()792 "foof32"(){bar = sparse<> : tensor<1x0x1xf32>} : () -> ()793// CHECK: "foof64"() {bar = sparse<0, -1.000000e+00> : tensor<1xf64>} : () -> ()794 "foof64"(){bar = sparse<[[0]], [-1.0]> : tensor<1xf64>} : () -> ()795// CHECK: "foof320"() {bar = sparse<> : tensor<0xf32>} : () -> ()796 "foof320"(){bar = sparse<> : tensor<0xf32>} : () -> ()797// CHECK: "foof321"() {bar = sparse<> : tensor<f32>} : () -> ()798 "foof321"(){bar = sparse<> : tensor<f32>} : () -> ()799 800// CHECK: "foostr"() {bar = sparse<0, "foo"> : tensor<1x1x1x!unknown<>>} : () -> ()801 "foostr"(){bar = sparse<0, "foo"> : tensor<1x1x1x!unknown<>>} : () -> ()802// CHECK: "foostr"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}"a", "b", "c"]> : tensor<2x2x2x!unknown<>>} : () -> ()803 "foostr"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], ["a", "b", "c"]> : tensor<2x2x2x!unknown<>>} : () -> ()804 return805}806 807// CHECK-LABEL: func @sparsevectorattr808func.func @sparsevectorattr() -> () {809^bb0:810// NOTE: The {{\[\[}} syntax is because "[[" confuses FileCheck.811// CHECK: "fooi8"() {bar = sparse<0, -2> : vector<1x1x1xi8>} : () -> ()812 "fooi8"(){bar = sparse<0, -2> : vector<1x1x1xi8>} : () -> ()813// CHECK: "fooi16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2, -1, 5]> : vector<2x2x2xi16>} : () -> ()814 "fooi16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2, -1, 5]> : vector<2x2x2xi16>} : () -> ()815// CHECK: "fooi32"() {bar = sparse<> : vector<1x1xi32>} : () -> ()816 "fooi32"(){bar = sparse<> : vector<1x1xi32>} : () -> ()817// CHECK: "fooi64"() {bar = sparse<0, -1> : vector<1xi64>} : () -> ()818 "fooi64"(){bar = sparse<[[0]], [-1]> : vector<1xi64>} : () -> ()819 820// CHECK: "foof16"() {bar = sparse<0, -2.000000e+00> : vector<1x1x1xf16>} : () -> ()821 "foof16"(){bar = sparse<0, -2.0> : vector<1x1x1xf16>} : () -> ()822// CHECK: "foobf16"() {bar = sparse<{{\[\[}}1, 1, 0], {{\[}}0, 1, 0], {{\[}}0, 0, 1]], {{\[}}2.000000e+00, -1.000000e+00, 5.000000e+00]> : vector<2x2x2xbf16>} : () -> ()823 "foobf16"(){bar = sparse<[[1, 1, 0], [0, 1, 0], [0, 0, 1]], [2.0, -1.0, 5.0]> : vector<2x2x2xbf16>} : () -> ()824// CHECK: "foof64"() {bar = sparse<0, -1.000000e+00> : vector<1xf64>} : () -> ()825 "foof64"(){bar = sparse<0, [-1.0]> : vector<1xf64>} : () -> ()826 return827}828 829// CHECK-LABEL: func @unknown_dialect_type() -> !bar<> {830func.func @unknown_dialect_type() -> !bar<> {831 // Unregistered dialect 'bar'.832 // CHECK: "foo"() : () -> !bar<>833 %0 = "foo"() : () -> !bar<>834 835 // CHECK: "foo"() : () -> !bar.baz836 %1 = "foo"() : () -> !bar<baz>837 838 return %0 : !bar<>839}840 841// CHECK-LABEL: func @type_alias() -> i32 {842!i32_type_alias = i32843func.func @type_alias() -> !i32_type_alias {844 845 // Return a non-aliased i32 type.846 %0 = "foo"() : () -> i32847 return %0 : i32848}849 850// CHECK-LABEL: func @no_integer_set_constraints(851func.func @no_integer_set_constraints() {852 // CHECK: affine.if [[$SET_TRUE]]() {853 affine.if affine_set<() : ()> () {854 }855 return856}857 858// CHECK-LABEL: func @verbose_if(859func.func @verbose_if(%N: index) {860 %c = arith.constant 200 : index861 862 // CHECK: affine.if #set{{.*}}(%{{.*}})[%{{.*}}, %{{.*}}] {863 "affine.if"(%c, %N, %c) ({864 // CHECK-NEXT: "add"865 %y = "add"(%c, %N) : (index, index) -> index866 "affine.yield"() : () -> ()867 // CHECK-NEXT: } else {868 }, { // The else region.869 // CHECK-NEXT: "add"870 %z = "add"(%c, %c) : (index, index) -> index871 "affine.yield"() : () -> ()872 })873 { condition = #set0 } : (index, index, index) -> ()874 return875}876 877// CHECK-LABEL: func @terminator_with_regions878func.func @terminator_with_regions() {879 // Combine successors and regions in the same operation.880 // CHECK: "region"()[^bb1] ({881 // CHECK: }) : () -> ()882 "region"()[^bb2] ({}) : () -> ()883^bb2:884 return885}886 887// CHECK-LABEL: func @unregistered_term888func.func @unregistered_term(%arg0 : i1) -> i1 {889 // CHECK-NEXT: "unregistered_br"(%{{.*}})[^bb1] : (i1) -> ()890 "unregistered_br"(%arg0)[^bb1] : (i1) -> ()891 892^bb1(%arg1 : i1):893 return %arg1 : i1894}895 896// CHECK-LABEL: func @dialect_attrs897func.func @dialect_attrs()898 // CHECK: attributes {dialect.attr = 10899 attributes {dialect.attr = 10} {900 return901}902 903// CHECK-LABEL: func private @_valid.function$name904func.func private @_valid.function$name()905 906// CHECK-LABEL: func private @external_func_arg_attrs(i32, i1 {dialect.attr = 10 : i64}, i32)907func.func private @external_func_arg_attrs(i32, i1 {dialect.attr = 10 : i64}, i32)908 909// CHECK-LABEL: func @func_arg_attrs(%{{.*}}: i1 {dialect.attr = 10 : i64})910func.func @func_arg_attrs(%arg0: i1 {dialect.attr = 10 : i64}) {911 return912}913 914// CHECK-LABEL: func @func_result_attrs({{.*}}) -> (f32 {dialect.attr = 1 : i64})915func.func @func_result_attrs(%arg0: f32) -> (f32 {dialect.attr = 1}) {916 return %arg0 : f32917}918 919// CHECK-LABEL: func private @empty_tuple(tuple<>)920func.func private @empty_tuple(tuple<>)921 922// CHECK-LABEL: func private @tuple_single_element(tuple<i32>)923func.func private @tuple_single_element(tuple<i32>)924 925// CHECK-LABEL: func private @tuple_multi_element(tuple<i32, i16, f32>)926func.func private @tuple_multi_element(tuple<i32, i16, f32>)927 928// CHECK-LABEL: func private @tuple_nested(tuple<tuple<tuple<i32>>>)929func.func private @tuple_nested(tuple<tuple<tuple<i32>>>)930 931// CHECK-LABEL: func @pretty_form_multi_result932func.func @pretty_form_multi_result() -> (i16, i16) {933 // CHECK: %{{.*}}:2 = "foo_div"() : () -> (i16, i16)934 %quot, %rem = "foo_div"() : () -> (i16, i16)935 return %quot, %rem : i16, i16936}937 938// CHECK-LABEL: func @pretty_form_multi_result_groups939func.func @pretty_form_multi_result_groups() -> (i16, i16, i16, i16, i16) {940 // CHECK: %[[RES:.*]]:5 =941 // CHECK: return %[[RES]]#0, %[[RES]]#1, %[[RES]]#2, %[[RES]]#3, %[[RES]]#4942 %group_1:2, %group_2, %group_3:2 = "foo_test"() : () -> (i16, i16, i16, i16, i16)943 return %group_1#0, %group_1#1, %group_2, %group_3#0, %group_3#1 : i16, i16, i16, i16, i16944}945 946// CHECK-LABEL: func @pretty_dialect_attribute()947func.func @pretty_dialect_attribute() {948 // CHECK: "foo.unknown_op"() {foo = #foo.simple_attr} : () -> ()949 "foo.unknown_op"() {foo = #foo.simple_attr} : () -> ()950 951 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd>} : () -> ()952 "foo.unknown_op"() {foo = #foo.complexattr<abcd>} : () -> ()953 954 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd<f32>>} : () -> ()955 "foo.unknown_op"() {foo = #foo.complexattr<abcd<f32>>} : () -> ()956 957 // CHECK: "foo.unknown_op"() {foo = #foo.complexattr<abcd<[f]$$[32]>>} : () -> ()958 "foo.unknown_op"() {foo = #foo.complexattr<abcd<[f]$$[32]>>} : () -> ()959 960 // CHECK: "foo.unknown_op"() {foo = #foo.dialect<!x@#!@#>} : () -> ()961 "foo.unknown_op"() {foo = #foo.dialect<!x@#!@#>} : () -> ()962 963 return964}965 966// CHECK-LABEL: func @pretty_dialect_type()967func.func @pretty_dialect_type() {968 969 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.simpletype970 %0 = "foo.unknown_op"() : () -> !foo.simpletype971 972 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd>973 %1 = "foo.unknown_op"() : () -> !foo.complextype<abcd>974 975 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>>976 %2 = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>>977 978 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.complextype<abcd<[f]$$[32]>>979 %3 = "foo.unknown_op"() : () -> !foo.complextype<abcd<[f]$$[32]>>980 981 // CHECK: %{{.*}} = "foo.unknown_op"() : () -> !foo.dialect<!x@#!@#>982 %4 = "foo.unknown_op"() : () -> !foo.dialect<!x@#!@#>983 984 return985}986 987// CHECK-LABEL: func @none_type988func.func @none_type() {989 // CHECK: "foo.unknown_op"() : () -> none990 %none_val = "foo.unknown_op"() : () -> none991 return992}993 994// CHECK-LABEL: func @scoped_names995func.func @scoped_names() {996 // CHECK-NEXT: "foo.region_op"997 "foo.region_op"() ({998 // CHECK-NEXT: "foo.unknown_op"999 %scoped_name = "foo.unknown_op"() : () -> none1000 "foo.terminator"() : () -> ()1001 }, {1002 // CHECK: "foo.unknown_op"1003 %scoped_name = "foo.unknown_op"() : () -> none1004 "foo.terminator"() : () -> ()1005 }) : () -> ()1006 return1007}1008 1009// CHECK-LABEL: func @dialect_attribute_with_type1010func.func @dialect_attribute_with_type() {1011 // CHECK-NEXT: foo = #foo.attr : i321012 "foo.unknown_op"() {foo = #foo.attr : i32} : () -> ()1013}1014 1015// CHECK-LABEL: @f16_special_values1016func.func @f16_special_values() {1017 // F16 NaNs.1018 // CHECK: arith.constant 0x7C01 : f161019 %0 = arith.constant 0x7C01 : f161020 // CHECK: arith.constant 0x7FFF : f161021 %1 = arith.constant 0x7FFF : f161022 // CHECK: arith.constant 0xFFFF : f161023 %2 = arith.constant 0xFFFF : f161024 1025 // F16 positive infinity.1026 // CHECK: arith.constant 0x7C00 : f161027 %3 = arith.constant 0x7C00 : f161028 // F16 negative infinity.1029 // CHECK: arith.constant 0xFC00 : f161030 %4 = arith.constant 0xFC00 : f161031 1032 return1033}1034 1035// CHECK-LABEL: @f32_special_values1036func.func @f32_special_values() {1037 // F32 signaling NaNs.1038 // CHECK: arith.constant 0x7F800001 : f321039 %0 = arith.constant 0x7F800001 : f321040 // CHECK: arith.constant 0x7FBFFFFF : f321041 %1 = arith.constant 0x7FBFFFFF : f321042 1043 // F32 quiet NaNs.1044 // CHECK: arith.constant 0x7FC00000 : f321045 %2 = arith.constant 0x7FC00000 : f321046 // CHECK: arith.constant 0xFFFFFFFF : f321047 %3 = arith.constant 0xFFFFFFFF : f321048 1049 // F32 positive infinity.1050 // CHECK: arith.constant 0x7F800000 : f321051 %4 = arith.constant 0x7F800000 : f321052 // F32 negative infinity.1053 // CHECK: arith.constant 0xFF800000 : f321054 %5 = arith.constant 0xFF800000 : f321055 1056 return1057}1058 1059// CHECK-LABEL: @f64_special_values1060func.func @f64_special_values() {1061 // F64 signaling NaNs.1062 // CHECK: arith.constant 0x7FF0000000000001 : f641063 %0 = arith.constant 0x7FF0000000000001 : f641064 // CHECK: arith.constant 0x7FF8000000000000 : f641065 %1 = arith.constant 0x7FF8000000000000 : f641066 1067 // F64 quiet NaNs.1068 // CHECK: arith.constant 0x7FF0000001000000 : f641069 %2 = arith.constant 0x7FF0000001000000 : f641070 // CHECK: arith.constant 0xFFF0000001000000 : f641071 %3 = arith.constant 0xFFF0000001000000 : f641072 1073 // F64 positive infinity.1074 // CHECK: arith.constant 0x7FF0000000000000 : f641075 %4 = arith.constant 0x7FF0000000000000 : f641076 // F64 negative infinity.1077 // CHECK: arith.constant 0xFFF0000000000000 : f641078 %5 = arith.constant 0xFFF0000000000000 : f641079 1080 // Check that values that can't be represented with the default format, use1081 // hex instead.1082 // CHECK: arith.constant 0xC1CDC00000000000 : f641083 %6 = arith.constant 0xC1CDC00000000000 : f641084 1085 return1086}1087 1088// CHECK-LABEL: @bfloat16_special_values1089func.func @bfloat16_special_values() {1090 // bfloat16 signaling NaNs.1091 // CHECK: arith.constant 0x7F81 : bf161092 %0 = arith.constant 0x7F81 : bf161093 // CHECK: arith.constant 0xFF81 : bf161094 %1 = arith.constant 0xFF81 : bf161095 1096 // bfloat16 quiet NaNs.1097 // CHECK: arith.constant 0x7FC0 : bf161098 %2 = arith.constant 0x7FC0 : bf161099 // CHECK: arith.constant 0xFFC0 : bf161100 %3 = arith.constant 0xFFC0 : bf161101 1102 // bfloat16 positive infinity.1103 // CHECK: arith.constant 0x7F80 : bf161104 %4 = arith.constant 0x7F80 : bf161105 // bfloat16 negative infinity.1106 // CHECK: arith.constant 0xFF80 : bf161107 %5 = arith.constant 0xFF80 : bf161108 1109 return1110}1111 1112// CHECK-LABEL: @f80_special_values1113func.func @f80_special_values() {1114 // F80 signaling NaNs.1115 // CHECK: arith.constant 0x7FFFE000000000000001 : f801116 %0 = arith.constant 0x7FFFE000000000000001 : f801117 // CHECK: arith.constant 0x7FFFB000000000000011 : f801118 %1 = arith.constant 0x7FFFB000000000000011 : f801119 1120 // F80 quiet NaNs.1121 // CHECK: arith.constant 0x7FFFC000000000100000 : f801122 %2 = arith.constant 0x7FFFC000000000100000 : f801123 // CHECK: arith.constant 0x7FFFE000000001000000 : f801124 %3 = arith.constant 0x7FFFE000000001000000 : f801125 1126 // F80 positive infinity.1127 // CHECK: arith.constant 0x7FFF8000000000000000 : f801128 %4 = arith.constant 0x7FFF8000000000000000 : f801129 // F80 negative infinity.1130 // CHECK: arith.constant 0xFFFF8000000000000000 : f801131 %5 = arith.constant 0xFFFF8000000000000000 : f801132 1133 return1134}1135 1136// We want to print floats in exponential notation with 6 significant digits,1137// but it may lead to precision loss when parsing back, in which case we print1138// the decimal form instead.1139// CHECK-LABEL: @f32_potential_precision_loss()1140func.func @f32_potential_precision_loss() {1141 // CHECK: arith.constant -1.23697901 : f321142 %0 = arith.constant -1.23697901 : f321143 return1144}1145 1146// CHECK-LABEL: @special_float_values_in_tensors1147func.func @special_float_values_in_tensors() {1148 // CHECK: dense<0xFFFFFFFF> : tensor<4x4xf32>1149 "foo"(){bar = dense<0xFFFFFFFF> : tensor<4x4xf32>} : () -> ()1150 // CHECK: dense<[{{\[}}0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32>1151 "foo"(){bar = dense<[[0xFFFFFFFF, 0x7F800000], [0x7FBFFFFF, 0x7F800001]]> : tensor<2x2xf32>} : () -> ()1152 // CHECK: dense<[0xFFFFFFFF, 0.000000e+00]> : tensor<2xf32>1153 "foo"(){bar = dense<[0xFFFFFFFF, 0.0]> : tensor<2xf32>} : () -> ()1154 1155 // CHECK: sparse<[{{\[}}1, 1, 0], [0, 1, 1]], [0xFFFFFFFF, 0x7F800001]>1156 "foo"(){bar = sparse<[[1,1,0],[0,1,1]], [0xFFFFFFFF, 0x7F800001]> : tensor<2x2x2xf32>} : () -> ()1157}1158 1159// Test parsing of an op with multiple region arguments, and without a1160// delimiter.1161 1162// GENERIC-LABEL: op_with_region_args1163func.func @op_with_region_args() {1164 // GENERIC: "test.polyfor"() ({1165 // GENERIC-NEXT: ^bb{{.*}}(%{{.*}}: index, %{{.*}}: index, %{{.*}}: index):1166 test.polyfor %i, %j, %k {1167 "foo"() : () -> ()1168 }1169 return1170}1171 1172// Test parsing an operation name from within another op custom syntax.1173 1174// CHECK-LABEL: @custom_name_api1175func.func @custom_name_api() {1176 // CHECK: test.parse_custom_operation_name_api(builtin.module)1177 test.parse_custom_operation_name_api(builtin.module)1178 return1179}1180 1181// Test allowing different name scopes for regions isolated from above.1182 1183// CHECK-LABEL: func @op_with_passthrough_region_args1184func.func @op_with_passthrough_region_args() {1185 // CHECK: [[VAL:%.*]] = arith.constant1186 %0 = arith.constant 10 : index1187 1188 // CHECK: test.isolated_region [[VAL]] {1189 // CHECK-NEXT: "foo.consumer"([[VAL]]) : (index)1190 // CHECK-NEXT: }1191 test.isolated_region %0 {1192 "foo.consumer"(%0) : (index) -> ()1193 }1194 1195 // CHECK: [[VAL:%.*]]:2 = "foo.op"1196 %result:2 = "foo.op"() : () -> (index, index)1197 1198 // CHECK: test.isolated_region [[VAL]]#1 {1199 // CHECK-NEXT: "foo.consumer"([[VAL]]#1) : (index)1200 // CHECK-NEXT: }1201 test.isolated_region %result#1 {1202 "foo.consumer"(%result#1) : (index) -> ()1203 }1204 1205 return1206}1207 1208// CHECK-LABEL: func private @ptr_to_function() -> !unreg.ptr<() -> ()>1209func.func private @ptr_to_function() -> !unreg.ptr<() -> ()>1210 1211// CHECK-LABEL: func private @escaped_string_char(i1 {foo.value = "\0A"})1212func.func private @escaped_string_char(i1 {foo.value = "\n"})1213 1214// CHECK-LABEL: func @parse_integer_literal_test1215func.func @parse_integer_literal_test() {1216 // CHECK: test.parse_integer_literal : 51217 test.parse_integer_literal : 51218 return1219}1220 1221// CHECK-LABEL: func @parse_wrapped_keyword_test1222func.func @parse_wrapped_keyword_test() {1223 // CHECK: test.parse_wrapped_keyword foo.keyword1224 test.parse_wrapped_keyword foo.keyword1225 return1226}1227 1228// GENERIC-LABEL: parse_base64_test1229func.func @parse_base64_test() {1230 // GENERIC: "test.parse_b64"() <{b64 = "hello world"}>1231 test.parse_b64 "aGVsbG8gd29ybGQ="1232 return1233}1234 1235// CHECK-LABEL: func @parse_slash_test1236func.func @parse_slash_test() {1237 // CHECK: "test.slash_attr"() <{attr = #test.slash_attr<1 / 2>}> : () -> ()1238 "test.slash_attr"() { attr = #test.slash_attr<1 / 2> } : () -> ()1239 return1240}1241 1242// CHECK-LABEL: func @"\22_string_symbol_reference\22"1243func.func @"\"_string_symbol_reference\""() {1244 // CHECK: ref = @"\22_string_symbol_reference\22"1245 "foo.symbol_reference"() {ref = @"\"_string_symbol_reference\""} : () -> ()1246 return1247}1248 1249// CHECK-LABEL: func private @parse_opaque_attr_escape1250func.func private @parse_opaque_attr_escape() {1251 // CHECK: value = #foo<"\"escaped\\\n\"">1252 "foo.constant"() {value = #foo<"\"escaped\\\n\"">} : () -> ()1253}1254 1255// CHECK-LABEL: func private @string_attr_name1256// CHECK-SAME: {"0 . 0", nested = {"0 . 0"}}1257func.func private @string_attr_name() attributes {"0 . 0", nested = {"0 . 0"}}1258 1259// CHECK-LABEL: func private @nested_reference1260// CHECK: ref = @some_symbol::@some_nested_symbol1261func.func private @nested_reference() attributes {test.ref = @some_symbol::@some_nested_symbol }1262 1263// CHECK-LABEL: func @custom_asm_names1264func.func @custom_asm_names() -> (i32, i32, i32, i32, i32, i32) {1265 // CHECK: %[[FIRST:first.*]], %[[MIDDLE:middle_results.*]]:2, %[[LAST:[0-9]+]]1266 %0, %1:2, %2 = "test.asm_interface_op"() : () -> (i32, i32, i32, i32)1267 1268 // CHECK: %[[FIRST_2:first.*]], %[[LAST_2:[0-9]+]]1269 %3, %4 = "test.asm_interface_op"() : () -> (i32, i32)1270 1271 // CHECK: return %[[FIRST]], %[[MIDDLE]]#0, %[[MIDDLE]]#1, %[[LAST]], %[[FIRST_2]], %[[LAST_2]]1272 return %0, %1#0, %1#1, %2, %3, %4 : i32, i32, i32, i32, i32, i321273}1274 1275 1276// CHECK-LABEL: func @pretty_names1277 1278// This tests the behavior1279func.func @pretty_names() {1280 // Simple case, should parse and print as %x being an implied 'name'1281 // attribute.1282 %x = test.string_attr_pretty_name1283 // CHECK: %x = test.string_attr_pretty_name1284 // CHECK-NOT: attributes1285 1286 // This specifies an explicit name, which should override the result.1287 %YY = test.string_attr_pretty_name attributes { names = ["y"] }1288 // CHECK: %y = test.string_attr_pretty_name1289 // CHECK-NOT: attributes1290 1291 // Conflicts with the 'y' name, so need an explicit attribute.1292 %0 = "test.string_attr_pretty_name"() { names = ["y"]} : () -> i321293 // CHECK: %y_0 = test.string_attr_pretty_name attributes {names = ["y"]}1294 1295 // Name contains a space.1296 %1 = "test.string_attr_pretty_name"() { names = ["space name"]} : () -> i321297 // CHECK: %space_name = test.string_attr_pretty_name attributes {names = ["space name"]}1298 1299 "unknown.use"(%x, %YY, %0, %1) : (i32, i32, i32, i32) -> ()1300 1301 // Multi-result support.1302 1303 %a, %b, %c = test.string_attr_pretty_name1304 // CHECK: %a, %b, %c = test.string_attr_pretty_name1305 // CHECK-NOT: attributes1306 1307 %q:3, %r = test.string_attr_pretty_name1308 // CHECK: %q, %q_1, %q_2, %r = test.string_attr_pretty_name attributes {names = ["q", "q", "q", "r"]}1309 1310 // CHECK: return1311 return1312}1313 1314 1315// This tests the behavior of "default dialect":1316// operations like `test.default_dialect` can define a default dialect1317// used in nested region.1318// CHECK-LABEL: func @default_dialect1319func.func @default_dialect(%bool : i1) {1320 test.default_dialect {1321 // The test dialect is the default in this region, the following two1322 // operations are parsed identically.1323 // CHECK-NOT: test.parse_integer_literal1324 parse_integer_literal : 51325 // CHECK: parse_integer_literal : 61326 test.parse_integer_literal : 61327 // Verify that only an op prefix is stripped, not an attribute value for1328 // example.1329 // CHECK: "test.op_with_attr"() {test.attr = "test.value"} : () -> ()1330 "test.op_with_attr"() {test.attr = "test.value"} : () -> ()1331 // Verify that the prefix is not stripped when it can lead to ambiguity.1332 // CHECK: test.op.with_dot_in_name1333 test.op.with_dot_in_name1334 // This is an unregistered operation, the printing/parsing is handled by the1335 // dialect, and the dialect prefix should not be stripped while printing1336 // because of potential ambiguity.1337 // CHECK: test.dialect_custom_printer.with.dot1338 test.dialect_custom_printer.with.dot1339 "test.terminator"() : ()->()1340 }1341 // The same operation outside of the region does not have an func. prefix.1342 // CHECK: return1343 func.return1344}1345 1346// CHECK-LABEL: func @unreachable_dominance_violation_ok1347func.func @unreachable_dominance_violation_ok() -> i1 {1348// CHECK: [[VAL:%.*]] = arith.constant false1349// CHECK: return [[VAL]] : i11350// CHECK: ^bb1: // no predecessors1351// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1)1352// CHECK: cf.br ^bb31353// CHECK: ^bb2: // pred: ^bb21354// CHECK: cf.br ^bb21355// CHECK: ^bb3: // pred: ^bb11356// CHECK: [[VAL3]] = "foo"() : () -> i641357// CHECK: return [[VAL2]]#1 : i11358// CHECK: }1359 %c = arith.constant false1360 return %c : i11361^bb1:1362 // %1 is not dominated by it's definition, but block is not reachable.1363 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)1364 cf.br ^bb31365^bb2:1366 cf.br ^bb21367^bb3:1368 %1 = "foo"() : ()->i641369 return %2#1 : i11370}1371 1372// CHECK-LABEL: func @graph_region_in_hierarchy_ok1373func.func @graph_region_in_hierarchy_ok() -> i64 {1374// CHECK: cf.br ^bb21375// CHECK: ^bb1:1376// CHECK: test.graph_region {1377// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1)1378// CHECK: }1379// CHECK: cf.br ^bb31380// CHECK: ^bb2: // pred: ^bb01381// CHECK: [[VAL3]] = "foo"() : () -> i641382// CHECK: cf.br ^bb11383// CHECK: ^bb3: // pred: ^bb11384// CHECK: return [[VAL3]] : i641385// CHECK: }1386 cf.br ^bb21387^bb1:1388 test.graph_region {1389 // %1 is well-defined here, since bb2 dominates bb1.1390 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)1391 }1392 cf.br ^bb41393^bb2:1394 %1 = "foo"() : ()->i641395 cf.br ^bb11396^bb4:1397 return %1 : i641398}1399 1400// CHECK-LABEL: func @graph_region_kind1401func.func @graph_region_kind() -> () {1402// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1)1403// CHECK: [[VAL3]] = "baz"([[VAL2]]#0) : (i1) -> i641404 test.graph_region {1405 // %1 OK here in graph region.1406 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)1407 %1 = "baz"(%2#0) : (i1) -> (i64)1408 }1409 return1410}1411 1412// CHECK-LABEL: func @graph_region_inside_ssacfg_region1413func.func @graph_region_inside_ssacfg_region() -> () {1414// CHECK: "test.ssacfg_region"1415// CHECK: [[VAL3:%.*]] = "baz"() : () -> i641416// CHECK: test.graph_region {1417// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3]]) : (i64) -> (i1, i1, i1)1418// CHECK: }1419// CHECK: [[VAL4:.*]] = "baz"() : () -> i641420 "test.ssacfg_region"() ({1421 %1 = "baz"() : () -> (i64)1422 test.graph_region {1423 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)1424 }1425 %3 = "baz"() : () -> (i64)1426 }) : () -> ()1427 return1428}1429 1430// CHECK-LABEL: func @graph_region_in_graph_region_ok1431func.func @graph_region_in_graph_region_ok() -> () {1432// CHECK: test.graph_region {1433// CHECK: test.graph_region {1434// CHECK: [[VAL2:%.*]]:3 = "bar"([[VAL3:%.*]]) : (i64) -> (i1, i1, i1)1435// CHECK: }1436// CHECK: [[VAL3]] = "foo"() : () -> i641437// CHECK: }1438test.graph_region {1439 test.graph_region {1440 // %1 is well-defined here since defined in graph region1441 %2:3 = "bar"(%1) : (i64) -> (i1,i1,i1)1442 }1443 %1 = "foo"() : ()->i641444 "test.terminator"() : ()->()1445 }1446 return1447}1448 1449// CHECK: test.graph_region {1450test.graph_region {1451// CHECK: [[VAL1:%.*]] = "op1"([[VAL3:%.*]]) : (i32) -> i321452// CHECK: [[VAL2:%.*]] = "test.ssacfg_region"([[VAL1]], [[VAL2]], [[VAL3]], [[VAL4:%.*]]) ({1453// CHECK: [[VAL5:%.*]] = "op2"([[VAL1]], [[VAL2]], [[VAL3]], [[VAL4]]) : (i32, i32, i32, i32) -> i321454// CHECK: }) : (i32, i32, i32, i32) -> i321455// CHECK: [[VAL3]] = "op2"([[VAL1]], [[VAL4]]) : (i32, i32) -> i321456// CHECK: [[VAL4]] = "op3"([[VAL1]]) : (i32) -> i321457 %1 = "op1"(%3) : (i32) -> (i32)1458 %2 = "test.ssacfg_region"(%1, %2, %3, %4) ({1459 %5 = "op2"(%1, %2, %3, %4) :1460 (i32, i32, i32, i32) -> (i32)1461 }) : (i32, i32, i32, i32) -> (i32)1462 %3 = "op2"(%1, %4) : (i32, i32) -> (i32)1463 %4 = "op3"(%1) : (i32) -> (i32)1464}1465 1466// CHECK: "unregistered_func_might_have_graph_region"() ({1467// CHECK: [[VAL1:%.*]] = "foo"([[VAL1]], [[VAL2:%.*]]) : (i64, i64) -> i641468// CHECK: [[VAL2]] = "bar"([[VAL1]])1469"unregistered_func_might_have_graph_region"() ({1470 %1 = "foo"(%1, %2) : (i64, i64) -> i641471 %2 = "bar"(%1) : (i64) -> i641472 "unregistered_terminator"() : () -> ()1473}) {sym_name = "unregistered_op_dominance_violation_ok", function_type = () -> i1} : () -> ()1474 1475// This is an unregister operation, the printing/parsing is handled by the dialect.1476// CHECK: test.dialect_custom_printer custom_format1477test.dialect_custom_printer custom_format1478 1479// This is a registered operation with no custom parser and printer, and should1480// be handled by the dialect.1481// CHECK: test.dialect_custom_format_fallback custom_format_fallback1482test.dialect_custom_format_fallback custom_format_fallback1483 1484// Check that an op with an optional result parses f80 as type.1485// CHECK: test.format_optional_result_d_op : f801486test.format_optional_result_d_op : f801487