xref: /llvm-project/mlir/test/Dialect/Tensor/bufferize.mlir (revision 1f5335c1db5d54b4465677c224b48e0ffc78e6d9)
1debdbedaSKunwar Grover// RUN: mlir-opt %s --one-shot-bufferize="dialect-filter=tensor,bufferization copy-before-write unknown-type-conversion=identity-layout-map" -cse -split-input-file | FileCheck %s
2daf18108SMatthias Springer
3e895a670SMatthias Springer// CHECK-LABEL:   func @dim(
43810f76cSQuentin Colombet// CHECK-SAME:              %[[TENSOR:.*]]: tensor<*xf32>,
5e895a670SMatthias Springer// CHECK-SAME:              %[[INDEX:.*]]: index) -> index {
6ced2fc78SChristopher Bate// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]] : tensor<*xf32> to memref<*xf32>
73810f76cSQuentin Colombet// CHECK:           %[[EXTENT:.*]] = memref.dim %[[MEMREF]], %[[INDEX]] : memref<*xf32>
8e895a670SMatthias Springer// CHECK:           return %[[EXTENT]] : index
93810f76cSQuentin Colombetfunc.func @dim(%arg0: tensor<*xf32>, %arg1: index) -> index {
103810f76cSQuentin Colombet  %0 = tensor.dim %arg0, %arg1 : tensor<*xf32>
11e895a670SMatthias Springer  return %0 : index
12e895a670SMatthias Springer}
13e895a670SMatthias Springer
14cc6462a4SMatthias Springer// -----
15cc6462a4SMatthias Springer
16a82a19c1SAlexander Belyaev// CHECK-LABEL: func @rank(
17a82a19c1SAlexander Belyaev// CHECK-SAME:    %[[TENSOR:.*]]: tensor<*xf32>) -> index {
18a82a19c1SAlexander Belyaev// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]]
19a82a19c1SAlexander Belyaev// CHECK:           %[[EXTENT:.*]] = memref.rank %[[MEMREF]] : memref<*xf32>
20c48e3a13SRiver Riddlefunc.func @rank(%arg0: tensor<*xf32>) -> index {
21a82a19c1SAlexander Belyaev  %0 = tensor.rank %arg0 : tensor<*xf32>
22a82a19c1SAlexander Belyaev  return %0 : index
23a82a19c1SAlexander Belyaev}
24a82a19c1SAlexander Belyaev
25cc6462a4SMatthias Springer// -----
26cc6462a4SMatthias Springer
27129d6e55SSean Silva// CHECK-LABEL:   func @tensor.cast(
28129d6e55SSean Silva// CHECK-SAME:                      %[[TENSOR:.*]]: tensor<?xindex>) -> tensor<2xindex> {
2957470abcSAlexander Belyaev// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]]
30e2310704SJulian Gross// CHECK:           %[[CASTED:.*]] = memref.cast %[[MEMREF]] : memref<?xindex> to memref<2xindex>
3157470abcSAlexander Belyaev// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[CASTED]]
32129d6e55SSean Silva// CHECK:           return %[[RET]] : tensor<2xindex>
33c48e3a13SRiver Riddlefunc.func @tensor.cast(%arg0: tensor<?xindex>) -> tensor<2xindex> {
34129d6e55SSean Silva  %0 = tensor.cast %arg0 : tensor<?xindex> to tensor<2xindex>
35129d6e55SSean Silva  return %0 : tensor<2xindex>
36129d6e55SSean Silva}
37129d6e55SSean Silva
38cc6462a4SMatthias Springer// -----
39cc6462a4SMatthias Springer
40129d6e55SSean Silva// CHECK-LABEL:   func @tensor.cast_from_unranked(
41129d6e55SSean Silva// CHECK-SAME:                                    %[[TENSOR:.*]]: tensor<*xf32>) -> tensor<2xf32> {
42ced2fc78SChristopher Bate// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]] : tensor<*xf32> to memref<*xf32>
43b6ae3f88SMatthias Springer// CHECK:           %[[CASTED_MEMREF:.*]] = memref.cast %[[MEMREF]] : memref<*xf32> to memref<2xf32, strided<[?], offset: ?>>
44b6ae3f88SMatthias Springer// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[CASTED_MEMREF]] : memref<2xf32, strided<[?], offset: ?>>
45129d6e55SSean Silva// CHECK:           return %[[RET]] : tensor<2xf32>
46c48e3a13SRiver Riddlefunc.func @tensor.cast_from_unranked(%arg0: tensor<*xf32>) -> tensor<2xf32> {
47129d6e55SSean Silva  %0 = tensor.cast %arg0 : tensor<*xf32> to tensor<2xf32>
48129d6e55SSean Silva  return %0 : tensor<2xf32>
49129d6e55SSean Silva}
50129d6e55SSean Silva
51cc6462a4SMatthias Springer// -----
52cc6462a4SMatthias Springer
53129d6e55SSean Silva// CHECK-LABEL:   func @tensor.cast_to_unranked(
54129d6e55SSean Silva// CHECK-SAME:                                  %[[TENSOR:.*]]: tensor<2xf32>) -> tensor<*xf32> {
55ced2fc78SChristopher Bate// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]] : tensor<2xf32> to memref<2xf32>
56e2310704SJulian Gross// CHECK:           %[[CASTED_MEMREF:.*]] = memref.cast %[[MEMREF]] : memref<2xf32> to memref<*xf32>
5757470abcSAlexander Belyaev// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[CASTED_MEMREF]] : memref<*xf32>
58129d6e55SSean Silva// CHECK:           return %[[RET]] : tensor<*xf32>
59c48e3a13SRiver Riddlefunc.func @tensor.cast_to_unranked(%arg0: tensor<2xf32>) -> tensor<*xf32> {
60129d6e55SSean Silva  %0 = tensor.cast %arg0 : tensor<2xf32> to tensor<*xf32>
61129d6e55SSean Silva  return %0 : tensor<*xf32>
62129d6e55SSean Silva}
63129d6e55SSean Silva
64cc6462a4SMatthias Springer// -----
65464dfebaSMatthias Springer
66464dfebaSMatthias Springer// CHECK-LABEL:   func @tensor.empty(
67464dfebaSMatthias Springer// CHECK:           %[[ALLOC:.*]] = memref.alloc() {{.*}} : memref<5xf32>
68464dfebaSMatthias Springer// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[ALLOC]] : memref<5xf32>
69464dfebaSMatthias Springer// CHECK:           return %[[RET]] : tensor<5xf32>
70be630f07SMatthias Springerfunc.func @tensor.empty() -> tensor<5xf32> {
71be630f07SMatthias Springer  %0 = tensor.empty() : tensor<5xf32>
72be630f07SMatthias Springer  return %0 : tensor<5xf32>
73be630f07SMatthias Springer}
74be630f07SMatthias Springer
75be630f07SMatthias Springer// -----
76cc6462a4SMatthias Springer
77be7352c0SSean Silva// CHECK-LABEL:   func @tensor.extract(
78444822d7SSean Silva// CHECK-SAME:                  %[[TENSOR:.*]]: tensor<?xf32>,
79444822d7SSean Silva// CHECK-SAME:                  %[[IDX:.*]]: index) -> f32 {
80ced2fc78SChristopher Bate// CHECK:           %[[MEMREF:.*]] = bufferization.to_memref %[[TENSOR]] : tensor<?xf32> to memref<?xf32>
81e2310704SJulian Gross// CHECK:           %[[RET:.*]] = memref.load %[[MEMREF]][%[[IDX]]] : memref<?xf32>
82444822d7SSean Silva// CHECK:           return %[[RET]] : f32
83444822d7SSean Silva// CHECK:         }
84c48e3a13SRiver Riddlefunc.func @tensor.extract(%arg0: tensor<?xf32>, %arg1: index) -> f32 {
85444822d7SSean Silva  %0 = tensor.extract %arg0[%arg1] : tensor<?xf32>
86444822d7SSean Silva  return %0 : f32
87444822d7SSean Silva}
88be7352c0SSean Silva
89cc6462a4SMatthias Springer// -----
90cc6462a4SMatthias Springer
91f77e9f87SAlexander Belyaev// CHECK-LABEL:   func @tensor.from_elements_0d(
92f77e9f87SAlexander Belyaev// CHECK-SAME:        %[[ELEM0:.*]]: index) -> tensor<index> {
93daf18108SMatthias Springer// CHECK:           %[[MEMREF:.*]] = memref.alloc() {{.*}} : memref<index>
94f77e9f87SAlexander Belyaev// CHECK:           store %[[ELEM0]], %[[MEMREF]]
95f77e9f87SAlexander Belyaev// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[MEMREF]]
96f77e9f87SAlexander Belyaev// CHECK:           return %[[RET]] : tensor<index>
97c48e3a13SRiver Riddlefunc.func @tensor.from_elements_0d(%arg0: index) -> tensor<index> {
98f77e9f87SAlexander Belyaev  %0 = tensor.from_elements %arg0 : tensor<index>
99f77e9f87SAlexander Belyaev  return %0 : tensor<index>
100f77e9f87SAlexander Belyaev}
101f77e9f87SAlexander Belyaev
102cc6462a4SMatthias Springer// -----
103cc6462a4SMatthias Springer
104f77e9f87SAlexander Belyaev// CHECK-LABEL:   func @tensor.from_elements_1d(
105be7352c0SSean Silva// CHECK-SAME:                               %[[ELEM0:.*]]: index,
106be7352c0SSean Silva// CHECK-SAME:                               %[[ELEM1:.*]]: index) -> tensor<2xindex> {
10739ec46bdSMatthias Springer// CHECK-DAG:       %[[C0:.*]] = arith.constant 0 : index
10839ec46bdSMatthias Springer// CHECK-DAG:       %[[C1:.*]] = arith.constant 1 : index
10939ec46bdSMatthias Springer// CHECK-DAG:       %[[MEMREF:.*]] = memref.alloc() {{.*}} : memref<2xindex>
110f77e9f87SAlexander Belyaev// CHECK:           store %[[ELEM0]], %[[MEMREF]][%[[C0]]]
111be7352c0SSean Silva// CHECK:           store %[[ELEM1]], %[[MEMREF]][%[[C1]]]
11257470abcSAlexander Belyaev// CHECK:           %[[RET:.*]] = bufferization.to_tensor %[[MEMREF]]
113be7352c0SSean Silva// CHECK:           return %[[RET]] : tensor<2xindex>
114c48e3a13SRiver Riddlefunc.func @tensor.from_elements_1d(%arg0: index, %arg1: index) -> tensor<2xindex> {
115be7352c0SSean Silva  %0 = tensor.from_elements %arg0, %arg1 : tensor<2xindex>
116be7352c0SSean Silva  return %0 : tensor<2xindex>
117be7352c0SSean Silva}
118be7352c0SSean Silva
119cc6462a4SMatthias Springer// -----
120cc6462a4SMatthias Springer
121f77e9f87SAlexander Belyaev// CHECK-LABEL: func @tensor.from_elements_2d(
122f77e9f87SAlexander Belyaev// CHECK-SAME:      %[[ELEM0:.*]]: index, %[[ELEM1:.*]]: index)
123f77e9f87SAlexander Belyaev// CHECK-SAME:      -> tensor<3x2xindex> {
124daf18108SMatthias Springer// CHECK-DAG:     %[[C0:.*]] = arith.constant 0 : index
125daf18108SMatthias Springer// CHECK-DAG:     %[[C1:.*]] = arith.constant 1 : index
126daf18108SMatthias Springer// CHECK-DAG:     %[[C2:.*]] = arith.constant 2 : index
12739ec46bdSMatthias Springer// CHECK-DAG:     %[[MEMREF:.*]] = memref.alloc() {{.*}} : memref<3x2xindex>
128f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM0]], %[[MEMREF]][%[[C0]], %[[C0]]]
129f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM1]], %[[MEMREF]][%[[C0]], %[[C1]]]
130f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM0]], %[[MEMREF]][%[[C1]], %[[C0]]]
131f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM1]], %[[MEMREF]][%[[C1]], %[[C1]]]
132f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM0]], %[[MEMREF]][%[[C2]], %[[C0]]]
133f77e9f87SAlexander Belyaev// CHECK:         store %[[ELEM1]], %[[MEMREF]][%[[C2]], %[[C1]]]
134f77e9f87SAlexander Belyaev// CHECK:         %[[RET:.*]] = bufferization.to_tensor %[[MEMREF]]
135f77e9f87SAlexander Belyaev// CHECK:         return %[[RET]] : tensor<3x2xindex>
136c48e3a13SRiver Riddlefunc.func @tensor.from_elements_2d(%arg0: index, %arg1: index) -> tensor<3x2xindex> {
137f77e9f87SAlexander Belyaev  %0 = tensor.from_elements %arg0, %arg1, %arg0, %arg1, %arg0, %arg1
138f77e9f87SAlexander Belyaev         : tensor<3x2xindex>
139f77e9f87SAlexander Belyaev  return %0 : tensor<3x2xindex>
140f77e9f87SAlexander Belyaev}
141f77e9f87SAlexander Belyaev
142cc6462a4SMatthias Springer// -----
143cc6462a4SMatthias Springer
144daf18108SMatthias Springer// CHECK-LABEL: func @tensor.from_elements_3d(
145daf18108SMatthias Springer//  CHECK-SAME:     %[[F0:.*]]: f32
146f77e9f87SAlexander Belyaev
147f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F1:.*]] = arith.constant 1.0{{0+}}e+00
148f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F2:.*]] = arith.constant 2.0
149f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F3:.*]] = arith.constant 3.0
150f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F4:.*]] = arith.constant 4.0
151f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F5:.*]] = arith.constant 5.0
152f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F6:.*]] = arith.constant 6.0
153f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F7:.*]] = arith.constant 7.0
154f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F8:.*]] = arith.constant 8.0
155f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F9:.*]] = arith.constant 9.0
156f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F10:.*]] = arith.constant 1.0{{0+}}e+01
157f77e9f87SAlexander Belyaev// CHECK-DAG: %[[F11:.*]] = arith.constant 1.1{{0+}}e+01
158f77e9f87SAlexander Belyaev
159daf18108SMatthias Springer// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
160daf18108SMatthias Springer// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
161daf18108SMatthias Springer// CHECK-DAG: %[[C2:.*]] = arith.constant 2 : index
162f77e9f87SAlexander Belyaev
16339ec46bdSMatthias Springer// CHECK-DAG: %[[MEMREF:.*]] = memref.alloc() {{.*}} : memref<3x2x2xf32>
164f77e9f87SAlexander Belyaev
165f77e9f87SAlexander Belyaev// CHECK: store %[[F0]], %[[MEMREF]][%[[C0]], %[[C0]], %[[C0]]]
166f77e9f87SAlexander Belyaev// CHECK: store %[[F1]], %[[MEMREF]][%[[C0]], %[[C0]], %[[C1]]]
167f77e9f87SAlexander Belyaev// CHECK: store %[[F2]], %[[MEMREF]][%[[C0]], %[[C1]], %[[C0]]]
168f77e9f87SAlexander Belyaev// CHECK: store %[[F3]], %[[MEMREF]][%[[C0]], %[[C1]], %[[C1]]]
169f77e9f87SAlexander Belyaev// CHECK: store %[[F4]], %[[MEMREF]][%[[C1]], %[[C0]], %[[C0]]]
170f77e9f87SAlexander Belyaev// CHECK: store %[[F5]], %[[MEMREF]][%[[C1]], %[[C0]], %[[C1]]]
171f77e9f87SAlexander Belyaev// CHECK: store %[[F6]], %[[MEMREF]][%[[C1]], %[[C1]], %[[C0]]]
172f77e9f87SAlexander Belyaev// CHECK: store %[[F7]], %[[MEMREF]][%[[C1]], %[[C1]], %[[C1]]]
173f77e9f87SAlexander Belyaev// CHECK: store %[[F8]], %[[MEMREF]][%[[C2]], %[[C0]], %[[C0]]]
174f77e9f87SAlexander Belyaev// CHECK: store %[[F9]], %[[MEMREF]][%[[C2]], %[[C0]], %[[C1]]]
175f77e9f87SAlexander Belyaev// CHECK: store %[[F10]], %[[MEMREF]][%[[C2]], %[[C1]], %[[C0]]]
176f77e9f87SAlexander Belyaev// CHECK: store %[[F11]], %[[MEMREF]][%[[C2]], %[[C1]], %[[C1]]]
177f77e9f87SAlexander Belyaev
178f77e9f87SAlexander Belyaev// CHECK: %[[RET:.*]] = bufferization.to_tensor %[[MEMREF]]
179f77e9f87SAlexander Belyaev// CHECK: return %[[RET]] : tensor<3x2x2xf32>
180c48e3a13SRiver Riddlefunc.func @tensor.from_elements_3d(%f0 : f32) -> tensor<3x2x2xf32> {
181f77e9f87SAlexander Belyaev  %f1 = arith.constant 1.0 : f32
182f77e9f87SAlexander Belyaev  %f2 = arith.constant 2.0 : f32
183f77e9f87SAlexander Belyaev  %f3 = arith.constant 3.0 : f32
184f77e9f87SAlexander Belyaev  %f4 = arith.constant 4.0 : f32
185f77e9f87SAlexander Belyaev  %f5 = arith.constant 5.0 : f32
186f77e9f87SAlexander Belyaev  %f6 = arith.constant 6.0 : f32
187f77e9f87SAlexander Belyaev  %f7 = arith.constant 7.0 : f32
188f77e9f87SAlexander Belyaev  %f8 = arith.constant 8.0 : f32
189f77e9f87SAlexander Belyaev  %f9 = arith.constant 9.0 : f32
190f77e9f87SAlexander Belyaev  %f10 = arith.constant 10.0 : f32
191f77e9f87SAlexander Belyaev  %f11 = arith.constant 11.0 : f32
192f77e9f87SAlexander Belyaev  %0 = tensor.from_elements %f0,%f1,%f2,%f3,%f4,%f5,%f6,%f7,%f8,%f9,%f10,%f11
193f77e9f87SAlexander Belyaev         : tensor<3x2x2xf32>
194f77e9f87SAlexander Belyaev  return %0 : tensor<3x2x2xf32>
195f77e9f87SAlexander Belyaev}
196f77e9f87SAlexander Belyaev
197cc6462a4SMatthias Springer// -----
198cc6462a4SMatthias Springer
199be7352c0SSean Silva// CHECK-LABEL:   func @tensor.generate(
200be7352c0SSean Silva// CHECK-SAME:        %[[ARG:.*]]: tensor<*xf32>,
201be7352c0SSean Silva// CHECK-SAME:        %[[DYNAMIC_EXTENT:.*]]: index) -> tensor<?xindex> {
202ced2fc78SChristopher Bate// CHECK-DAG:       %[[ARG_M:.*]] = bufferization.to_memref %[[ARG]] : tensor<*xf32> to memref<*xf32>
203c1f0a15cSMatthias Springer// CHECK-DAG:       %[[ALLOC:.*]] = memref.alloc(%[[DYNAMIC_EXTENT]]) {{.*}} : memref<?xindex>
204c1f0a15cSMatthias Springer// CHECK:           %[[ALLOC_T:.*]] = bufferization.to_tensor %[[ALLOC]]
20566baa349SMatthias Springer// CHECK:           %[[MAPPED:.*]] = linalg.map
20666baa349SMatthias Springer// CHECK:                 outs(%[[ALLOC_T]] : tensor<?xindex>)
207c1f0a15cSMatthias Springer// CHECK:             %[[INDEX:.*]] = linalg.index 0 : index
208c1f0a15cSMatthias Springer// CHECK:             %[[ELEM:.*]] = memref.dim %[[ARG_M]], %[[INDEX]] : memref<*xf32>
209c1f0a15cSMatthias Springer// CHECK:             linalg.yield %[[ELEM]]
210be7352c0SSean Silva// CHECK:           }
211c1f0a15cSMatthias Springer// CHECK:           return %[[MAPPED]] : tensor<?xindex>
212be7352c0SSean Silva// CHECK:         }
213c48e3a13SRiver Riddlefunc.func @tensor.generate(%arg: tensor<*xf32>, %dynamic_extent: index) -> tensor<?xindex> {
214be7352c0SSean Silva  %result = tensor.generate %dynamic_extent {
215be7352c0SSean Silva  ^bb0(%i : index):
216c0a6318dSMatthias Springer    %elem = tensor.dim %arg, %i : tensor<*xf32>
217be7352c0SSean Silva    tensor.yield %elem : index
218be7352c0SSean Silva  } : tensor<?xindex>
219be7352c0SSean Silva  return %result : tensor<?xindex>
220be7352c0SSean Silva}
221be7352c0SSean Silva
222cc6462a4SMatthias Springer// -----
223cc6462a4SMatthias Springer
224be7352c0SSean Silva// Additional test that checks the logic for intermixed static and dynamic
225be7352c0SSean Silva// extents.
226be7352c0SSean Silva//
227be7352c0SSean Silva// CHECK-LABEL:   func @tensor.generate_static_and_dynamic(
228be7352c0SSean Silva// CHECK-SAME:        %[[DYNAMIC_EXTENT:.*]]: index) -> tensor<16x?xindex> {
229c1f0a15cSMatthias Springer// CHECK:           %[[ALLOC:.*]] = memref.alloc(%[[DYNAMIC_EXTENT]]) {{.*}} : memref<16x?xindex>
230c1f0a15cSMatthias Springer// CHECK:           %[[ALLOC_T:.*]] = bufferization.to_tensor %[[ALLOC]]
23166baa349SMatthias Springer// CHECK:           %[[MAPPED:.*]] = linalg.map
23266baa349SMatthias Springer// CHECK:                 outs(%[[ALLOC_T]] : tensor<16x?xindex>)
233c1f0a15cSMatthias Springer// CHECK:             %[[INDEX0:.*]] = linalg.index 0
234c1f0a15cSMatthias Springer// CHECK:             %[[INDEX1:.*]] = linalg.index 1
235c1f0a15cSMatthias Springer// CHECK:             %[[ADD:.*]] = arith.addi %[[INDEX0]], %[[INDEX1]]
236c1f0a15cSMatthias Springer// CHECK:             linalg.yield %[[ADD]]
237be7352c0SSean Silva// CHECK:           }
238c1f0a15cSMatthias Springer// CHECK:           return %[[MAPPED]] : tensor<16x?xindex>
239be7352c0SSean Silva// CHECK:         }
240c48e3a13SRiver Riddlefunc.func @tensor.generate_static_and_dynamic(%arg0: index) -> tensor<16x?xindex> {
241be7352c0SSean Silva  %result = tensor.generate %arg0 {
242be7352c0SSean Silva  ^bb0(%i: index, %j: index):
243a54f4eaeSMogball    %sum = arith.addi %i, %j : index
244be7352c0SSean Silva    tensor.yield %sum : index
245be7352c0SSean Silva  } : tensor<16x?xindex>
246be7352c0SSean Silva  return %result : tensor<16x?xindex>
247be7352c0SSean Silva}
248be7352c0SSean Silva
249cc6462a4SMatthias Springer// -----
250cc6462a4SMatthias Springer
251be7352c0SSean Silva// CHECK-LABEL: func @tensor.generate_unknown_ops_in_body
252c48e3a13SRiver Riddlefunc.func @tensor.generate_unknown_ops_in_body(%arg0: index) -> tensor<?xindex> {
253be7352c0SSean Silva  // CHECK-NOT: tensor.generate
254be7352c0SSean Silva  %tensor = tensor.generate %arg0 {
255be7352c0SSean Silva  ^bb0(%iv: index):
256be7352c0SSean Silva    // CHECK: test.source
257be7352c0SSean Silva    %0 = "test.source"() : () -> index
258be7352c0SSean Silva    tensor.yield %0 : index
259be7352c0SSean Silva  } : tensor<?xindex>
260be7352c0SSean Silva  return %tensor : tensor<?xindex>
261be7352c0SSean Silva}
262daf18108SMatthias Springer
263cc6462a4SMatthias Springer// -----
264cc6462a4SMatthias Springer
265daf18108SMatthias Springer// CHECK-LABEL: func @tensor.extract_slice(
266daf18108SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<?x?xf32>, %[[idx1:.*]]: index, %[[idx2:.*]]: index
267c48e3a13SRiver Riddlefunc.func @tensor.extract_slice(
268daf18108SMatthias Springer    %t1: tensor<?x?xf32>, %idx1: index, %idx2: index) -> tensor<?x10xf32> {
269ced2fc78SChristopher Bate  // CHECK: %[[m:.*]] = bufferization.to_memref %[[t1]] : tensor<?x?xf32> to memref<?x?xf32>
2702791162bSAlex Zinenko  // CHECK: %[[r:.*]] = memref.subview %[[m]][5, %[[idx2]]] [%[[idx1]], 10] [1, 1] : memref<?x?xf32> to memref<?x10xf32, strided<[?, 1], offset: ?>>
271daf18108SMatthias Springer  %0 = tensor.extract_slice %t1[5, %idx2][%idx1, 10][1, 1]
272daf18108SMatthias Springer      : tensor<?x?xf32> to tensor<?x10xf32>
273daf18108SMatthias Springer  // CHECK: %[[r_tensor:.*]] = bufferization.to_tensor %[[r]]
274daf18108SMatthias Springer  // CHECK: return %[[r_tensor]]
275daf18108SMatthias Springer  return %0 : tensor<?x10xf32>
276daf18108SMatthias Springer}
277daf18108SMatthias Springer
278cc6462a4SMatthias Springer// -----
279cc6462a4SMatthias Springer
280daf18108SMatthias Springer// CHECK-LABEL: func @tensor.extract_slice_rank_reducing(
281daf18108SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<?x10x?xf32>, %[[idx1:.*]]: index,
282daf18108SMatthias Springer//  CHECK-SAME:     %[[idx2:.*]]: index
283c48e3a13SRiver Riddlefunc.func @tensor.extract_slice_rank_reducing(
284daf18108SMatthias Springer    %t1: tensor<?x10x?xf32>, %idx1: index, %idx2: index) -> tensor<?x15xf32> {
285ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<?x10x?xf32> to memref<?x10x?xf32>
2862791162bSAlex Zinenko  // CHECK: %[[r:.*]] = memref.subview %[[m1]][5, %[[idx1]], 10] [%[[idx2]], 1, 15] [1, 1, 1] : memref<?x10x?xf32> to memref<?x15xf32, strided<[?, 1], offset: ?>>
287daf18108SMatthias Springer  %0 = tensor.extract_slice %t1[5, %idx1, 10][%idx2, 1, 15][1, 1, 1]
288daf18108SMatthias Springer      : tensor<?x10x?xf32> to tensor<?x15xf32>
289daf18108SMatthias Springer  // CHECK: %[[r_tensor:.*]] = bufferization.to_tensor %[[r]]
290daf18108SMatthias Springer  // CHECK: return %[[r_tensor]]
291daf18108SMatthias Springer  return %0 : tensor<?x15xf32>
292daf18108SMatthias Springer}
293daf18108SMatthias Springer
294cc6462a4SMatthias Springer// -----
295cc6462a4SMatthias Springer
296daf18108SMatthias Springer// CHECK-LABEL: func @tensor.insert_slice(
297daf18108SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<?x?xf32>, %[[t2:.*]]: tensor<?x10xf32>,
298daf18108SMatthias Springer//  CHECK-SAME:     %[[idx1:.*]]: index, %[[idx2:.*]]: index
299c48e3a13SRiver Riddlefunc.func @tensor.insert_slice(%t1: tensor<?x?xf32>, %t2: tensor<?x10xf32>,
300daf18108SMatthias Springer                               %idx1: index, %idx2: index) -> tensor<?x?xf32> {
301daf18108SMatthias Springer  // CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
302daf18108SMatthias Springer  // CHECK-DAG: %[[c1:.*]] = arith.constant 1 : index
303ced2fc78SChristopher Bate  // CHECK-DAG: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<?x?xf32> to memref<?x?xf32>
304ced2fc78SChristopher Bate  // CHECK-DAG: %[[m2:.*]] = bufferization.to_memref %[[t2]] : tensor<?x10xf32> to memref<?x10xf32>
305d820acddSMatthias Springer  // CHECK-DAG: %[[dim0:.*]] = memref.dim %[[m1]], %[[c0]]
306d820acddSMatthias Springer  // CHECK-DAG: %[[dim1:.*]] = memref.dim %[[m1]], %[[c1]]
307daf18108SMatthias Springer  //     CHECK: %[[alloc:.*]] = memref.alloc(%[[dim0]], %[[dim1]])
308daf18108SMatthias Springer  //     CHECK: memref.copy %[[m1]], %[[alloc]]
309daf18108SMatthias Springer  //     CHECK: %[[subview:.*]] = memref.subview %[[alloc]][%[[idx1]], 5] [%[[idx2]], 10] [1, 1]
310daf18108SMatthias Springer  //     CHECK: memref.copy %[[m2]], %[[subview]]
311daf18108SMatthias Springer  %0 = tensor.insert_slice %t2 into %t1[%idx1, 5][%idx2, 10][1, 1]
312daf18108SMatthias Springer      : tensor<?x10xf32> into tensor<?x?xf32>
313daf18108SMatthias Springer
314daf18108SMatthias Springer  //     CHECK: %[[r:.*]] = bufferization.to_tensor %[[alloc]]
315daf18108SMatthias Springer  //     CHECK: return %[[r]]
316daf18108SMatthias Springer  return %0 : tensor<?x?xf32>
3176c3c5f80SMatthias Springer}
3186c3c5f80SMatthias Springer
3196c3c5f80SMatthias Springer// -----
3206c3c5f80SMatthias Springer
3216c3c5f80SMatthias Springer// CHECK-LABEL: func @tensor.insert_slice_rank_reducing_1(
3226c3c5f80SMatthias Springerfunc.func @tensor.insert_slice_rank_reducing_1(
3236c3c5f80SMatthias Springer    %t1: tensor<?x?xf32>, %f: tensor<f32>, %idx1: index, %idx2: index)
3246c3c5f80SMatthias Springer  -> tensor<?x?xf32>
3256c3c5f80SMatthias Springer{
3266c3c5f80SMatthias Springer  // CHECK: %[[alloc:.*]] = memref.alloc{{.*}} : memref<?x?xf32>
3272791162bSAlex Zinenko  // CHECK: memref.subview %[[alloc]][%{{.*}}, %{{.*}}] [1, 1] [1, 1] : memref<?x?xf32> to memref<f32, strided<[], offset: ?>>
3282791162bSAlex Zinenko  // CHECK: memref.copy {{.*}} : memref<f32> to memref<f32, strided<[], offset: ?>>
3296c3c5f80SMatthias Springer  %0 = tensor.insert_slice %f into %t1[%idx1, %idx2][1, 1][1, 1]
3306c3c5f80SMatthias Springer      : tensor<f32> into tensor<?x?xf32>
3316c3c5f80SMatthias Springer  return %0 : tensor<?x?xf32>
3326c3c5f80SMatthias Springer}
3336c3c5f80SMatthias Springer
3346c3c5f80SMatthias Springer// -----
3356c3c5f80SMatthias Springer
3366c3c5f80SMatthias Springer// CHECK-LABEL: func @tensor.insert_slice_rank_reducing_2(
3376c3c5f80SMatthias Springerfunc.func @tensor.insert_slice_rank_reducing_2(
3386c3c5f80SMatthias Springer    %t1: tensor<?x?x?x?x?x?x?xf32>, %t2: tensor<2x1x4x1x1xf32>, %i: index)
3396c3c5f80SMatthias Springer  -> tensor<?x?x?x?x?x?x?xf32>
3406c3c5f80SMatthias Springer{
3416c3c5f80SMatthias Springer  // CHECK: %[[alloc:.*]] = memref.alloc{{.*}} : memref<?x?x?x?x?x?x?xf32>
3422791162bSAlex Zinenko  // CHECK: memref.subview %[[alloc]][{{.*}}] [1, 2, 1, 4, 1, 1, 1] [1, 1, 1, 1, 1, 1, 1] : memref<?x?x?x?x?x?x?xf32> to memref<2x1x4x1x1xf32, strided<[?, ?, ?, ?, ?], offset: ?>>
3432791162bSAlex Zinenko  // CHECK: memref.copy {{.*}} : memref<2x1x4x1x1xf32> to memref<2x1x4x1x1xf32, strided<[?, ?, ?, ?, ?], offset: ?>>
3446c3c5f80SMatthias Springer  %0 = tensor.insert_slice %t2 into %t1[%i, %i, %i, %i, %i, %i, %i][1, 2, 1, 4, 1, 1, 1][1, 1, 1, 1, 1, 1, 1]
3456c3c5f80SMatthias Springer      : tensor<2x1x4x1x1xf32> into tensor<?x?x?x?x?x?x?xf32>
3466c3c5f80SMatthias Springer  return %0 : tensor<?x?x?x?x?x?x?xf32>
347daf18108SMatthias Springer}
348daf18108SMatthias Springer
349cc6462a4SMatthias Springer// -----
350cc6462a4SMatthias Springer
351daf18108SMatthias Springer// CHECK-LABEL: func @tensor.insert(
352daf18108SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<5xf32>, %[[idx1:.*]]: index,
353daf18108SMatthias Springer//  CHECK-SAME:     %[[f:.*]]: f32
354c48e3a13SRiver Riddlefunc.func @tensor.insert(%t1: tensor<5xf32>, %idx1: index, %f: f32) -> tensor<5xf32> {
35539ec46bdSMatthias Springer  // CHECK-DAG: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<5xf32>
356ced2fc78SChristopher Bate  // CHECK-DAG: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<5xf32> to memref<5xf32>
357daf18108SMatthias Springer  // CHECK: memref.copy %[[m1]], %[[alloc]]
358daf18108SMatthias Springer  // CHECK: memref.store %[[f]], %[[alloc]][%[[idx1]]]
359daf18108SMatthias Springer  %0 = tensor.insert %f into %t1[%idx1] : tensor<5xf32>
360daf18108SMatthias Springer
361daf18108SMatthias Springer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[alloc]]
362daf18108SMatthias Springer  // CHECK: return %[[r]]
363daf18108SMatthias Springer  return %0 : tensor<5xf32>
364daf18108SMatthias Springer}
365e6f69161SMatthias Springer
366cc6462a4SMatthias Springer// -----
367cc6462a4SMatthias Springer
368e6f69161SMatthias Springer// CHECK-LABEL: func @tensor.expand_shape(
369e6f69161SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<?x10xf32>
37097069a86SGaurav Shuklafunc.func @tensor.expand_shape(%t1: tensor<?x10xf32>, %sz0: index) -> tensor<2x?x10xf32> {
371ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]]
37297069a86SGaurav Shukla  // CHECK: %[[C0:.*]] = arith.constant 0 : index
37397069a86SGaurav Shukla  // CHECK: %[[DIM:.*]] = memref.dim %[[m1]], %[[C0]] : memref<?x10xf32>
37497069a86SGaurav Shukla  // CHECK: %[[C2:.*]] = arith.constant 2 : index
375*1f5335c1SMaheshRavishankar  // CHECK: %[[VAL_1:.*]] = arith.divsi %[[DIM]], %[[C2]] : index
37697069a86SGaurav Shukla  // CHECK: %[[expanded:.*]] = memref.expand_shape %[[m1]] {{\[\[}}0, 1], [2]] output_shape [2, %[[VAL_1]], 10] : memref<?x10xf32> into memref<2x?x10xf32>
37797069a86SGaurav Shukla  %0 = tensor.expand_shape %t1 [[0, 1], [2]] output_shape [2, %sz0, 10]
378e6f69161SMatthias Springer      : tensor<?x10xf32> into tensor<2x?x10xf32>
379e6f69161SMatthias Springer
380e6f69161SMatthias Springer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[expanded]]
381e6f69161SMatthias Springer  // CHECK: return %[[r]]
382e6f69161SMatthias Springer  return %0 : tensor<2x?x10xf32>
383e6f69161SMatthias Springer}
384e6f69161SMatthias Springer
385cc6462a4SMatthias Springer// -----
386cc6462a4SMatthias Springer
38751df6238SMatthias Springer// CHECK-LABEL: func @tensor.expand_shape_of_slice(
38851df6238SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<?x20xf32>
389c48e3a13SRiver Riddlefunc.func @tensor.expand_shape_of_slice(
39097069a86SGaurav Shukla    %t1: tensor<?x20xf32>, %o1: index, %s1: index, %sz0: index) -> tensor<?x7x2x5xf32> {
391ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] :
3922791162bSAlex Zinenko  // CHECK: %[[subview:.*]] = memref.subview %[[m1]][%{{.*}}, 5] [%{{.*}}, 10] [1, 1] : memref<?x20xf32> to memref<?x10xf32, strided<[20, 1], offset: ?>>
39351df6238SMatthias Springer  %0 = tensor.extract_slice %t1[%o1, 5][%s1, 10][1, 1] :
39451df6238SMatthias Springer      tensor<?x20xf32> to tensor<?x10xf32>
39597069a86SGaurav Shukla  // CHECK: %[[C7:.*]] = arith.constant 7 : index
396*1f5335c1SMaheshRavishankar  // CHECK: %[[VAL_1:.*]] = arith.divsi %{{.*}}, %[[C7]] : index
39797069a86SGaurav Shukla  // CHECK: %[[expanded:.*]] = memref.expand_shape %[[subview]] {{\[\[}}0, 1], [2, 3]] output_shape [%[[VAL_1]], 7, 2, 5] : memref<?x10xf32, strided<[20, 1], offset: ?>> into memref<?x7x2x5xf32, strided<[140, 20, 5, 1], offset: ?>>
39897069a86SGaurav Shukla  %1 = tensor.expand_shape %0 [[0, 1], [2, 3]] output_shape [%sz0, 7, 2, 5] :
39951df6238SMatthias Springer      tensor<?x10xf32> into tensor<?x7x2x5xf32>
40051df6238SMatthias Springer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[expanded]]
40151df6238SMatthias Springer  // CHECK: return %[[r]]
40251df6238SMatthias Springer  return %1 : tensor<?x7x2x5xf32>
40351df6238SMatthias Springer}
40451df6238SMatthias Springer
405cc6462a4SMatthias Springer// -----
406cc6462a4SMatthias Springer
4076eb0f8e2SBenjamin Kramer// CHECK-LABEL: func @tensor.expand_shape_of_scalar_slice(
4086eb0f8e2SBenjamin Kramer//  CHECK-SAME:     %[[t1:.*]]: tensor<?xf32>
4096eb0f8e2SBenjamin Kramerfunc.func @tensor.expand_shape_of_scalar_slice(
4106eb0f8e2SBenjamin Kramer    %t1: tensor<?xf32>, %o1: index, %s1: index) -> tensor<1xf32> {
411ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<?xf32> to memref<?xf32>
4122791162bSAlex Zinenko  // CHECK: %[[subview:.*]] = memref.subview %[[m1]][%{{.*}}] [1] [1] :  memref<?xf32> to memref<f32, strided<[], offset: ?>>
4136eb0f8e2SBenjamin Kramer  %0 = tensor.extract_slice %t1[%o1][1][1] : tensor<?xf32> to tensor<f32>
41497069a86SGaurav Shukla  // CHECK: %[[expanded:.*]] = memref.expand_shape %[[subview]] [] output_shape [1] : memref<f32, strided{{.*}}> into memref<1xf32, strided<[1], offset: ?>>
41597069a86SGaurav Shukla  %1 = tensor.expand_shape %0 [] output_shape [1] : tensor<f32> into tensor<1xf32>
4166eb0f8e2SBenjamin Kramer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[expanded]]
4176eb0f8e2SBenjamin Kramer  // CHECK: return %[[r]]
4186eb0f8e2SBenjamin Kramer  return %1 : tensor<1xf32>
4196eb0f8e2SBenjamin Kramer}
4206eb0f8e2SBenjamin Kramer
421cc6462a4SMatthias Springer// -----
422cc6462a4SMatthias Springer
423e6f69161SMatthias Springer// CHECK-LABEL: func @tensor.collapse_shape(
424e6f69161SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<2x?x?xf32>
425c48e3a13SRiver Riddlefunc.func @tensor.collapse_shape(%t1: tensor<2x?x?xf32>) -> tensor<?x?xf32> {
426ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<2x?x?xf32> to memref<2x?x?xf32>
427e6f69161SMatthias Springer  // CHECK: %[[collapsed:.*]] = memref.collapse_shape %[[m1]] [
428e6f69161SMatthias Springer  // CHECK-SAME: [0, 1], [2]] : memref<2x?x?xf32> into memref<?x?xf32>
429e6f69161SMatthias Springer  %0 = tensor.collapse_shape %t1 [[0, 1], [2]]
430e6f69161SMatthias Springer      : tensor<2x?x?xf32> into tensor<?x?xf32>
431e6f69161SMatthias Springer
432e6f69161SMatthias Springer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[collapsed]]
433e6f69161SMatthias Springer  // CHECK: return %[[r]]
434e6f69161SMatthias Springer  return %0 : tensor<?x?xf32>
435e6f69161SMatthias Springer}
43651df6238SMatthias Springer
437cc6462a4SMatthias Springer// -----
438cc6462a4SMatthias Springer
43951df6238SMatthias Springer// CHECK-LABEL: func @tensor.collapse_shape_to_scalar(
44051df6238SMatthias Springer//  CHECK-SAME:     %[[t1:.*]]: tensor<1x1x1xf32>
441c48e3a13SRiver Riddlefunc.func @tensor.collapse_shape_to_scalar(%t1: tensor<1x1x1xf32>) -> tensor<f32> {
442ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<1x1x1xf32> to memref<1x1x1xf32>
44351df6238SMatthias Springer  // CHECK: %[[collapsed:.*]] = memref.collapse_shape %[[m1]] [] : memref<1x1x1xf32> into memref<f32>
44451df6238SMatthias Springer  %0 = tensor.collapse_shape %t1 []
44551df6238SMatthias Springer      : tensor<1x1x1xf32> into tensor<f32>
44651df6238SMatthias Springer
44751df6238SMatthias Springer  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[collapsed]]
44851df6238SMatthias Springer  // CHECK: return %[[r]]
44951df6238SMatthias Springer  return %0 : tensor<f32>
45051df6238SMatthias Springer}
45173c0333dSMatthias Springer
452cc6462a4SMatthias Springer// -----
453cc6462a4SMatthias Springer
45473c0333dSMatthias Springer// CHECK-LABEL: func @tensor.collapse_shape_of_slice(
455c48e3a13SRiver Riddlefunc.func @tensor.collapse_shape_of_slice(%arg0: tensor<2xi32>) -> tensor<i32> {
4562791162bSAlex Zinenko  // CHECK: memref.subview %{{.*}}[1] [1] [1] : memref<2xi32> to memref<1xi32, strided<[1], offset: 1>>
45773c0333dSMatthias Springer  %0 = tensor.extract_slice %arg0[1] [1] [1] : tensor<2xi32> to tensor<1xi32>
45846b90a7bSAlex Zinenko  // CHECK: memref.collapse_shape %{{.*}} [] : memref<1xi32, strided<[1], offset: 1>> into memref<i32, strided<[], offset: 1>>
45973c0333dSMatthias Springer  %1 = tensor.collapse_shape %0 [] : tensor<1xi32> into tensor<i32>
46073c0333dSMatthias Springer  return %1 : tensor<i32>
46173c0333dSMatthias Springer}
462d7a9bf91SMatthias Springer
463cc6462a4SMatthias Springer// -----
464cc6462a4SMatthias Springer
465d7a9bf91SMatthias Springer// CHECK-LABEL: func @tensor.collapse_shape_of_slice2(
466c48e3a13SRiver Riddlefunc.func @tensor.collapse_shape_of_slice2(
467d7a9bf91SMatthias Springer    %arg0: tensor<?x?x?x?xi64>, %o1: index, %o2: index, %o3: index, %o4: index)
468d7a9bf91SMatthias Springer    -> tensor<87x63648xi64> {
4692791162bSAlex Zinenko  // CHECK: %[[subview:.*]] = memref.subview %{{.*}} : memref<?x?x?x?xi64> to memref<87x78x68x12xi64, strided{{.*}}>
470d7a9bf91SMatthias Springer  %0 = tensor.extract_slice %arg0[%o1, %o2, %o3, %o4] [87, 78, 68, 12] [1, 1, 1, 1] : tensor<?x?x?x?xi64> to tensor<87x78x68x12xi64>
471d7a9bf91SMatthias Springer
472d7a9bf91SMatthias Springer  // This memref may not be collapsible, so the buffer must be copied to get rid
473d7a9bf91SMatthias Springer  // of the layout map.
474d7a9bf91SMatthias Springer  // CHECK: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<87x78x68x12xi64>
475d7a9bf91SMatthias Springer  // CHECK: memref.copy %[[subview]], %[[alloc]]
476d7a9bf91SMatthias Springer  // CHECK: memref.collapse_shape %[[alloc]] [
477d7a9bf91SMatthias Springer  // CHECK-SAME: [0], [1, 2, 3]] : memref<87x78x68x12xi64> into memref<87x63648xi64>
478d7a9bf91SMatthias Springer  %1 = tensor.collapse_shape %0 [[0], [1, 2, 3]] : tensor<87x78x68x12xi64> into tensor<87x63648xi64>
479d7a9bf91SMatthias Springer  return %1 : tensor<87x63648xi64>
480d7a9bf91SMatthias Springer}
4811cddcfdcSYi Zhang
482cc6462a4SMatthias Springer// -----
483cc6462a4SMatthias Springer
4841cddcfdcSYi Zhang// CHECK-LABEL: func @tensor.collapse_shape_of_slice3(
4851cddcfdcSYi Zhang//  CHECK-SAME:     %[[t1:.*]]: tensor<1x2xf32>
4861cddcfdcSYi Zhangfunc.func @tensor.collapse_shape_of_slice3(%t1: tensor<1x2xf32>) -> tensor<1xf32> {
4872791162bSAlex Zinenko  // CHECK: memref.subview {{.*}} : memref<1x2xf32> to memref<1x1xf32, strided<[2, 1]>>
4881cddcfdcSYi Zhang  %0 = tensor.extract_slice %t1[0, 0][1, 1][1, 1] : tensor<1x2xf32> to tensor<1x1xf32>
4891cddcfdcSYi Zhang  // CHECK: memref.collapse_shape %{{.*}} [
49046b90a7bSAlex Zinenko  // CHECK-SAME: [0, 1]] : memref<1x1xf32, strided<[2, 1]>> into memref<1xf32, strided<[2]>>
4911cddcfdcSYi Zhang  %1 = tensor.collapse_shape %0 [[0, 1]] : tensor<1x1xf32> into tensor<1xf32>
4921cddcfdcSYi Zhang  return %1 : tensor<1xf32>
4931cddcfdcSYi Zhang}
4941cddcfdcSYi Zhang
495cc6462a4SMatthias Springer// -----
496cc6462a4SMatthias Springer
4971cddcfdcSYi Zhang// CHECK-LABEL:   func @tensor.collapse_shape_of_slice4(
4981cddcfdcSYi Zhang//  CHECK-SAME:     %[[t1:.*]]: tensor<?x2x4xf32>,
4991cddcfdcSYi Zhang// CHECK-SAME:      %[[OFFSET:.*]]: index) -> tensor<8xf32> {
5001cddcfdcSYi Zhangfunc.func @tensor.collapse_shape_of_slice4(%arg0: tensor<?x2x4xf32>, %offset: index, %size: index) -> tensor<8xf32> {
5012791162bSAlex Zinenko  // CHECK: memref.subview %{{.*}} : memref<?x2x4xf32> to memref<4x2x1xf32, strided<[8, 4, 1], offset: ?>>
5021cddcfdcSYi Zhang  %0 = tensor.extract_slice %arg0[0, 0, %offset] [4, 2, 1] [1, 1, 1] : tensor<?x2x4xf32> to tensor<4x2x1xf32>
5031cddcfdcSYi Zhang  // CHECK: memref.collapse_shape %{{.*}} [
50446b90a7bSAlex Zinenko  // CHECK-SAME: [0, 1, 2]] : memref<4x2x1xf32, strided<[8, 4, 1], offset: ?>> into memref<8xf32, strided<[4], offset: ?>>
5051cddcfdcSYi Zhang  %ret = tensor.collapse_shape %0 [[0, 1, 2]] : tensor<4x2x1xf32> into tensor<8xf32>
5061cddcfdcSYi Zhang  return %ret: tensor<8xf32>
5071cddcfdcSYi Zhang}
508e287d647SAshay Rane
509cc6462a4SMatthias Springer// -----
510cc6462a4SMatthias Springer
511d7c606f5SJohannes Reifferscheid// CHECK-LABEL: func @tensor.collapse_shape_of_slice5(
512d7c606f5SJohannes Reifferscheidfunc.func @tensor.collapse_shape_of_slice5(%arg0: tensor<2x2x2xi64>) -> tensor<4xi64> {
51378f4a02aSJohannes Reifferscheid  // CHECK: %[[subview:.*]] = memref.subview %{{.*}} : memref<2x2x2xi64> to memref<2x1x2xi64, {{.*}}>
514d7c606f5SJohannes Reifferscheid  %0 = tensor.extract_slice %arg0[0, 0, 0] [2, 1, 2] [1, 1, 1] : tensor<2x2x2xi64> to tensor<2x1x2xi64>
515d7c606f5SJohannes Reifferscheid
516d7c606f5SJohannes Reifferscheid  // This memref is not collapsible, so the buffer must be copied to get rid of
517d7c606f5SJohannes Reifferscheid  // the layout map.
518d7c606f5SJohannes Reifferscheid  // CHECK: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<2x1x2xi64>
519d7c606f5SJohannes Reifferscheid  // CHECK: memref.copy %[[subview]], %[[alloc]]
520d7c606f5SJohannes Reifferscheid  // CHECK: memref.collapse_shape %[[alloc]] [
521d7c606f5SJohannes Reifferscheid  // CHECK-SAME: [0, 1, 2]] : memref<2x1x2xi64> into memref<4xi64>
522d7c606f5SJohannes Reifferscheid  %1 = tensor.collapse_shape %0 [[0, 1, 2]] : tensor<2x1x2xi64> into tensor<4xi64>
523d7c606f5SJohannes Reifferscheid  return %1 : tensor<4xi64>
524d7c606f5SJohannes Reifferscheid}
525d7c606f5SJohannes Reifferscheid
526d7c606f5SJohannes Reifferscheid// -----
527d7c606f5SJohannes Reifferscheid
528e287d647SAshay Rane// CHECK-LABEL: func @tensor.reshape(
529e287d647SAshay Rane//  CHECK-SAME:     %[[t1:.*]]: tensor<?x10xf32>
530e287d647SAshay Ranefunc.func @tensor.reshape(%t1: tensor<?x10xf32>) -> tensor<2x2x5xf32> {
531ced2fc78SChristopher Bate  // CHECK: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<?x10xf32> to memref<?x10xf32>
532e287d647SAshay Rane
533e287d647SAshay Rane  // CHECK: %[[two:.*]] = arith.constant 2 : i64
534e287d647SAshay Rane  %two = arith.constant 2 : i64
535e287d647SAshay Rane  // CHECK: %[[five:.*]] = arith.constant 5 : i64
536e287d647SAshay Rane  %five = arith.constant 5 : i64
537e287d647SAshay Rane
53872d76a24SEmilio Cota  // CHECK: %[[alloc:.*]] = memref.alloc() {alignment = 64 : i64} : memref<3xi64>
539e287d647SAshay Rane  // CHECK: %[[zero_idx:.*]] = arith.constant 0 : index
540e287d647SAshay Rane  // CHECK: %[[one_idx:.*]] = arith.constant 1 : index
541e287d647SAshay Rane  // CHECK: %[[two_idx:.*]] = arith.constant 2 : index
542e287d647SAshay Rane  // CHECK: memref.store %[[two]], %[[alloc]][%[[zero_idx]]] : memref<3xi64>
543e287d647SAshay Rane  // CHECK: memref.store %[[two]], %[[alloc]][%[[one_idx]]] : memref<3xi64>
544e287d647SAshay Rane  // CHECK: memref.store %[[five]], %[[alloc]][%[[two_idx]]] : memref<3xi64>
545e287d647SAshay Rane  %shape = tensor.from_elements %two, %two, %five : tensor<3xi64>
546e287d647SAshay Rane
547e287d647SAshay Rane  // CHECK: %[[reshaped:.*]] = memref.reshape %[[m1]](%[[alloc]]) : (memref<?x10xf32>, memref<3xi64>) -> memref<2x2x5xf32>
548e287d647SAshay Rane  %reshaped = tensor.reshape %t1(%shape) : (tensor<?x10xf32>, tensor<3xi64>) -> tensor<2x2x5xf32>
549e287d647SAshay Rane
550e287d647SAshay Rane  // CHECK: %[[r:.*]] = bufferization.to_tensor %[[reshaped]]
551e287d647SAshay Rane  // CHECK: return %[[r]]
552e287d647SAshay Rane  return %reshaped : tensor<2x2x5xf32>
553e287d647SAshay Rane}
5549ee12f47SMatthias Springer
5559ee12f47SMatthias Springer// -----
5569ee12f47SMatthias Springer
55723bd2e96SMatthias Springer// CHECK:       #[[$sum_map_1:.+]] = affine_map<()[s0, s1] -> (s0 + s1 + 5)>
55809dfb441SMatthias Springer// CHECK:       #[[$sum_map_2:.+]] = affine_map<()[s0, s1] -> (s0 + s1 + 10)>
5599ee12f47SMatthias Springer// CHECK-LABEL: func @tensor.pad(
5609ee12f47SMatthias Springer//  CHECK-SAME:   %[[t1:.*]]: tensor<?x10xindex>, %[[l2:.*]]: index, %[[h1:.*]]: index, %[[h2:.*]]: index
5619ee12f47SMatthias Springerfunc.func @tensor.pad(%t1: tensor<?x10xindex>, %l2: index, %h1: index,
5629ee12f47SMatthias Springer                      %h2: index) -> tensor<?x?xindex> {
563ced2fc78SChristopher Bate  // CHECK-DAG: %[[m1:.*]] = bufferization.to_memref %[[t1]] : tensor<?x10xindex> to memref<?x10xindex>
5649ee12f47SMatthias Springer  // CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
5659ee12f47SMatthias Springer  // CHECK-DAG: %[[c1:.*]] = arith.constant 1 : index
5669ee12f47SMatthias Springer  // CHECK-DAG: %[[dim0:.*]] = memref.dim %[[m1]], %[[c0]]
5679ee12f47SMatthias Springer  // CHECK-DAG: %[[dim1:.*]] = memref.dim %[[m1]], %[[c1]]
56809dfb441SMatthias Springer  // CHECK-DAG: %[[size0:.*]] = affine.apply #[[$sum_map_1]]()[%[[h1]], %[[dim0]]]
56909dfb441SMatthias Springer  // CHECK-DAG: %[[size1:.*]] = affine.apply #[[$sum_map_2]]()[%[[l2]], %[[h2]]]
5709ee12f47SMatthias Springer  // CHECK:     %[[alloc:.*]] = memref.alloc(%[[size0]], %[[size1]]) {{.*}} : memref<?x?xindex>
571c1f0a15cSMatthias Springer  // CHECK:     %[[alloc_t:.*]] = bufferization.to_tensor %[[alloc]]
57266baa349SMatthias Springer  // CHECK:     %[[mapped:.*]] = linalg.map
57366baa349SMatthias Springer  // CHECK:           outs(%[[alloc_t]] : tensor<?x?xindex>)
574c1f0a15cSMatthias Springer  // CHECK:       %[[index0:.*]] = linalg.index 0
575c1f0a15cSMatthias Springer  // CHECK:       %[[index1:.*]] = linalg.index 1
576c1f0a15cSMatthias Springer  // CHECK:       %[[mul:.*]] = arith.muli %[[index0]], %[[index1]]
577c1f0a15cSMatthias Springer  // CHECK:       linalg.yield %[[mul]]
5789ee12f47SMatthias Springer  // CHECK:     }
579c1f0a15cSMatthias Springer  // CHECK:     %[[mapped_m:.*]] = bufferization.to_memref %[[mapped]]
580c1f0a15cSMatthias Springer  // CHECK:     %[[subview:.*]] = memref.subview %[[mapped_m]][5, %[[l2]]] [%[[dim0]], 10] [1, 1]
5819ee12f47SMatthias Springer  // CHECK:     memref.copy %[[m1]], %[[subview]]
5829ee12f47SMatthias Springer  %0 = tensor.pad %t1 low[5, %l2] high[%h1, %h2] {
5839ee12f47SMatthias Springer  ^bb0(%arg0: index, %arg1: index):
5849ee12f47SMatthias Springer    %m = arith.muli %arg0, %arg1 : index
5859ee12f47SMatthias Springer    tensor.yield %m : index
5869ee12f47SMatthias Springer  } : tensor<?x10xindex> to tensor<?x?xindex>
5879ee12f47SMatthias Springer
588c1f0a15cSMatthias Springer  // CHECK:     %[[r:.*]] = bufferization.to_tensor %[[mapped_m]]
5899ee12f47SMatthias Springer  // CHECK:     return %[[r]] : tensor<?x?xindex>
5909ee12f47SMatthias Springer  return %0 : tensor<?x?xindex>
5919ee12f47SMatthias Springer}
592481b254eSMatthias Springer
593481b254eSMatthias Springer// -----
594481b254eSMatthias Springer
595481b254eSMatthias Springer// CHECK-LABEL:   func @tensor.splat(
596481b254eSMatthias Springer// CHECK-SAME:        %[[F:.*]]: f32)
597481b254eSMatthias Springer// CHECK-DAG:       %[[ALLOC:.*]] = memref.alloc() {{.*}} : memref<10x2x4xf32>
598481b254eSMatthias Springer// CHECK:           %[[ALLOC_T:.*]] = bufferization.to_tensor %[[ALLOC]]
599481b254eSMatthias Springer// CHECK:           %[[MAPPED:.*]] = linalg.map
600481b254eSMatthias Springer// CHECK:                 outs(%[[ALLOC_T]] : tensor<10x2x4xf32>)
601481b254eSMatthias Springer// CHECK:             linalg.yield %[[F]]
602481b254eSMatthias Springer// CHECK:           }
603481b254eSMatthias Springer// CHECK:           return %[[MAPPED]] : tensor<10x2x4xf32>
604481b254eSMatthias Springer// CHECK:         }
605481b254eSMatthias Springerfunc.func @tensor.splat(%f: f32) -> tensor<10x2x4xf32> {
606481b254eSMatthias Springer  %t = tensor.splat %f : tensor<10x2x4xf32>
607481b254eSMatthias Springer  return %t : tensor<10x2x4xf32>
608481b254eSMatthias Springer}
609214d32ccSRafael Ubal
610214d32ccSRafael Ubal// -----
611214d32ccSRafael Ubal
612214d32ccSRafael Ubal// CHECK-LABEL: func @tensor.splat_dynamic(
613214d32ccSRafael Ubal// CHECK-SAME:  %[[F:[a-zA-Z0-9_]+]]: f32
614214d32ccSRafael Ubal// CHECK-SAME:  %[[M:[a-zA-Z0-9_]+]]: index
615214d32ccSRafael Ubal// CHECK-SAME:  %[[N:[a-zA-Z0-9_]+]]: index
616214d32ccSRafael Ubal// CHECK-DAG:     %[[ALLOC:.*]] = memref.alloc(%[[M]], %[[N]]) {{.*}} : memref<?x3x?xf32>
617214d32ccSRafael Ubal// CHECK:         %[[ALLOC_T:.*]] = bufferization.to_tensor %[[ALLOC]]
618214d32ccSRafael Ubal// CHECK:         %[[MAPPED:.*]] = linalg.map outs(%[[ALLOC_T]] : tensor<?x3x?xf32>)
619214d32ccSRafael Ubal// CHECK:         () {
620214d32ccSRafael Ubal// CHECK:           linalg.yield %[[F]] : f32
621214d32ccSRafael Ubal// CHECK:         }
622214d32ccSRafael Ubal// CHECK:         return %[[MAPPED]] : tensor<?x3x?xf32>
623214d32ccSRafael Ubal// CHECK:       }
624214d32ccSRafael Ubalfunc.func @tensor.splat_dynamic(%f: f32, %m: index, %n: index) -> tensor<?x3x?xf32> {
625214d32ccSRafael Ubal  %0 = tensor.splat %f[%m, %n] : tensor<?x3x?xf32>
626214d32ccSRafael Ubal  return %0 : tensor<?x3x?xf32>
627214d32ccSRafael Ubal}
628214d32ccSRafael Ubal
629d69e9491Sdonald chen// -----
630d69e9491Sdonald chen
631d69e9491Sdonald chen// CHECK-LABEL: func.func @parallel_insert_slice_copy_before_write
632d69e9491Sdonald chenfunc.func @parallel_insert_slice_copy_before_write(%in: tensor<4xf32>, %out: tensor<4xf32>) {
633d69e9491Sdonald chen  %c1 = arith.constant 1 : index
634d69e9491Sdonald chen  %num_threads = arith.constant 4 : index
635d69e9491Sdonald chen
636d69e9491Sdonald chen  // CHECK: scf.forall {{.*}} {
637d69e9491Sdonald chen  %result = scf.forall (%thread_idx) in (%num_threads) shared_outs (%o = %out) -> tensor<4xf32> {
638d69e9491Sdonald chen      %1 = tensor.extract_slice %in[%thread_idx][1][1] : tensor<4xf32> to tensor<1xf32>
639d69e9491Sdonald chen      scf.forall.in_parallel {
640d69e9491Sdonald chen        // CHECK: memref.subview %{{.*}}[%{{.*}}] [1] [1] : memref<4xf32> to memref<1xf32, strided<[1], offset: ?>>
641d69e9491Sdonald chen        // CHECK: memref.subview %{{.*}}[%{{.*}}] [1] [1] : memref<4xf32> to memref<1xf32, strided<[1], offset: ?>>
642d69e9491Sdonald chen        tensor.parallel_insert_slice %1 into %o[%thread_idx][1][1] :
643d69e9491Sdonald chen          tensor<1xf32> into tensor<4xf32>
644d69e9491Sdonald chen      }
645d69e9491Sdonald chen  }
646d69e9491Sdonald chen  // CHECK: }
647d69e9491Sdonald chen  return
648d69e9491Sdonald chen}
649