xref: /llvm-project/mlir/test/Conversion/MemRefToLLVM/convert-static-memref-ops.mlir (revision 6937dbbe51391471f3cf50fe2b8fa2cd14080a3b)
1// RUN: mlir-opt -finalize-memref-to-llvm -split-input-file %s | FileCheck %s
2
3// CHECK-LABEL: func @zero_d_alloc()
4func.func @zero_d_alloc() -> memref<f32> {
5// CHECK: %[[one:.*]] = llvm.mlir.constant(1 : index) : i64
6// CHECK: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr
7// CHECK: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[one]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
8// CHECK: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i64
9// CHECK: %[[ptr:.*]] = llvm.call @malloc(%[[size_bytes]]) : (i64) -> !llvm.ptr
10// CHECK: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64)>
11// CHECK: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64)>
12// CHECK: llvm.insertvalue %[[ptr]], %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64)>
13// CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64
14// CHECK: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64)>
15// CHECK: unrealized_conversion_cast %{{.*}}
16
17  %0 = memref.alloc() : memref<f32>
18  return %0 : memref<f32>
19}
20
21// -----
22
23// CHECK-LABEL: func @zero_d_dealloc
24func.func @zero_d_dealloc(%arg0: memref<f32>) {
25// CHECK: unrealized_conversion_cast
26// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64)>
27// CHECK: llvm.call @free(%[[ptr]]) : (!llvm.ptr) -> ()
28
29  memref.dealloc %arg0 : memref<f32>
30  return
31}
32
33// -----
34
35// CHECK-LABEL: func @aligned_1d_alloc(
36func.func @aligned_1d_alloc() -> memref<42xf32> {
37// CHECK: %[[sz1:.*]] = llvm.mlir.constant(42 : index) : i64
38// CHECK: %[[st1:.*]] = llvm.mlir.constant(1 : index) : i64
39// CHECK: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr
40// CHECK: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[sz1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
41// CHECK: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i64
42// CHECK: %[[alignment:.*]] = llvm.mlir.constant(8 : index) : i64
43// CHECK: %[[allocsize:.*]] = llvm.add %[[size_bytes]], %[[alignment]] : i64
44// CHECK: %[[ptr:.*]] = llvm.call @malloc(%[[allocsize]]) : (i64) -> !llvm.ptr
45// CHECK: %[[allocatedAsInt:.*]] = llvm.ptrtoint %[[ptr]] : !llvm.ptr to i64
46// CHECK: %[[one_1:.*]] = llvm.mlir.constant(1 : index) : i64
47// CHECK: %[[bump:.*]] = llvm.sub %[[alignment]], %[[one_1]] : i64
48// CHECK: %[[bumped:.*]] = llvm.add %[[allocatedAsInt]], %[[bump]] : i64
49// CHECK: %[[mod:.*]] = llvm.urem %[[bumped]], %[[alignment]] : i64
50// CHECK: %[[aligned:.*]] = llvm.sub %[[bumped]], %[[mod]] : i64
51// CHECK: %[[alignedBitCast:.*]] = llvm.inttoptr %[[aligned]] : i64 to !llvm.ptr
52// CHECK: llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
53// CHECK: llvm.insertvalue %[[ptr]], %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
54// CHECK: llvm.insertvalue %[[alignedBitCast]], %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
55// CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64
56// CHECK: llvm.insertvalue %[[c0]], %{{.*}}[2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
57  %0 = memref.alloc() {alignment = 8} : memref<42xf32>
58  return %0 : memref<42xf32>
59}
60
61// -----
62
63// CHECK-LABEL: func @static_alloc()
64func.func @static_alloc() -> memref<32x18xf32> {
65// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : i64
66// CHECK: %[[null:.*]] = llvm.mlir.zero : !llvm.ptr
67// CHECK: %[[gep:.*]] = llvm.getelementptr %[[null]][%[[num_elems]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
68// CHECK: %[[size_bytes:.*]] = llvm.ptrtoint %[[gep]] : !llvm.ptr to i64
69// CHECK: llvm.call @malloc(%[[size_bytes]]) : (i64) -> !llvm.ptr
70 %0 = memref.alloc() : memref<32x18xf32>
71 return %0 : memref<32x18xf32>
72}
73
74// -----
75
76// CHECK-LABEL: func @static_alloca()
77func.func @static_alloca() -> memref<32x18xf32> {
78// CHECK: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : i64
79// CHECK: %[[sz2:.*]] = llvm.mlir.constant(18 : index) : i64
80// CHECK: %[[st2:.*]] = llvm.mlir.constant(1 : index) : i64
81// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(576 : index) : i64
82// CHECK: %[[allocated:.*]] = llvm.alloca %[[num_elems]] x f32 : (i64) -> !llvm.ptr
83 %0 = memref.alloca() : memref<32x18xf32>
84
85 // Test with explicitly specified alignment. llvm.alloca takes care of the
86 // alignment. The same pointer is thus used for allocation and aligned
87 // accesses.
88 // CHECK: %[[alloca_aligned:.*]] = llvm.alloca %{{.*}} x f32 {alignment = 32 : i64} : (i64) -> !llvm.ptr
89 // CHECK: %[[desc:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
90 // CHECK: %[[desc1:.*]] = llvm.insertvalue %[[alloca_aligned]], %[[desc]][0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
91 // CHECK: llvm.insertvalue %[[alloca_aligned]], %[[desc1]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
92 memref.alloca() {alignment = 32} : memref<32x18xf32>
93 return %0 : memref<32x18xf32>
94}
95
96// -----
97
98// CHECK-LABEL: func @static_alloca_zero()
99func.func @static_alloca_zero() -> memref<32x0x18xf32> {
100// CHECK: %[[sz1:.*]] = llvm.mlir.constant(32 : index) : i64
101// CHECK: %[[sz2:.*]] = llvm.mlir.constant(0 : index) : i64
102// CHECK: %[[sz3:.*]] = llvm.mlir.constant(18 : index) : i64
103// CHECK: %[[st1:.*]] = llvm.mlir.constant(1 : index) : i64
104// CHECK: %[[st2:.*]] = llvm.mlir.constant(0 : index) : i64
105// CHECK: %[[num_elems:.*]] = llvm.mlir.constant(0 : index) : i64
106// CHECK: %[[allocated:.*]] = llvm.alloca %[[num_elems]] x f32 : (i64) -> !llvm.ptr
107 %0 = memref.alloca() : memref<32x0x18xf32>
108
109 return %0 : memref<32x0x18xf32>
110}
111
112// -----
113
114// CHECK-LABEL: func @static_dealloc
115func.func @static_dealloc(%static: memref<10x8xf32>) {
116// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
117// CHECK: llvm.call @free(%[[ptr]]) : (!llvm.ptr) -> ()
118  memref.dealloc %static : memref<10x8xf32>
119  return
120}
121
122// -----
123
124// CHECK-LABEL: func @zero_d_load
125func.func @zero_d_load(%arg0: memref<f32>) -> f32 {
126// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64)>
127// CHECK: %{{.*}} = llvm.load %[[ptr]] : !llvm.ptr -> f32
128  %0 = memref.load %arg0[] : memref<f32>
129  return %0 : f32
130}
131
132// -----
133
134// CHECK-LABEL: func @static_load(
135// CHECK-SAME:    %[[MEMREF:.*]]: memref<10x42xf32>, %[[I:.*]]: index, %[[J:.*]]: index)
136func.func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) {
137// CHECK-DAG:  %[[II:.*]] = builtin.unrealized_conversion_cast %[[I]]
138// CHECK-DAG:  %[[JJ:.*]] = builtin.unrealized_conversion_cast %[[J]]
139// CHECK:  %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
140// CHECK:  %[[st0:.*]] = llvm.mlir.constant(42 : index) : i64
141// CHECK:  %[[offI:.*]] = llvm.mul %[[II]], %[[st0]] : i64
142// CHECK:  %[[off1:.*]] = llvm.add %[[offI]], %[[JJ]] : i64
143// CHECK:  %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
144// CHECK:  llvm.load %[[addr]] : !llvm.ptr -> f32
145  %0 = memref.load %static[%i, %j] : memref<10x42xf32>
146  return
147}
148
149// -----
150
151// CHECK-LABEL: func @zero_d_store
152func.func @zero_d_store(%arg0: memref<f32>, %arg1: f32) {
153// CHECK: %[[ptr:.*]] = llvm.extractvalue %[[ld:.*]][1] : !llvm.struct<(ptr, ptr, i64)>
154// CHECK: llvm.store %{{.*}}, %[[ptr]] : f32, !llvm.ptr
155  memref.store %arg1, %arg0[] : memref<f32>
156  return
157}
158
159// -----
160
161// CHECK-LABEL: func @static_store
162// CHECK:         %[[MEMREF:.*]]: memref<10x42xf32>,
163// CHECK-SAME:    %[[I:.*]]: index, %[[J:.*]]: index,
164func.func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f32) {
165// CHECK-DAG: %[[II:.*]] = builtin.unrealized_conversion_cast %[[I]]
166// CHECK-DAG: %[[JJ:.*]] = builtin.unrealized_conversion_cast %[[J]]
167// CHECK: %[[ptr:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
168// CHECK: %[[st0:.*]] = llvm.mlir.constant(42 : index) : i64
169// CHECK: %[[offI:.*]] = llvm.mul %[[II]], %[[st0]] : i64
170// CHECK: %[[off1:.*]] = llvm.add %[[offI]], %[[JJ]] : i64
171// CHECK: %[[addr:.*]] = llvm.getelementptr %[[ptr]][%[[off1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
172// CHECK: llvm.store %{{.*}}, %[[addr]] : f32, !llvm.ptr
173
174  memref.store %val, %static[%i, %j] : memref<10x42xf32>
175  return
176}
177
178// -----
179
180// CHECK-LABEL: func @static_memref_dim
181func.func @static_memref_dim(%static : memref<42x32x15x13x27xf32>) {
182// CHECK:  llvm.mlir.constant(42 : index) : i64
183  %c0 = arith.constant 0 : index
184  %0 = memref.dim %static, %c0 : memref<42x32x15x13x27xf32>
185// CHECK:  llvm.mlir.constant(32 : index) : i64
186  %c1 = arith.constant 1 : index
187  %1 = memref.dim %static, %c1 : memref<42x32x15x13x27xf32>
188// CHECK:  llvm.mlir.constant(15 : index) : i64
189  %c2 = arith.constant 2 : index
190  %2 = memref.dim %static, %c2 : memref<42x32x15x13x27xf32>
191// CHECK:  llvm.mlir.constant(13 : index) : i64
192  %c3 = arith.constant 3 : index
193  %3 = memref.dim %static, %c3 : memref<42x32x15x13x27xf32>
194// CHECK:  llvm.mlir.constant(27 : index) : i64
195  %c4 = arith.constant 4 : index
196  %4 = memref.dim %static, %c4 : memref<42x32x15x13x27xf32>
197  return
198}
199
200// -----
201
202// CHECK-LABEL: func @static_out_of_bound_memref_dim
203func.func @static_out_of_bound_memref_dim(%static : memref<42x32x15x13x27xf32>) -> index {
204// CHECK: %[[C_MINUS_7:.*]] = arith.constant -7 : index
205// CHECK: %[[C_MINUS_7_I64:.*]] = builtin.unrealized_conversion_cast %[[C_MINUS_7]] : index to i64
206// CHECK: %[[UB_IDX:.*]] = llvm.getelementptr %{{.*}}[0, %[[C_MINUS_7_I64]]] : (!llvm.ptr, i64) -> !llvm.ptr
207// CHECK: %[[UB_DIM_I64:.*]] = llvm.load %[[UB_IDX]] : !llvm.ptr
208// CHECK: %[[UB_DIM:.*]] = builtin.unrealized_conversion_cast %[[UB_DIM_I64]] : i64 to index
209// CHECK: return %[[UB_DIM]] : index
210  %c-7 = arith.constant -7 : index
211  %1 = memref.dim %static, %c-7 : memref<42x32x15x13x27xf32>
212  return %1 : index
213}
214// -----
215
216// Check that consistent types are emitted in address arithemic in presence of
217// a data layout specification.
218module attributes { dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<index, 32>> } {
219  func.func @address() {
220    %c1 = arith.constant 1 : index
221    %0 = memref.alloc(%c1) : memref<? x vector<2xf32>>
222    // CHECK-DAG: %[[CST_S:.*]] = arith.constant 1 : index
223    // CHECK: %[[CST:.*]] = builtin.unrealized_conversion_cast
224    // CHECK: llvm.mlir.zero
225    // CHECK: llvm.getelementptr %{{.*}}[[CST]]
226    // CHECK: llvm.ptrtoint %{{.*}} : !llvm.ptr to i32
227    // CHECK: llvm.ptrtoint %{{.*}} : !llvm.ptr to i32
228    // CHECK: llvm.add %{{.*}} : i32
229    // CHECK: llvm.call @malloc(%{{.*}}) : (i32) -> !llvm.ptr
230    // CHECK: llvm.ptrtoint %{{.*}} : !llvm.ptr to i32
231    // CHECK: llvm.sub {{.*}} : i32
232    // CHECK: llvm.add {{.*}} : i32
233    // CHECK: llvm.urem {{.*}} : i32
234    // CHECK: llvm.sub {{.*}} : i32
235    // CHECK: llvm.inttoptr %{{.*}} : i32 to !llvm.ptr
236    return
237  }
238}
239
240// -----
241
242memref.global "private" constant @__constant_3xi64 : memref<3xi64> = dense<[2, 6, 20]>
243
244// CHECK-LABEL: func @memref.reshape
245// CHECK-SAME:    %[[arg0:.*]]: memref<4x5x6xf32>) -> memref<2x6x20xf32>
246func.func @memref.reshape(%arg0: memref<4x5x6xf32>) -> memref<2x6x20xf32> {
247  // CHECK: %[[cast0:.*]] = builtin.unrealized_conversion_cast %arg0 : memref<4x5x6xf32> to !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
248  %0 = memref.get_global @__constant_3xi64 : memref<3xi64>
249
250  // CHECK: %[[undef:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
251  // CHECK: %[[elem0:.*]] = llvm.extractvalue %[[cast0]][0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
252  // CHECK: %[[elem1:.*]] = llvm.extractvalue %[[cast0]][1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
253  // CHECK: %[[insert0:.*]] = llvm.insertvalue %[[elem0]], %[[undef]][0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
254  // CHECK: %[[insert1:.*]] = llvm.insertvalue %[[elem1]], %[[insert0:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
255
256  // CHECK: %[[zero:.*]] = llvm.mlir.constant(0 : index) : i64
257  // CHECK: %[[insert2:.*]] = llvm.insertvalue %[[zero]], %[[insert1]][2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
258
259  // CHECK: %[[one:.*]] = llvm.mlir.constant(1 : index) : i64
260  // CHECK: %[[twenty0:.*]] = llvm.mlir.constant(20 : index) : i64
261  // CHECK: %[[insert3:.*]] = llvm.insertvalue %[[twenty0]], %[[insert2]][3, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
262  // CHECK: %[[insert4:.*]] = llvm.insertvalue %[[one]], %[[insert3]][4, 2] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
263
264  // CHECK: %[[twenty1:.*]] = llvm.mlir.constant(20 : index) : i64
265  // CHECK: %[[six:.*]] = llvm.mlir.constant(6 : index) : i64
266  // CHECK: %[[insert5:.*]] = llvm.insertvalue %[[six]], %[[insert4]][3, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
267  // CHECK: %[[insert6:.*]] = llvm.insertvalue %[[twenty1]], %[[insert5]][4, 1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
268
269  // CHECK: %[[hundred_and_twenty:.*]] = llvm.mlir.constant(120 : index) : i64
270  // CHECK: %[[two:.*]] = llvm.mlir.constant(2 : index) : i64
271  // CHECK: %[[insert7:.*]] = llvm.insertvalue %[[two]], %[[insert6]][3, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
272  // CHECK: %[[insert8:.*]] = llvm.insertvalue %[[hundred_and_twenty]], %[[insert7]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
273
274  // CHECK: %[[cast1:.*]] = builtin.unrealized_conversion_cast %[[insert8]] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)> to memref<2x6x20xf32>
275  %1 = memref.reshape %arg0(%0) : (memref<4x5x6xf32>, memref<3xi64>) -> memref<2x6x20xf32>
276
277  // CHECK: return %[[cast1]] : memref<2x6x20xf32>
278  return %1 : memref<2x6x20xf32>
279}
280
281// -----
282
283// CHECK-LABEL: func @memref.reshape.dynamic.dim
284// CHECK-SAME:    %[[arg:.*]]: memref<?x?x?xf32>, %[[shape:.*]]: memref<4xi64>) -> memref<?x?x12x32xf32>
285func.func @memref.reshape.dynamic.dim(%arg: memref<?x?x?xf32>, %shape: memref<4xi64>) -> memref<?x?x12x32xf32> {
286  // CHECK-DAG: %[[arg_cast:.*]] = builtin.unrealized_conversion_cast %[[arg]] : memref<?x?x?xf32> to !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
287  // CHECK-DAG: %[[shape_cast:.*]] = builtin.unrealized_conversion_cast %[[shape]] : memref<4xi64> to !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
288  // CHECK: %[[undef:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
289  // CHECK: %[[alloc_ptr:.*]] = llvm.extractvalue %[[arg_cast]][0] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
290  // CHECK: %[[align_ptr:.*]] = llvm.extractvalue %[[arg_cast]][1] : !llvm.struct<(ptr, ptr, i64, array<3 x i64>, array<3 x i64>)>
291  // CHECK: %[[insert0:.*]] = llvm.insertvalue %[[alloc_ptr]], %[[undef]][0] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
292  // CHECK: %[[insert1:.*]] = llvm.insertvalue %[[align_ptr]], %[[insert0]][1] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
293
294  // CHECK: %[[zero0:.*]] = llvm.mlir.constant(0 : index) : i64
295  // CHECK: %[[insert2:.*]] = llvm.insertvalue %[[zero0]], %[[insert1]][2] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
296
297  // CHECK: %[[one0:.*]] = llvm.mlir.constant(1 : index) : i64
298  // CHECK: %[[thirty_two0:.*]] = llvm.mlir.constant(32 : index) : i64
299  // CHECK: %[[insert3:.*]] = llvm.insertvalue %[[thirty_two0]], %[[insert2]][3, 3] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
300  // CHECK: %[[insert4:.*]] = llvm.insertvalue %[[one0]], %[[insert3]][4, 3] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
301
302  // CHECK: %[[thirty_two1:.*]] = llvm.mlir.constant(32 : index) : i64
303  // CHECK: %[[twelve:.*]] = llvm.mlir.constant(12 : index) : i64
304  // CHECK: %[[insert5:.*]] = llvm.insertvalue %[[twelve]], %[[insert4]][3, 2] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
305  // CHECK: %[[insert6:.*]] = llvm.insertvalue %[[thirty_two1]], %[[insert5]][4, 2] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
306
307  // CHECK: %[[three_hundred_and_eighty_four:.*]] = llvm.mlir.constant(384 : index) : i64
308  // CHECK: %[[one1:.*]] = llvm.mlir.constant(1 : index) : i64
309  // CHECK: %[[shape_ptr0:.*]] = llvm.extractvalue %[[shape_cast]][1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
310  // CHECK: %[[shape_gep0:.*]] = llvm.getelementptr %[[shape_ptr0]][%[[one1]]] : (!llvm.ptr, i64) -> !llvm.ptr, i64
311  // CHECK: %[[shape_load0:.*]] = llvm.load %[[shape_gep0]] : !llvm.ptr -> i64
312  // CHECK: %[[insert7:.*]] = llvm.insertvalue %[[shape_load0]], %[[insert6]][3, 1] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
313  // CHECK: %[[insert8:.*]] = llvm.insertvalue %[[three_hundred_and_eighty_four]], %[[insert7]][4, 1] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
314
315  // CHECK: %[[mul:.*]] = llvm.mul %19, %23  : i64
316  // CHECK: %[[zero1:.*]] = llvm.mlir.constant(0 : index) : i64
317  // CHECK: %[[shape_ptr1:.*]] = llvm.extractvalue %[[shape_cast]][1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
318  // CHECK: %[[shape_gep1:.*]] = llvm.getelementptr %[[shape_ptr1]][%[[zero1]]] : (!llvm.ptr, i64) -> !llvm.ptr, i64
319  // CHECK: %[[shape_load1:.*]] = llvm.load %[[shape_gep1]] : !llvm.ptr -> i64
320  // CHECK: %[[insert9:.*]] = llvm.insertvalue %[[shape_load1]], %[[insert8]][3, 0] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
321  // CHECK: %[[insert10:.*]] = llvm.insertvalue %[[mul]], %[[insert9]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)>
322
323  // CHECK: %[[result_cast:.*]] = builtin.unrealized_conversion_cast %[[insert10]] : !llvm.struct<(ptr, ptr, i64, array<4 x i64>, array<4 x i64>)> to memref<?x?x12x32xf32>
324  %0 = memref.reshape %arg(%shape) : (memref<?x?x?xf32>, memref<4xi64>) -> memref<?x?x12x32xf32>
325
326  return %0 : memref<?x?x12x32xf32>
327  // CHECK: return %[[result_cast]] : memref<?x?x12x32xf32>
328}
329
330// -----
331
332// CHECK-LABEL: func @memref.reshape_index
333// CHECK-SAME:    %[[arg:.*]]: memref<?x?xi32>, %[[shape:.*]]: memref<1xindex>
334func.func @memref.reshape_index(%arg0: memref<?x?xi32>, %shape: memref<1xindex>) ->  memref<?xi32> {
335  // CHECK-DAG: %[[arg_cast:.*]] = builtin.unrealized_conversion_cast %[[arg]] : memref<?x?xi32> to !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
336  // CHECK-DAG: %[[shape_cast:.*]] = builtin.unrealized_conversion_cast %[[shape]] : memref<1xindex> to !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
337  // CHECK: %[[undef:.*]] = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
338  // CHECK: %[[alloc_ptr:.*]] = llvm.extractvalue %[[arg_cast]][0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
339  // CHECK: %[[align_ptr:.*]] = llvm.extractvalue %[[arg_cast]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
340  // CHECK: %[[insert0:.*]] = llvm.insertvalue %[[alloc_ptr]], %[[undef:.*]][0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
341  // CHECK: %[[insert1:.*]] = llvm.insertvalue %[[align_ptr]], %[[insert0:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
342
343  // CHECK: %[[zero0:.*]] = llvm.mlir.constant(0 : index) : i64
344  // CHECK: %[[insert2:.*]] = llvm.insertvalue %[[zero0]], %[[insert1:.*]][2] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
345
346  // CHECK: %[[one0:.*]] = llvm.mlir.constant(1 : index) : i64
347  // CHECK: %[[zero1:.*]] = llvm.mlir.constant(0 : index) : i64
348
349  // CHECK: %[[shape_ptr0:.*]] = llvm.extractvalue %[[shape_cast:.*]][1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
350  // CHECK: %[[shape_gep0:.*]] = llvm.getelementptr %[[shape_ptr0:.*]][%[[zero1:.*]]] : (!llvm.ptr, i64) -> !llvm.ptr, i64
351  // CHECK: %[[shape_load0:.*]] = llvm.load %[[shape_gep0:.*]] : !llvm.ptr -> i64
352  // CHECK: %[[insert3:.*]] = llvm.insertvalue %[[shape_load0:.*]], %[[insert2:.*]][3, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
353  // CHECK: %[[insert4:.*]] = llvm.insertvalue %[[one0:.*]], %[[insert3:.*]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
354
355  // CHECK: %[[result_cast:.*]] = builtin.unrealized_conversion_cast %[[insert4:.*]] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> to memref<?xi32>
356  // CHECK: return %[[result_cast:.*]] : memref<?xi32>
357
358  %1 = memref.reshape %arg0(%shape) : (memref<?x?xi32>, memref<1xindex>) -> memref<?xi32>
359  return %1 : memref<?xi32>
360}
361
362// CHECK-LABEL: @memref_memory_space_cast
363func.func @memref_memory_space_cast(%input : memref<?xf32>) -> memref<?xf32, 1> {
364  %cast = memref.memory_space_cast %input : memref<?xf32> to memref<?xf32, 1>
365  return %cast : memref<?xf32, 1>
366}
367// CHECK: [[INPUT:%.*]] = builtin.unrealized_conversion_cast %{{.*}}
368//  CHECK: [[ALLOC:%.*]] = llvm.extractvalue [[INPUT]][0]
369//  CHECK: [[ALIGN:%.*]] = llvm.extractvalue [[INPUT]][1]
370// CHECK: [[OFFSET:%.*]] = llvm.extractvalue [[INPUT]][2]
371//   CHECK: [[SIZE:%.*]] = llvm.extractvalue [[INPUT]][3, 0]
372// CHECK: [[STRIDE:%.*]] = llvm.extractvalue [[INPUT]][4, 0]
373// CHECK: [[CAST_ALLOC:%.*]] = llvm.addrspacecast [[ALLOC]] : !llvm.ptr to !llvm.ptr<1>
374// CHECK: [[CAST_ALIGN:%.*]] = llvm.addrspacecast [[ALIGN]] : !llvm.ptr to !llvm.ptr<1>
375// CHECK: [[RESULT_0:%.*]] = llvm.mlir.undef
376// CHECK: [[RESULT_1:%.*]] = llvm.insertvalue [[CAST_ALLOC]], [[RESULT_0]][0]
377// CHECK: [[RESULT_2:%.*]] = llvm.insertvalue [[CAST_ALIGN]], [[RESULT_1]][1]
378// CHECK: [[RESULT_3:%.*]] = llvm.insertvalue [[OFFSET]], [[RESULT_2]][2]
379// CHECK: [[RESULT_4:%.*]] = llvm.insertvalue [[SIZE]], [[RESULT_3]][3, 0]
380// CHECK: [[RESULT_5:%.*]] = llvm.insertvalue [[STRIDE]], [[RESULT_4]][4, 0]
381// CHECK: [[RESULT:%.*]] = builtin.unrealized_conversion_cast [[RESULT_5]] : {{.*}} to memref<?xf32, 1>
382// CHECK: return [[RESULT]]
383