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