[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / mlir / test / Interfaces / TilingInterface / lower-to-loops-using-interface.mlir
blob8cbee3cbb758b2aef940961f1cdd9b358fdb66ca
1 // RUN: mlir-opt -transform-interpreter -split-input-file -canonicalize -cse %s | FileCheck %s
3 func.func @gemm(%arg0 : memref<?x?xf32>, %arg1 : memref<?x?xf32>,
4   %arg2 : memref<?x?xf32>) {
5   linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)
6       outs(%arg2 : memref<?x?xf32>)
7   return
10 module attributes {transform.with_named_sequence} {
11   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
12     %matmul = transform.structured.match ops{["linalg.matmul"]} in %arg1
13       : (!transform.any_op) -> !transform.any_op
14     %0 = transform.structured.convert_to_loops %matmul
15       : (!transform.any_op) -> (!transform.any_op)
16     transform.yield
17   }
19 // CHECK-LABEL: func @gemm
20 //  CHECK-SAME:     %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?xf32>
21 //  CHECK-SAME:     %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>
22 //  CHECK-SAME:     %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?xf32>
23 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
24 //   CHECK-DAG:   %[[M:.+]] = memref.dim %[[ARG0]], %[[C0]]
25 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
26 //   CHECK-DAG:   %[[K:.+]] = memref.dim %[[ARG0]], %[[C1]]
27 //   CHECK-DAG:   %[[N:.+]] = memref.dim %[[ARG1]], %[[C1]]
28 //       CHECK:   scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]
29 //       CHECK:     scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]
30 //       CHECK:       scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]
31 //   CHECK-DAG:         %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV2]]]
32 //   CHECK-DAG:         %[[RHS:.+]] = memref.load %[[ARG1]][%[[IV2]], %[[IV1]]]
33 //   CHECK-DAG:         %[[OUT:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]]]
34 //       CHECK:         %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]
35 //       CHECK:         %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]
36 //       CHECK:         memref.store %[[ADDF]], %[[ARG2]][%[[IV0]], %[[IV1]]]
37 //   CHECK-NOT:   linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)
39 // -----
41 func.func @gemm(%arg0 : memref<?x?xf32>, %arg1 : memref<?x?xf32>,
42   %arg2 : memref<?x?xf32>, %arg3 : memref<?xf32>, %arg4 : memref<?xf32>) {
43   linalg.matmul ins(%arg0, %arg1 : memref<?x?xf32>, memref<?x?xf32>)
44       outs(%arg2 : memref<?x?xf32>)
45   linalg.matvec ins(%arg0, %arg3 : memref<?x?xf32>, memref<?xf32>)
46       outs(%arg4 : memref<?xf32>)
47   return
50 module attributes {transform.with_named_sequence} {
51   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
52     %linalg_ops = transform.structured.match interface{TilingInterface} in %arg1
53       : (!transform.any_op) -> !transform.any_op
54     %0 = transform.structured.convert_to_loops %linalg_ops
55       : (!transform.any_op) -> (!transform.any_op)
56     %1:5 = transform.split_handle %0
57       : (!transform.any_op) -> (!transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op, !transform.any_op)
58     transform.yield
59   }
61 // CHECK-LABEL: func @gemm
62 //  CHECK-SAME:     %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?xf32>
63 //  CHECK-SAME:     %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>
64 //  CHECK-SAME:     %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?xf32>
65 //  CHECK-SAME:     %[[ARG3:[a-zA-Z0-9]+]]: memref<?xf32>
66 //  CHECK-SAME:     %[[ARG4:[a-zA-Z0-9]+]]: memref<?xf32>
67 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
68 //   CHECK-DAG:   %[[M:.+]] = memref.dim %[[ARG0]], %[[C0]]
69 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
70 //   CHECK-DAG:   %[[K:.+]] = memref.dim %[[ARG0]], %[[C1]]
71 //   CHECK-DAG:   %[[N:.+]] = memref.dim %[[ARG1]], %[[C1]]
72 //       CHECK:   scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]
73 //       CHECK:     scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]
74 //       CHECK:       scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]
75 //   CHECK-DAG:         %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV2]]]
76 //   CHECK-DAG:         %[[RHS:.+]] = memref.load %[[ARG1]][%[[IV2]], %[[IV1]]]
77 //   CHECK-DAG:         %[[OUT:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]]]
78 //       CHECK:         %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]
79 //       CHECK:         %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]
80 //       CHECK:         memref.store %[[ADDF]], %[[ARG2]][%[[IV0]], %[[IV1]]]
81 //       CHECK:   scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[M]] step %[[C1]]
82 //       CHECK:     scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[K]] step %[[C1]]
83 //   CHECK-DAG:         %[[LHS:.+]] = memref.load %[[ARG0]][%[[IV3]], %[[IV4]]]
84 //   CHECK-DAG:         %[[RHS:.+]] = memref.load %[[ARG3]][%[[IV4]]]
85 //   CHECK-DAG:         %[[OUT:.+]] = memref.load %[[ARG4]][%[[IV3]]]
86 //       CHECK:         %[[MULF:.+]] = arith.mulf %[[LHS]], %[[RHS]]
87 //       CHECK:         %[[ADDF:.+]] = arith.addf %[[OUT]], %[[MULF]]
88 //       CHECK:         memref.store %[[ADDF]], %[[ARG4]][%[[IV3]]]
90 // -----
92 func.func @indexed_generic(%arg0 : memref<200x300xi32>, %arg1 : memref<300xi16>,
93     %arg2 : memref<200xi8>, %arg3 : memref<300x200xi64>) {
94   linalg.generic {
95       indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d1)>,
96                        affine_map<(d0, d1) -> (d0)>, affine_map<(d0, d1) -> (d1, d0)>],
97       iterator_types = ["parallel", "parallel"]}
98       ins(%arg0, %arg1, %arg2 : memref<200x300xi32>, memref<300xi16>, memref<200xi8>)
99       outs(%arg3 : memref<300x200xi64>) {
100     ^bb0(%b0 : i32, %b1 : i16, %b2 : i8, %b3 : i64):
101       %0 = linalg.index 0 : index
102       %1 = arith.index_cast %0 : index to i16
103       %2 = arith.muli %b1, %1 : i16
104       %3 = linalg.index 1 : index
105       %4 = arith.index_cast %3 : index to i8
106       %5 = arith.muli %b2, %4 : i8
107       %6 = arith.extsi %2 : i16 to i32
108       %7 = arith.extsi %5 : i8 to i32
109       %8 = arith.addi %6, %7 : i32
110       %9 = arith.addi %8, %b0 : i32
111       %10 = arith.extsi %9 : i32 to i64
112       linalg.yield %10 : i64
113     }
114   return
117 module attributes {transform.with_named_sequence} {
118   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
119     %generic = transform.structured.match ops{["linalg.generic"]} in %arg1
120       : (!transform.any_op) -> !transform.any_op
121     %0 = transform.structured.convert_to_loops %generic
122       : (!transform.any_op) -> (!transform.any_op)
123     transform.yield
124   }
126 // CHECK-LABEL: func @indexed_generic
127 //  CHECK-SAME:     %[[ARG0:.+]]: memref<200x300xi32>
128 //  CHECK-SAME:     %[[ARG1:.+]]: memref<300xi16>
129 //  CHECK-SAME:     %[[ARG2:.+]]: memref<200xi8>
130 //  CHECK-SAME:     %[[ARG3:.+]]: memref<300x200xi64>
131 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
132 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
133 //   CHECK-DAG:   %[[C200:.+]] = arith.constant 200 : index
134 //   CHECK-DAG:   %[[C300:.+]] = arith.constant 300 : index
135 //       CHECK:   scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[C200]] step %[[C1]]
136 //       CHECK:     scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[C300]] step %[[C1]]
137 //   CHECK-DAG:       %[[B0:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[IV1]]]
138 //   CHECK-DAG:       %[[B1:.+]] = memref.load %[[ARG1]][%[[IV1]]]
139 //   CHECK-DAG:       %[[B2:.+]] = memref.load %[[ARG2]][%[[IV0]]]
140 //       CHECK:       %[[T1:.+]] = arith.index_cast %[[IV0]]
141 //       CHECK:       %[[T2:.+]] = arith.muli %[[B1]], %[[T1]]
142 //       CHECK:       %[[T4:.+]] = arith.index_cast %[[IV1]]
143 //       CHECK:       %[[T5:.+]] = arith.muli %[[B2]], %[[T4]]
144 //       CHECK:       %[[T6:.+]] = arith.extsi %[[T2]]
145 //       CHECK:       %[[T7:.+]] = arith.extsi %[[T5]]
146 //       CHECK:       %[[T8:.+]] = arith.addi %[[T6]], %[[T7]]
147 //       CHECK:       %[[T9:.+]] = arith.addi %[[T8]], %[[B0]]
148 //       CHECK:       %[[T10:.+]] = arith.extsi %[[T9]]
149 //       CHECK:       memref.store %[[T10]], %[[ARG3]][%[[IV1]], %[[IV0]]]
151 // -----
153 func.func @conv_strides_and_dilation(%arg0 : memref<?x?x?x?xf32>, %arg1 : memref<?x?x?x?xf32>,
154   %arg2 : memref<?x?x?x?xf32>) {
155   linalg.conv_2d_nhwc_hwcf {
156       strides = dense<[1, 2]> : tensor<2xi64>,
157       dilations = dense<[3, 4]> : tensor<2xi64>}
158       ins(%arg0, %arg1 : memref<?x?x?x?xf32>, memref<?x?x?x?xf32>)
159       outs(%arg2 : memref<?x?x?x?xf32>)
160   return
163 module attributes {transform.with_named_sequence} {
164   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
165     %conv = transform.structured.match ops{["linalg.conv_2d_nhwc_hwcf"]} in %arg1
166       : (!transform.any_op) -> !transform.any_op
167     %0 = transform.structured.convert_to_loops %conv
168       : (!transform.any_op) -> (!transform.any_op)
169     transform.yield
170   }
173 //  CHECK-DAG:  #[[MAP0:.+]] = affine_map<(d0, d1) -> (d0 + d1 * 3)>
174 //  CHECK-DAG:  #[[MAP1:.+]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>
175 //       CHECK: func @conv_strides_and_dilation(
176 //  CHECK-SAME:     %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
177 //  CHECK-SAME:     %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
178 //  CHECK-SAME:     %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
179 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
180 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
181 //   CHECK-DAG:   %[[C2:.+]] = arith.constant 2 : index
182 //   CHECK-DAG:   %[[C3:.+]] = arith.constant 3 : index
183 //   CHECK-DAG:   %[[N:.+]] = memref.dim %[[ARG0]], %[[C0]]
184 //   CHECK-DAG:   %[[C:.+]] = memref.dim %[[ARG0]], %[[C3]]
185 //   CHECK-DAG:   %[[H:.+]] = memref.dim %[[ARG1]], %[[C0]]
186 //   CHECK-DAG:   %[[W:.+]] = memref.dim %[[ARG1]], %[[C1]]
187 //   CHECK-DAG:   %[[F:.+]] = memref.dim %[[ARG1]], %[[C3]]
188 //   CHECK-DAG:   %[[P:.+]] = memref.dim %[[ARG2]], %[[C1]]
189 //   CHECK-DAG:   %[[Q:.+]] = memref.dim %[[ARG2]], %[[C2]]
190 //       CHECK:   scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]
191 //       CHECK:     scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[P]] step %[[C1]]
192 //       CHECK:       scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[Q]] step %[[C1]]
193 //       CHECK:         scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[F]] step %[[C1]]
194 //       CHECK:           scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[H]] step %[[C1]]
195 //       CHECK:             scf.for %[[IV5:[a-zA-Z0-9]+]] = %[[C0]] to %[[W]] step %[[C1]]
196 //       CHECK:               scf.for %[[IV6:[a-zA-Z0-9]+]] = %[[C0]] to %[[C]] step %[[C1]]
197 //   CHECK-DAG:                 %[[I:.+]] = affine.apply #[[MAP0]](%[[IV1]], %[[IV4]])
198 //   CHECK-DAG:                 %[[J:.+]] = affine.apply #[[MAP1]](%[[IV2]], %[[IV5]])
199 //   CHECK-DAG:                 %[[T9:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[I]], %[[J]], %[[IV6]]]
200 //   CHECK-DAG:                 %[[T10:.+]] = memref.load %[[ARG1]][%[[IV4]], %[[IV5]], %[[IV6]], %[[IV3]]]
201 //   CHECK-DAG:                 %[[T11:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]
202 //       CHECK:                 %[[T12:.+]] = arith.mulf %[[T9]], %[[T10]]
203 //       CHECK:                 %[[T13:.+]] = arith.addf %[[T11]], %[[T12]]
204 //       CHECK:                 memref.store %[[T13]], %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]
206 // -----
208 func.func @pool_strides_and_dilation(%arg0 : memref<?x?x?x?xf32>, %arg1 : memref<?x?xf32>,
209   %arg2 : memref<?x?x?x?xf32>) {
210   linalg.pooling_nhwc_max {
211       strides = dense<[1, 2]> : tensor<2xi64>,
212       dilations = dense<[3, 4]> : tensor<2xi64>}
213       ins(%arg0, %arg1 : memref<?x?x?x?xf32>, memref<?x?xf32>)
214       outs(%arg2 : memref<?x?x?x?xf32>)
215   return
218 module attributes {transform.with_named_sequence} {
219   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
220     %pool = transform.structured.match ops{["linalg.pooling_nhwc_max"]} in %arg1
221       : (!transform.any_op) -> !transform.any_op
222     %0 = transform.structured.convert_to_loops %pool
223       : (!transform.any_op) -> (!transform.any_op)
224     transform.yield
225   }
228 //  CHECK-DAG:  #[[MAP0:.+]] = affine_map<(d0, d1) -> (d0 + d1 * 3)>
229 //  CHECK-DAG:  #[[MAP1:.+]] = affine_map<(d0, d1) -> (d0 * 2 + d1 * 4)>
230 //       CHECK: func @pool_strides_and_dilation
231 //  CHECK-SAME:     %[[ARG0:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
232 //  CHECK-SAME:     %[[ARG1:[a-zA-Z0-9]+]]: memref<?x?xf32>
233 //  CHECK-SAME:     %[[ARG2:[a-zA-Z0-9]+]]: memref<?x?x?x?xf32>
234 //   CHECK-DAG:   %[[C0:.+]] = arith.constant 0 : index
235 //   CHECK-DAG:   %[[C1:.+]] = arith.constant 1 : index
236 //   CHECK-DAG:   %[[C2:.+]] = arith.constant 2 : index
237 //   CHECK-DAG:   %[[C3:.+]] = arith.constant 3 : index
238 //   CHECK-DAG:   %[[N:.+]] = memref.dim %[[ARG0]], %[[C0]]
239 //   CHECK-DAG:   %[[C:.+]] = memref.dim %[[ARG0]], %[[C3]]
240 //   CHECK-DAG:   %[[H:.+]] = memref.dim %[[ARG1]], %[[C0]]
241 //   CHECK-DAG:   %[[W:.+]] = memref.dim %[[ARG1]], %[[C1]]
242 //   CHECK-DAG:   %[[P:.+]] = memref.dim %[[ARG2]], %[[C1]]
243 //   CHECK-DAG:   %[[Q:.+]] = memref.dim %[[ARG2]], %[[C2]]
244 //       CHECK:   scf.for %[[IV0:[a-zA-Z0-9]+]] = %[[C0]] to %[[N]] step %[[C1]]
245 //       CHECK:     scf.for %[[IV1:[a-zA-Z0-9]+]] = %[[C0]] to %[[P]] step %[[C1]]
246 //       CHECK:       scf.for %[[IV2:[a-zA-Z0-9]+]] = %[[C0]] to %[[Q]] step %[[C1]]
247 //       CHECK:         scf.for %[[IV3:[a-zA-Z0-9]+]] = %[[C0]] to %[[C]] step %[[C1]]
248 //       CHECK:           scf.for %[[IV4:[a-zA-Z0-9]+]] = %[[C0]] to %[[H]] step %[[C1]]
249 //       CHECK:             scf.for %[[IV5:[a-zA-Z0-9]+]] = %[[C0]] to %[[W]] step %[[C1]]
250 //   CHECK-DAG:               %[[I:.+]] = affine.apply #[[MAP0]](%[[IV1]], %[[IV4]])
251 //   CHECK-DAG:               %[[J:.+]] = affine.apply #[[MAP1]](%[[IV2]], %[[IV5]])
252 //   CHECK-DAG:               %[[T8:.+]] = memref.load %[[ARG0]][%[[IV0]], %[[I]], %[[J]], %[[IV3]]]
253 //   CHECK-DAG:               %[[T9:.+]] = memref.load %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]
254 //       CHECK:               %[[T10:.+]] = arith.maximumf %[[T9]], %[[T8]]
255 //       CHECK:               memref.store %[[T10]], %[[ARG2]][%[[IV0]], %[[IV1]], %[[IV2]], %[[IV3]]]
257 // -----
259 func.func @map(%lhs: memref<64xf32>,
260     %rhs: memref<64xf32>, %out: memref<64xf32>) {
261   linalg.map ins(%lhs, %rhs : memref<64xf32>, memref<64xf32>)
262              outs(%out : memref<64xf32>)
263     (%in: f32, %in_0: f32) {
264       %0 = arith.addf %in, %in_0 : f32
265       linalg.yield %0 : f32
266     }
267   return
270 module attributes {transform.with_named_sequence} {
271   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
272     %map = transform.structured.match ops{["linalg.map"]} in %arg1
273       : (!transform.any_op) -> !transform.any_op
274     %0 = transform.structured.convert_to_loops %map
275       : (!transform.any_op) -> (!transform.any_op)
276     transform.yield
277   }
279 // CHECK-LABEL: func.func @map(
280 // CHECK-SAME:    %[[LHS:[a-zA-Z0-9]+]]: memref<64xf32>,
281 // CHECK-SAME:    %[[RHS:[a-zA-Z0-9]+]]: memref<64xf32>,
282 // CHECK-SAME:    %[[OUT:[a-zA-Z0-9]+]]: memref<64xf32>) {
284 // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
285 // CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
286 // CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index
288 // CHECK:     scf.for %[[I:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {
289 // CHECK:       %[[LHS_ELEM:.*]] = memref.load %[[LHS]][%[[I]]]
290 // CHECK:       %[[RHS_ELEM:.*]] = memref.load %[[RHS]][%[[I]]]
291 // CHECK:       %[[ADD:.*]] = arith.addf %[[LHS_ELEM]], %[[RHS_ELEM]]
292 // CHECK:       memref.store %[[ADD]], %[[OUT]][%[[I]]]
294 // -----
296 func.func @transpose(%arg0: memref<16x32x64xf32>,
297                                %arg1: memref<32x64x16xf32>) {
298   linalg.transpose ins(%arg0 : memref<16x32x64xf32>)
299                    outs(%arg1 : memref<32x64x16xf32>) permutation = [1, 2, 0]
300   return
303 module attributes {transform.with_named_sequence} {
304   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
305     %transpose = transform.structured.match ops{["linalg.transpose"]} in %arg1
306       : (!transform.any_op) -> !transform.any_op
307     %0 = transform.structured.convert_to_loops %transpose
308       : (!transform.any_op) -> (!transform.any_op)
309     transform.yield
310   }
312 // CHECK-LABEL: func.func @transpose(
313 // CHECK-SAME:    %[[IN:[a-zA-Z0-9]+]]: memref<16x32x64xf32>,
314 // CHECK-SAME:    %[[OUT:[a-zA-Z0-9]+]]: memref<32x64x16xf32>)
316 // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
317 // CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
318 // CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index
319 // CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index
320 // CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index
322 // CHECK:     scf.for %[[I:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {
323 // CHECK:       scf.for %[[J:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {
324 // CHECK:         scf.for %[[K:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {
325 // CHECK:           %[[ELEM:.*]] = memref.load %[[IN]][%[[K]], %[[I]], %[[J]]]
326 // CHECK:           memref.store %[[ELEM]], %[[OUT]][%[[I]], %[[J]], %[[K]]]
328 // -----
330 func.func @reduce(%arg0: memref<16x32x64xf32>,
331                   %arg1: memref<16x64xf32>) {
332   linalg.reduce ins(%arg0 : memref<16x32x64xf32>)
333                 outs(%arg1 : memref<16x64xf32>) dimensions = [1]
334     (%in: f32, %init: f32) {
335       %0 = arith.addf %in, %init : f32
336       linalg.yield %0 : f32
337     }
338   return
341 module attributes {transform.with_named_sequence} {
342   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
343     %reduce = transform.structured.match ops{["linalg.reduce"]} in %arg1
344       : (!transform.any_op) -> !transform.any_op
345     %0 = transform.structured.convert_to_loops %reduce
346       : (!transform.any_op) -> (!transform.any_op)
347     transform.yield
348   }
350 // CHECK-LABEL: func.func @reduce(
351 // CHECK-SAME:    %[[IN:[a-zA-Z0-9]+]]: memref<16x32x64xf32>,
352 // CHECK-SAME:    %[[OUT:[a-zA-Z0-9]+]]: memref<16x64xf32>
354 // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
355 // CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
356 // CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index
357 // CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index
358 // CHECK-DAG: %[[C64:.*]] = arith.constant 64 : index
360 // CHECK:     scf.for %[[I:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {
361 // CHECK:       scf.for %[[J:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {
362 // CHECK:         scf.for %[[K:.*]] = %[[C0]] to %[[C64]] step %[[C1]] {
363 // CHECK:           %[[IN_ELEM:.*]] = memref.load %[[IN]][%[[I]], %[[J]], %[[K]]]
364 // CHECK:           %[[OUT_ELEM:.*]] = memref.load %[[OUT]][%[[I]], %[[K]]]
365 // CHECK:           %[[ADD:.*]] = arith.addf %[[IN_ELEM]], %[[OUT_ELEM]]
366 // CHECK:           memref.store %[[ADD]], %[[OUT]][%[[I]], %[[K]]]
368 // -----
370 func.func @broadcast(%input: memref<8x32xf32>,
371                      %init: memref<8x16x32xf32>) {
372   linalg.broadcast
373       ins(%input:memref<8x32xf32>)
374       outs(%init:memref<8x16x32xf32>)
375       dimensions = [1]
376   func.return
379 module attributes {transform.with_named_sequence} {
380   transform.named_sequence @__transform_main(%arg1 : !transform.any_op {transform.readonly}) {
381     %broadcast = transform.structured.match ops{["linalg.broadcast"]} in %arg1
382       : (!transform.any_op) -> !transform.any_op
383     %0 = transform.structured.convert_to_loops %broadcast
384       : (!transform.any_op) -> (!transform.any_op)
385     transform.yield
386   }
388 // CHECK-LABEL: func.func @broadcast(
389 // CHECK-SAME:    %[[IN:[a-zA-Z0-9]+]]: memref<8x32xf32>,
390 // CHECK-SAME:    %[[OUT:[a-zA-Z0-9]+]]: memref<8x16x32xf32>
392 // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
393 // CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
394 // CHECK-DAG: %[[C8:.*]] = arith.constant 8 : index
395 // CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index
396 // CHECK-DAG: %[[C32:.*]] = arith.constant 32 : index
398 // CHECK:     scf.for %[[I:.*]] = %[[C0]] to %[[C8]] step %[[C1]] {
399 // CHECK:       scf.for %[[J:.*]] = %[[C0]] to %[[C16]] step %[[C1]] {
400 // CHECK:         scf.for %[[K:.*]] = %[[C0]] to %[[C32]] step %[[C1]] {
401 // CHECK:           %[[ELEM:.*]] = memref.load %[[IN]][%[[I]], %[[K]]]
402 // CHECK:           memref.store %[[ELEM]], %[[OUT]][%[[I]], %[[J]], %[[K]]]