1// RUN: mlir-opt -convert-std-to-llvm %s -split-input-file | FileCheck %s
2// RUN: mlir-opt -convert-std-to-llvm='index-bitwidth=32' %s -split-input-file | FileCheck --check-prefix=CHECK32 %s
3
4// CHECK-LABEL: func @empty() {
5// CHECK-NEXT:  llvm.return
6// CHECK-NEXT: }
7func @empty() {
8^bb0:
9  return
10}
11
12// CHECK-LABEL: llvm.func @body(!llvm.i64)
13func private @body(index)
14
15// CHECK-LABEL: func @simple_loop() {
16// CHECK32-LABEL: func @simple_loop() {
17func @simple_loop() {
18^bb0:
19// CHECK-NEXT:  llvm.br ^bb1
20// CHECK32-NEXT:  llvm.br ^bb1
21  br ^bb1
22
23// CHECK-NEXT: ^bb1:	// pred: ^bb0
24// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64
25// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64
26// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
27// CHECK32-NEXT: ^bb1:	// pred: ^bb0
28// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32
29// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i32
30// CHECK32-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i32)
31^bb1:	// pred: ^bb0
32  %c1 = constant 1 : index
33  %c42 = constant 42 : index
34  br ^bb2(%c1 : index)
35
36// CHECK:      ^bb2({{.*}}: !llvm.i64):	// 2 preds: ^bb1, ^bb3
37// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
38// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb4
39// CHECK32:      ^bb2({{.*}}: !llvm.i32):	// 2 preds: ^bb1, ^bb3
40// CHECK32-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i32
41// CHECK32-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb4
42^bb2(%0: index):	// 2 preds: ^bb1, ^bb3
43  %1 = cmpi "slt", %0, %c42 : index
44  cond_br %1, ^bb3, ^bb4
45
46// CHECK:      ^bb3:	// pred: ^bb2
47// CHECK-NEXT:  llvm.call @body({{.*}}) : (!llvm.i64) -> ()
48// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64
49// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
50// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
51// CHECK32:      ^bb3:	// pred: ^bb2
52// CHECK32-NEXT:  llvm.call @body({{.*}}) : (!llvm.i32) -> ()
53// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32
54// CHECK32-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i32
55// CHECK32-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i32)
56^bb3:	// pred: ^bb2
57  call @body(%0) : (index) -> ()
58  %c1_0 = constant 1 : index
59  %2 = addi %0, %c1_0 : index
60  br ^bb2(%2 : index)
61
62// CHECK:      ^bb4:	// pred: ^bb2
63// CHECK-NEXT:  llvm.return
64^bb4:	// pred: ^bb2
65  return
66}
67
68// CHECK-LABEL: llvm.func @complex_numbers()
69// CHECK-NEXT:    %[[REAL0:.*]] = llvm.mlir.constant(1.200000e+00 : f32) : !llvm.float
70// CHECK-NEXT:    %[[IMAG0:.*]] = llvm.mlir.constant(3.400000e+00 : f32) : !llvm.float
71// CHECK-NEXT:    %[[CPLX0:.*]] = llvm.mlir.undef : !llvm.struct<(float, float)>
72// CHECK-NEXT:    %[[CPLX1:.*]] = llvm.insertvalue %[[REAL0]], %[[CPLX0]][0] : !llvm.struct<(float, float)>
73// CHECK-NEXT:    %[[CPLX2:.*]] = llvm.insertvalue %[[IMAG0]], %[[CPLX1]][1] : !llvm.struct<(float, float)>
74// CHECK-NEXT:    %[[REAL1:.*]] = llvm.extractvalue %[[CPLX2:.*]][0] : !llvm.struct<(float, float)>
75// CHECK-NEXT:    %[[IMAG1:.*]] = llvm.extractvalue %[[CPLX2:.*]][1] : !llvm.struct<(float, float)>
76// CHECK-NEXT:    llvm.return
77func @complex_numbers() {
78  %real0 = constant 1.2 : f32
79  %imag0 = constant 3.4 : f32
80  %cplx2 = create_complex %real0, %imag0 : complex<f32>
81  %real1 = re %cplx2 : complex<f32>
82  %imag1 = im %cplx2 : complex<f32>
83  return
84}
85
86// CHECK-LABEL: llvm.func @complex_addition()
87// CHECK-DAG:     %[[A_REAL:.*]] = llvm.extractvalue %[[A:.*]][0] : !llvm.struct<(double, double)>
88// CHECK-DAG:     %[[B_REAL:.*]] = llvm.extractvalue %[[B:.*]][0] : !llvm.struct<(double, double)>
89// CHECK-DAG:     %[[A_IMAG:.*]] = llvm.extractvalue %[[A]][1] : !llvm.struct<(double, double)>
90// CHECK-DAG:     %[[B_IMAG:.*]] = llvm.extractvalue %[[B]][1] : !llvm.struct<(double, double)>
91// CHECK:         %[[C0:.*]] = llvm.mlir.undef : !llvm.struct<(double, double)>
92// CHECK-DAG:     %[[C_REAL:.*]] = llvm.fadd %[[A_REAL]], %[[B_REAL]] : !llvm.double
93// CHECK-DAG:     %[[C_IMAG:.*]] = llvm.fadd %[[A_IMAG]], %[[B_IMAG]] : !llvm.double
94// CHECK:         %[[C1:.*]] = llvm.insertvalue %[[C_REAL]], %[[C0]][0] : !llvm.struct<(double, double)>
95// CHECK:         %[[C2:.*]] = llvm.insertvalue %[[C_IMAG]], %[[C1]][1] : !llvm.struct<(double, double)>
96func @complex_addition() {
97  %a_re = constant 1.2 : f64
98  %a_im = constant 3.4 : f64
99  %a = create_complex %a_re, %a_im : complex<f64>
100  %b_re = constant 5.6 : f64
101  %b_im = constant 7.8 : f64
102  %b = create_complex %b_re, %b_im : complex<f64>
103  %c = addcf %a, %b : complex<f64>
104  return
105}
106
107// CHECK-LABEL: llvm.func @complex_substraction()
108// CHECK-DAG:     %[[A_REAL:.*]] = llvm.extractvalue %[[A:.*]][0] : !llvm.struct<(double, double)>
109// CHECK-DAG:     %[[B_REAL:.*]] = llvm.extractvalue %[[B:.*]][0] : !llvm.struct<(double, double)>
110// CHECK-DAG:     %[[A_IMAG:.*]] = llvm.extractvalue %[[A]][1] : !llvm.struct<(double, double)>
111// CHECK-DAG:     %[[B_IMAG:.*]] = llvm.extractvalue %[[B]][1] : !llvm.struct<(double, double)>
112// CHECK:         %[[C0:.*]] = llvm.mlir.undef : !llvm.struct<(double, double)>
113// CHECK-DAG:     %[[C_REAL:.*]] = llvm.fsub %[[A_REAL]], %[[B_REAL]] : !llvm.double
114// CHECK-DAG:     %[[C_IMAG:.*]] = llvm.fsub %[[A_IMAG]], %[[B_IMAG]] : !llvm.double
115// CHECK:         %[[C1:.*]] = llvm.insertvalue %[[C_REAL]], %[[C0]][0] : !llvm.struct<(double, double)>
116// CHECK:         %[[C2:.*]] = llvm.insertvalue %[[C_IMAG]], %[[C1]][1] : !llvm.struct<(double, double)>
117func @complex_substraction() {
118  %a_re = constant 1.2 : f64
119  %a_im = constant 3.4 : f64
120  %a = create_complex %a_re, %a_im : complex<f64>
121  %b_re = constant 5.6 : f64
122  %b_im = constant 7.8 : f64
123  %b = create_complex %b_re, %b_im : complex<f64>
124  %c = subcf %a, %b : complex<f64>
125  return
126}
127
128// CHECK-LABEL: func @simple_caller() {
129// CHECK-NEXT:  llvm.call @simple_loop() : () -> ()
130// CHECK-NEXT:  llvm.return
131// CHECK-NEXT: }
132func @simple_caller() {
133^bb0:
134  call @simple_loop() : () -> ()
135  return
136}
137
138// Check that function call attributes persist during conversion.
139// CHECK-LABEL: @call_with_attributes
140func @call_with_attributes() {
141  // CHECK: llvm.call @simple_loop() {baz = [1, 2, 3, 4], foo = "bar"} : () -> ()
142  call @simple_loop() {foo="bar", baz=[1,2,3,4]} : () -> ()
143  return
144}
145
146// CHECK-LABEL: func @ml_caller() {
147// CHECK-NEXT:  llvm.call @simple_loop() : () -> ()
148// CHECK-NEXT:  llvm.call @more_imperfectly_nested_loops() : () -> ()
149// CHECK-NEXT:  llvm.return
150// CHECK-NEXT: }
151func @ml_caller() {
152^bb0:
153  call @simple_loop() : () -> ()
154  call @more_imperfectly_nested_loops() : () -> ()
155  return
156}
157
158// CHECK-LABEL: llvm.func @body_args(!llvm.i64) -> !llvm.i64
159// CHECK32-LABEL: llvm.func @body_args(!llvm.i32) -> !llvm.i32
160func private @body_args(index) -> index
161// CHECK-LABEL: llvm.func @other(!llvm.i64, !llvm.i32) -> !llvm.i32
162// CHECK32-LABEL: llvm.func @other(!llvm.i32, !llvm.i32) -> !llvm.i32
163func private @other(index, i32) -> i32
164
165// CHECK-LABEL: func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 {
166// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(0 : i32) : !llvm.i32
167// CHECK-NEXT:  llvm.br ^bb1
168// CHECK32-LABEL: func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 {
169// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(0 : i32) : !llvm.i32
170// CHECK32-NEXT:  llvm.br ^bb1
171func @func_args(i32, i32) -> i32 {
172^bb0(%arg0: i32, %arg1: i32):
173  %c0_i32 = constant 0 : i32
174  br ^bb1
175
176// CHECK-NEXT: ^bb1:	// pred: ^bb0
177// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64
178// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64
179// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
180// CHECK32-NEXT: ^bb1:	// pred: ^bb0
181// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i32
182// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i32
183// CHECK32-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i32)
184^bb1:	// pred: ^bb0
185  %c0 = constant 0 : index
186  %c42 = constant 42 : index
187  br ^bb2(%c0 : index)
188
189// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64):	// 2 preds: ^bb1, ^bb3
190// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
191// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb4
192// CHECK32-NEXT: ^bb2({{.*}}: !llvm.i32):	// 2 preds: ^bb1, ^bb3
193// CHECK32-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i32
194// CHECK32-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb4
195^bb2(%0: index):	// 2 preds: ^bb1, ^bb3
196  %1 = cmpi "slt", %0, %c42 : index
197  cond_br %1, ^bb3, ^bb4
198
199// CHECK-NEXT: ^bb3:	// pred: ^bb2
200// CHECK-NEXT:  {{.*}} = llvm.call @body_args({{.*}}) : (!llvm.i64) -> !llvm.i64
201// CHECK-NEXT:  {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm.i64, !llvm.i32) -> !llvm.i32
202// CHECK-NEXT:  {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32
203// CHECK-NEXT:  {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm.i64, !llvm.i32) -> !llvm.i32
204// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64
205// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
206// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
207// CHECK32-NEXT: ^bb3:	// pred: ^bb2
208// CHECK32-NEXT:  {{.*}} = llvm.call @body_args({{.*}}) : (!llvm.i32) -> !llvm.i32
209// CHECK32-NEXT:  {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm.i32, !llvm.i32) -> !llvm.i32
210// CHECK32-NEXT:  {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i32, !llvm.i32) -> !llvm.i32
211// CHECK32-NEXT:  {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.i32
212// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32
213// CHECK32-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i32
214// CHECK32-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i32)
215^bb3:	// pred: ^bb2
216  %2 = call @body_args(%0) : (index) -> index
217  %3 = call @other(%2, %arg0) : (index, i32) -> i32
218  %4 = call @other(%2, %3) : (index, i32) -> i32
219  %5 = call @other(%2, %arg1) : (index, i32) -> i32
220  %c1 = constant 1 : index
221  %6 = addi %0, %c1 : index
222  br ^bb2(%6 : index)
223
224// CHECK-NEXT: ^bb4:	// pred: ^bb2
225// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64
226// CHECK-NEXT:  {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32
227// CHECK-NEXT:  llvm.return {{.*}} : !llvm.i32
228// CHECK32-NEXT: ^bb4:	// pred: ^bb2
229// CHECK32-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i32
230// CHECK32-NEXT:  {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i32, !llvm.i32) -> !llvm.i32
231// CHECK32-NEXT:  llvm.return {{.*}} : !llvm.i32
232^bb4:	// pred: ^bb2
233  %c0_0 = constant 0 : index
234  %7 = call @other(%c0_0, %c0_i32) : (index, i32) -> i32
235  return %7 : i32
236}
237
238// CHECK-LABEL: llvm.func @pre(!llvm.i64)
239// CHECK32-LABEL: llvm.func @pre(!llvm.i32)
240func private @pre(index)
241
242// CHECK-LABEL: llvm.func @body2(!llvm.i64, !llvm.i64)
243// CHECK32-LABEL: llvm.func @body2(!llvm.i32, !llvm.i32)
244func private @body2(index, index)
245
246// CHECK-LABEL: llvm.func @post(!llvm.i64)
247// CHECK32-LABEL: llvm.func @post(!llvm.i32)
248func private @post(index)
249
250// CHECK-LABEL: func @imperfectly_nested_loops() {
251// CHECK-NEXT:  llvm.br ^bb1
252func @imperfectly_nested_loops() {
253^bb0:
254  br ^bb1
255
256// CHECK-NEXT: ^bb1:	// pred: ^bb0
257// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64
258// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64
259// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
260^bb1:	// pred: ^bb0
261  %c0 = constant 0 : index
262  %c42 = constant 42 : index
263  br ^bb2(%c0 : index)
264
265// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64):	// 2 preds: ^bb1, ^bb7
266// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
267// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb8
268^bb2(%0: index):	// 2 preds: ^bb1, ^bb7
269  %1 = cmpi "slt", %0, %c42 : index
270  cond_br %1, ^bb3, ^bb8
271
272// CHECK-NEXT: ^bb3:
273// CHECK-NEXT:  llvm.call @pre({{.*}}) : (!llvm.i64) -> ()
274// CHECK-NEXT:  llvm.br ^bb4
275^bb3:	// pred: ^bb2
276  call @pre(%0) : (index) -> ()
277  br ^bb4
278
279// CHECK-NEXT: ^bb4:	// pred: ^bb3
280// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(7 : index) : !llvm.i64
281// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(56 : index) : !llvm.i64
282// CHECK-NEXT:  llvm.br ^bb5({{.*}} : !llvm.i64)
283^bb4:	// pred: ^bb3
284  %c7 = constant 7 : index
285  %c56 = constant 56 : index
286  br ^bb5(%c7 : index)
287
288// CHECK-NEXT: ^bb5({{.*}}: !llvm.i64):	// 2 preds: ^bb4, ^bb6
289// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
290// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb6, ^bb7
291^bb5(%2: index):	// 2 preds: ^bb4, ^bb6
292  %3 = cmpi "slt", %2, %c56 : index
293  cond_br %3, ^bb6, ^bb7
294
295// CHECK-NEXT: ^bb6:	// pred: ^bb5
296// CHECK-NEXT:  llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
297// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(2 : index) : !llvm.i64
298// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
299// CHECK-NEXT:  llvm.br ^bb5({{.*}} : !llvm.i64)
300^bb6:	// pred: ^bb5
301  call @body2(%0, %2) : (index, index) -> ()
302  %c2 = constant 2 : index
303  %4 = addi %2, %c2 : index
304  br ^bb5(%4 : index)
305
306// CHECK-NEXT: ^bb7:	// pred: ^bb5
307// CHECK-NEXT:  llvm.call @post({{.*}}) : (!llvm.i64) -> ()
308// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64
309// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
310// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
311^bb7:	// pred: ^bb5
312  call @post(%0) : (index) -> ()
313  %c1 = constant 1 : index
314  %5 = addi %0, %c1 : index
315  br ^bb2(%5 : index)
316
317// CHECK-NEXT: ^bb8:	// pred: ^bb2
318// CHECK-NEXT:  llvm.return
319^bb8:	// pred: ^bb2
320  return
321}
322
323// CHECK-LABEL: llvm.func @mid(!llvm.i64)
324func private @mid(index)
325
326// CHECK-LABEL: llvm.func @body3(!llvm.i64, !llvm.i64)
327func private @body3(index, index)
328
329// A complete function transformation check.
330// CHECK-LABEL: func @more_imperfectly_nested_loops() {
331// CHECK-NEXT:  llvm.br ^bb1
332// CHECK-NEXT:^bb1:	// pred: ^bb0
333// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64
334// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64
335// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
336// CHECK-NEXT:^bb2({{.*}}: !llvm.i64):	// 2 preds: ^bb1, ^bb11
337// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
338// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb3, ^bb12
339// CHECK-NEXT:^bb3:	// pred: ^bb2
340// CHECK-NEXT:  llvm.call @pre({{.*}}) : (!llvm.i64) -> ()
341// CHECK-NEXT:  llvm.br ^bb4
342// CHECK-NEXT:^bb4:	// pred: ^bb3
343// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(7 : index) : !llvm.i64
344// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(56 : index) : !llvm.i64
345// CHECK-NEXT:  llvm.br ^bb5({{.*}} : !llvm.i64)
346// CHECK-NEXT:^bb5({{.*}}: !llvm.i64):	// 2 preds: ^bb4, ^bb6
347// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
348// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb6, ^bb7
349// CHECK-NEXT:^bb6:	// pred: ^bb5
350// CHECK-NEXT:  llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
351// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(2 : index) : !llvm.i64
352// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
353// CHECK-NEXT:  llvm.br ^bb5({{.*}} : !llvm.i64)
354// CHECK-NEXT:^bb7:	// pred: ^bb5
355// CHECK-NEXT:  llvm.call @mid({{.*}}) : (!llvm.i64) -> ()
356// CHECK-NEXT:  llvm.br ^bb8
357// CHECK-NEXT:^bb8:	// pred: ^bb7
358// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(18 : index) : !llvm.i64
359// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(37 : index) : !llvm.i64
360// CHECK-NEXT:  llvm.br ^bb9({{.*}} : !llvm.i64)
361// CHECK-NEXT:^bb9({{.*}}: !llvm.i64):	// 2 preds: ^bb8, ^bb10
362// CHECK-NEXT:  {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
363// CHECK-NEXT:  llvm.cond_br {{.*}}, ^bb10, ^bb11
364// CHECK-NEXT:^bb10:	// pred: ^bb9
365// CHECK-NEXT:  llvm.call @body3({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
366// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(3 : index) : !llvm.i64
367// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
368// CHECK-NEXT:  llvm.br ^bb9({{.*}} : !llvm.i64)
369// CHECK-NEXT:^bb11:	// pred: ^bb9
370// CHECK-NEXT:  llvm.call @post({{.*}}) : (!llvm.i64) -> ()
371// CHECK-NEXT:  {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64
372// CHECK-NEXT:  {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
373// CHECK-NEXT:  llvm.br ^bb2({{.*}} : !llvm.i64)
374// CHECK-NEXT:^bb12:	// pred: ^bb2
375// CHECK-NEXT:  llvm.return
376// CHECK-NEXT: }
377func @more_imperfectly_nested_loops() {
378^bb0:
379  br ^bb1
380^bb1:	// pred: ^bb0
381  %c0 = constant 0 : index
382  %c42 = constant 42 : index
383  br ^bb2(%c0 : index)
384^bb2(%0: index):	// 2 preds: ^bb1, ^bb11
385  %1 = cmpi "slt", %0, %c42 : index
386  cond_br %1, ^bb3, ^bb12
387^bb3:	// pred: ^bb2
388  call @pre(%0) : (index) -> ()
389  br ^bb4
390^bb4:	// pred: ^bb3
391  %c7 = constant 7 : index
392  %c56 = constant 56 : index
393  br ^bb5(%c7 : index)
394^bb5(%2: index):	// 2 preds: ^bb4, ^bb6
395  %3 = cmpi "slt", %2, %c56 : index
396  cond_br %3, ^bb6, ^bb7
397^bb6:	// pred: ^bb5
398  call @body2(%0, %2) : (index, index) -> ()
399  %c2 = constant 2 : index
400  %4 = addi %2, %c2 : index
401  br ^bb5(%4 : index)
402^bb7:	// pred: ^bb5
403  call @mid(%0) : (index) -> ()
404  br ^bb8
405^bb8:	// pred: ^bb7
406  %c18 = constant 18 : index
407  %c37 = constant 37 : index
408  br ^bb9(%c18 : index)
409^bb9(%5: index):	// 2 preds: ^bb8, ^bb10
410  %6 = cmpi "slt", %5, %c37 : index
411  cond_br %6, ^bb10, ^bb11
412^bb10:	// pred: ^bb9
413  call @body3(%0, %5) : (index, index) -> ()
414  %c3 = constant 3 : index
415  %7 = addi %5, %c3 : index
416  br ^bb9(%7 : index)
417^bb11:	// pred: ^bb9
418  call @post(%0) : (index) -> ()
419  %c1 = constant 1 : index
420  %8 = addi %0, %c1 : index
421  br ^bb2(%8 : index)
422^bb12:	// pred: ^bb2
423  return
424}
425
426// CHECK-LABEL: llvm.func @get_i64() -> !llvm.i64
427func private @get_i64() -> (i64)
428// CHECK-LABEL: llvm.func @get_f32() -> !llvm.float
429func private @get_f32() -> (f32)
430// CHECK-LABEL: llvm.func @get_c16() -> !llvm.struct<(half, half)>
431func private @get_c16() -> (complex<f16>)
432// CHECK-LABEL: llvm.func @get_c32() -> !llvm.struct<(float, float)>
433func private @get_c32() -> (complex<f32>)
434// CHECK-LABEL: llvm.func @get_c64() -> !llvm.struct<(double, double)>
435func private @get_c64() -> (complex<f64>)
436// CHECK-LABEL: llvm.func @get_memref() -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>
437// CHECK32-LABEL: llvm.func @get_memref() -> !llvm.struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>
438func private @get_memref() -> (memref<42x?x10x?xf32>)
439
440// CHECK-LABEL: llvm.func @multireturn() -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> {
441// CHECK32-LABEL: llvm.func @multireturn() -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> {
442func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) {
443^bb0:
444// CHECK-NEXT:  {{.*}} = llvm.call @get_i64() : () -> !llvm.i64
445// CHECK-NEXT:  {{.*}} = llvm.call @get_f32() : () -> !llvm.float
446// CHECK-NEXT:  {{.*}} = llvm.call @get_memref() : () -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>
447// CHECK32-NEXT:  {{.*}} = llvm.call @get_i64() : () -> !llvm.i64
448// CHECK32-NEXT:  {{.*}} = llvm.call @get_f32() : () -> !llvm.float
449// CHECK32-NEXT:  {{.*}} = llvm.call @get_memref() : () -> !llvm.struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>
450  %0 = call @get_i64() : () -> (i64)
451  %1 = call @get_f32() : () -> (f32)
452  %2 = call @get_memref() : () -> (memref<42x?x10x?xf32>)
453// CHECK-NEXT:  {{.*}} = llvm.mlir.undef : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
454// CHECK-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
455// CHECK-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
456// CHECK-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
457// CHECK-NEXT:  llvm.return {{.*}} : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
458// CHECK32-NEXT:  {{.*}} = llvm.mlir.undef : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
459// CHECK32-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
460// CHECK32-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
461// CHECK32-NEXT:  {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
462// CHECK32-NEXT:  llvm.return {{.*}} : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
463  return %0, %1, %2 : i64, f32, memref<42x?x10x?xf32>
464}
465
466
467// CHECK-LABEL: llvm.func @multireturn_caller() {
468// CHECK32-LABEL: llvm.func @multireturn_caller() {
469func @multireturn_caller() {
470^bb0:
471// CHECK-NEXT:  {{.*}} = llvm.call @multireturn() : () -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
472// CHECK-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
473// CHECK-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
474// CHECK-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)>
475// CHECK32-NEXT:  {{.*}} = llvm.call @multireturn() : () -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
476// CHECK32-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
477// CHECK32-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
478// CHECK32-NEXT:  {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)>
479  %0:3 = call @multireturn() : () -> (i64, f32, memref<42x?x10x?xf32>)
480  %1 = constant 42 : i64
481// CHECK:       {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
482  %2 = addi %0#0, %1 : i64
483  %3 = constant 42.0 : f32
484// CHECK:       {{.*}} = llvm.fadd {{.*}}, {{.*}} : !llvm.float
485  %4 = addf %0#1, %3 : f32
486  %5 = constant 0 : index
487  return
488}
489
490// CHECK-LABEL: llvm.func @vector_ops(%arg0: !llvm.vec<4 x float>, %arg1: !llvm.vec<4 x i1>, %arg2: !llvm.vec<4 x i64>, %arg3: !llvm.vec<4 x i64>) -> !llvm.vec<4 x float> {
491func @vector_ops(%arg0: vector<4xf32>, %arg1: vector<4xi1>, %arg2: vector<4xi64>, %arg3: vector<4xi64>) -> vector<4xf32> {
492// CHECK-NEXT:  %0 = llvm.mlir.constant(dense<4.200000e+01> : vector<4xf32>) : !llvm.vec<4 x float>
493  %0 = constant dense<42.> : vector<4xf32>
494// CHECK-NEXT:  %1 = llvm.fadd %arg0, %0 : !llvm.vec<4 x float>
495  %1 = addf %arg0, %0 : vector<4xf32>
496// CHECK-NEXT:  %2 = llvm.sdiv %arg2, %arg2 : !llvm.vec<4 x i64>
497  %3 = divi_signed %arg2, %arg2 : vector<4xi64>
498// CHECK-NEXT:  %3 = llvm.udiv %arg2, %arg2 : !llvm.vec<4 x i64>
499  %4 = divi_unsigned %arg2, %arg2 : vector<4xi64>
500// CHECK-NEXT:  %4 = llvm.srem %arg2, %arg2 : !llvm.vec<4 x i64>
501  %5 = remi_signed %arg2, %arg2 : vector<4xi64>
502// CHECK-NEXT:  %5 = llvm.urem %arg2, %arg2 : !llvm.vec<4 x i64>
503  %6 = remi_unsigned %arg2, %arg2 : vector<4xi64>
504// CHECK-NEXT:  %6 = llvm.fdiv %arg0, %0 : !llvm.vec<4 x float>
505  %7 = divf %arg0, %0 : vector<4xf32>
506// CHECK-NEXT:  %7 = llvm.frem %arg0, %0 : !llvm.vec<4 x float>
507  %8 = remf %arg0, %0 : vector<4xf32>
508// CHECK-NEXT:  %8 = llvm.and %arg2, %arg3 : !llvm.vec<4 x i64>
509  %9 = and %arg2, %arg3 : vector<4xi64>
510// CHECK-NEXT:  %9 = llvm.or %arg2, %arg3 : !llvm.vec<4 x i64>
511  %10 = or %arg2, %arg3 : vector<4xi64>
512// CHECK-NEXT:  %10 = llvm.xor %arg2, %arg3 : !llvm.vec<4 x i64>
513  %11 = xor %arg2, %arg3 : vector<4xi64>
514// CHECK-NEXT:  %11 = llvm.shl %arg2, %arg2 : !llvm.vec<4 x i64>
515  %12 = shift_left %arg2, %arg2 : vector<4xi64>
516// CHECK-NEXT:  %12 = llvm.ashr %arg2, %arg2 : !llvm.vec<4 x i64>
517  %13 = shift_right_signed %arg2, %arg2 : vector<4xi64>
518// CHECK-NEXT:  %13 = llvm.lshr %arg2, %arg2 : !llvm.vec<4 x i64>
519  %14 = shift_right_unsigned %arg2, %arg2 : vector<4xi64>
520  return %1 : vector<4xf32>
521}
522
523// CHECK-LABEL: @ops
524func @ops(f32, f32, i32, i32, f64) -> (f32, i32) {
525^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64):
526// CHECK-NEXT:  %0 = llvm.fsub %arg0, %arg1 : !llvm.float
527  %0 = subf %arg0, %arg1: f32
528// CHECK-NEXT:  %1 = llvm.sub %arg2, %arg3 : !llvm.i32
529  %1 = subi %arg2, %arg3: i32
530// CHECK-NEXT:  %2 = llvm.icmp "slt" %arg2, %1 : !llvm.i32
531  %2 = cmpi "slt", %arg2, %1 : i32
532// CHECK-NEXT:  %3 = llvm.sdiv %arg2, %arg3 : !llvm.i32
533  %3 = divi_signed %arg2, %arg3 : i32
534// CHECK-NEXT:  %4 = llvm.udiv %arg2, %arg3 : !llvm.i32
535  %4 = divi_unsigned %arg2, %arg3 : i32
536// CHECK-NEXT:  %5 = llvm.srem %arg2, %arg3 : !llvm.i32
537  %5 = remi_signed %arg2, %arg3 : i32
538// CHECK-NEXT:  %6 = llvm.urem %arg2, %arg3 : !llvm.i32
539  %6 = remi_unsigned %arg2, %arg3 : i32
540// CHECK-NEXT:  %7 = llvm.select %2, %arg2, %arg3 : !llvm.i1, !llvm.i32
541  %7 = select %2, %arg2, %arg3 : i32
542// CHECK-NEXT:  %8 = llvm.fdiv %arg0, %arg1 : !llvm.float
543  %8 = divf %arg0, %arg1 : f32
544// CHECK-NEXT:  %9 = llvm.frem %arg0, %arg1 : !llvm.float
545  %9 = remf %arg0, %arg1 : f32
546// CHECK-NEXT: %10 = llvm.and %arg2, %arg3 : !llvm.i32
547  %10 = and %arg2, %arg3 : i32
548// CHECK-NEXT: %11 = llvm.or %arg2, %arg3 : !llvm.i32
549  %11 = or %arg2, %arg3 : i32
550// CHECK-NEXT: %12 = llvm.xor %arg2, %arg3 : !llvm.i32
551  %12 = xor %arg2, %arg3 : i32
552// CHECK-NEXT: %13 = "llvm.intr.exp"(%arg0) : (!llvm.float) -> !llvm.float
553  %13 = std.exp %arg0 : f32
554// CHECK-NEXT: %14 = "llvm.intr.exp2"(%arg0) : (!llvm.float) -> !llvm.float
555  %14 = std.exp2 %arg0 : f32
556// CHECK-NEXT: %15 = llvm.mlir.constant(7.900000e-01 : f64) : !llvm.double
557  %15 = constant 7.9e-01 : f64
558// CHECK-NEXT: %16 = llvm.shl %arg2, %arg3 : !llvm.i32
559  %16 = shift_left %arg2, %arg3 : i32
560// CHECK-NEXT: %17 = llvm.ashr %arg2, %arg3 : !llvm.i32
561  %17 = shift_right_signed %arg2, %arg3 : i32
562// CHECK-NEXT: %18 = llvm.lshr %arg2, %arg3 : !llvm.i32
563  %18 = shift_right_unsigned %arg2, %arg3 : i32
564// CHECK-NEXT: %{{[0-9]+}} = "llvm.intr.sqrt"(%arg0) : (!llvm.float) -> !llvm.float
565  %19 = std.sqrt %arg0 : f32
566// CHECK-NEXT: %{{[0-9]+}} = "llvm.intr.sqrt"(%arg4) : (!llvm.double) -> !llvm.double
567  %20 = std.sqrt %arg4 : f64
568  return %0, %4 : f32, i32
569}
570
571// Checking conversion of index types to integers using i1, assuming no target
572// system would have a 1-bit address space.  Otherwise, we would have had to
573// make this test dependent on the pointer size on the target system.
574// CHECK-LABEL: @index_cast
575func @index_cast(%arg0: index, %arg1: i1) {
576// CHECK-NEXT: = llvm.trunc %arg0 : !llvm.i{{.*}} to !llvm.i1
577  %0 = index_cast %arg0: index to i1
578// CHECK-NEXT: = llvm.sext %arg1 : !llvm.i1 to !llvm.i{{.*}}
579  %1 = index_cast %arg1: i1 to index
580  return
581}
582
583// Checking conversion of signed integer types to floating point.
584// CHECK-LABEL: @sitofp
585func @sitofp(%arg0 : i32, %arg1 : i64) {
586// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i32 to !llvm.float
587  %0 = sitofp %arg0: i32 to f32
588// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i32 to !llvm.double
589  %1 = sitofp %arg0: i32 to f64
590// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i64 to !llvm.float
591  %2 = sitofp %arg1: i64 to f32
592// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i64 to !llvm.double
593  %3 = sitofp %arg1: i64 to f64
594  return
595}
596
597// Checking conversion of integer vectors to floating point vector types.
598// CHECK-LABEL: @sitofp_vector
599func @sitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
600// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x float>
601  %0 = sitofp %arg0: vector<2xi16> to vector<2xf32>
602// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x double>
603  %1 = sitofp %arg0: vector<2xi16> to vector<2xf64>
604// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x float>
605  %2 = sitofp %arg1: vector<2xi32> to vector<2xf32>
606// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x double>
607  %3 = sitofp %arg1: vector<2xi32> to vector<2xf64>
608// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x float>
609  %4 = sitofp %arg2: vector<2xi64> to vector<2xf32>
610// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x double>
611  %5 = sitofp %arg2: vector<2xi64> to vector<2xf64>
612  return
613}
614
615// Checking conversion of unsigned integer types to floating point.
616// CHECK-LABEL: @uitofp
617func @uitofp(%arg0 : i32, %arg1 : i64) {
618// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.float
619  %0 = uitofp %arg0: i32 to f32
620// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.double
621  %1 = uitofp %arg0: i32 to f64
622// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.float
623  %2 = uitofp %arg1: i64 to f32
624// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.double
625  %3 = uitofp %arg1: i64 to f64
626  return
627}
628
629// Checking conversion of integer types to floating point.
630// CHECK-LABEL: @fpext
631func @fpext(%arg0 : f16, %arg1 : f32) {
632// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.half to !llvm.float
633  %0 = fpext %arg0: f16 to f32
634// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.half to !llvm.double
635  %1 = fpext %arg0: f16 to f64
636// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.float to !llvm.double
637  %2 = fpext %arg1: f32 to f64
638  return
639}
640
641// Checking conversion of integer types to floating point.
642// CHECK-LABEL: @fpext
643func @fpext_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>) {
644// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x float>
645  %0 = fpext %arg0: vector<2xf16> to vector<2xf32>
646// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x double>
647  %1 = fpext %arg0: vector<2xf16> to vector<2xf64>
648// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x double>
649  %2 = fpext %arg1: vector<2xf32> to vector<2xf64>
650  return
651}
652
653// Checking conversion of floating point to integer types.
654// CHECK-LABEL: @fptosi
655func @fptosi(%arg0 : f32, %arg1 : f64) {
656// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.float to !llvm.i32
657  %0 = fptosi %arg0: f32 to i32
658// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.float to !llvm.i64
659  %1 = fptosi %arg0: f32 to i64
660// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.double to !llvm.i32
661  %2 = fptosi %arg1: f64 to i32
662// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.double to !llvm.i64
663  %3 = fptosi %arg1: f64 to i64
664  return
665}
666
667// Checking conversion of floating point vectors to integer vector types.
668// CHECK-LABEL: @fptosi_vector
669func @fptosi_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
670// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i32>
671  %0 = fptosi %arg0: vector<2xf16> to vector<2xi32>
672// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i64>
673  %1 = fptosi %arg0: vector<2xf16> to vector<2xi64>
674// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i32>
675  %2 = fptosi %arg1: vector<2xf32> to vector<2xi32>
676// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i64>
677  %3 = fptosi %arg1: vector<2xf32> to vector<2xi64>
678// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i32>
679  %4 = fptosi %arg2: vector<2xf64> to vector<2xi32>
680// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i64>
681  %5 = fptosi %arg2: vector<2xf64> to vector<2xi64>
682  return
683}
684
685// Checking conversion of floating point to integer types.
686// CHECK-LABEL: @fptoui
687func @fptoui(%arg0 : f32, %arg1 : f64) {
688// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i32
689  %0 = fptoui %arg0: f32 to i32
690// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i64
691  %1 = fptoui %arg0: f32 to i64
692// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i32
693  %2 = fptoui %arg1: f64 to i32
694// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i64
695  %3 = fptoui %arg1: f64 to i64
696  return
697}
698
699// Checking conversion of floating point vectors to integer vector types.
700// CHECK-LABEL: @fptoui_vector
701func @fptoui_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
702// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i32>
703  %0 = fptoui %arg0: vector<2xf16> to vector<2xi32>
704// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i64>
705  %1 = fptoui %arg0: vector<2xf16> to vector<2xi64>
706// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i32>
707  %2 = fptoui %arg1: vector<2xf32> to vector<2xi32>
708// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i64>
709  %3 = fptoui %arg1: vector<2xf32> to vector<2xi64>
710// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i32>
711  %4 = fptoui %arg2: vector<2xf64> to vector<2xi32>
712// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i64>
713  %5 = fptoui %arg2: vector<2xf64> to vector<2xi64>
714  return
715}
716
717// Checking conversion of integer vectors to floating point vector types.
718// CHECK-LABEL: @uitofp_vector
719func @uitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
720// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x float>
721  %0 = uitofp %arg0: vector<2xi16> to vector<2xf32>
722// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x double>
723  %1 = uitofp %arg0: vector<2xi16> to vector<2xf64>
724// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x float>
725  %2 = uitofp %arg1: vector<2xi32> to vector<2xf32>
726// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x double>
727  %3 = uitofp %arg1: vector<2xi32> to vector<2xf64>
728// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x float>
729  %4 = uitofp %arg2: vector<2xi64> to vector<2xf32>
730// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x double>
731  %5 = uitofp %arg2: vector<2xi64> to vector<2xf64>
732  return
733}
734
735// Checking conversion of integer types to floating point.
736// CHECK-LABEL: @fptrunc
737func @fptrunc(%arg0 : f32, %arg1 : f64) {
738// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.float to !llvm.half
739  %0 = fptrunc %arg0: f32 to f16
740// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.double to !llvm.half
741  %1 = fptrunc %arg1: f64 to f16
742// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.double to !llvm.float
743  %2 = fptrunc %arg1: f64 to f32
744  return
745}
746
747// Checking conversion of integer types to floating point.
748// CHECK-LABEL: @fptrunc
749func @fptrunc_vector(%arg0 : vector<2xf32>, %arg1 : vector<2xf64>) {
750// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x half>
751  %0 = fptrunc %arg0: vector<2xf32> to vector<2xf16>
752// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x half>
753  %1 = fptrunc %arg1: vector<2xf64> to vector<2xf16>
754// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x float>
755  %2 = fptrunc %arg1: vector<2xf64> to vector<2xf32>
756  return
757}
758
759// Check sign and zero extension and truncation of integers.
760// CHECK-LABEL: @integer_extension_and_truncation
761func @integer_extension_and_truncation() {
762// CHECK-NEXT:  %0 = llvm.mlir.constant(-3 : i3) : !llvm.i3
763  %0 = constant 5 : i3
764// CHECK-NEXT: = llvm.sext %0 : !llvm.i3 to !llvm.i6
765  %1 = sexti %0 : i3 to i6
766// CHECK-NEXT: = llvm.zext %0 : !llvm.i3 to !llvm.i6
767  %2 = zexti %0 : i3 to i6
768// CHECK-NEXT: = llvm.trunc %0 : !llvm.i3 to !llvm.i2
769   %3 = trunci %0 : i3 to i2
770  return
771}
772
773// CHECK-LABEL: @dfs_block_order
774func @dfs_block_order(%arg0: i32) -> (i32) {
775// CHECK-NEXT:  %[[CST:.*]] = llvm.mlir.constant(42 : i32) : !llvm.i32
776  %0 = constant 42 : i32
777// CHECK-NEXT:  llvm.br ^bb2
778  br ^bb2
779
780// CHECK-NEXT: ^bb1:
781// CHECK-NEXT:  %[[ADD:.*]] = llvm.add %arg0, %[[CST]] : !llvm.i32
782// CHECK-NEXT:  llvm.return %[[ADD]] : !llvm.i32
783^bb1:
784  %2 = addi %arg0, %0 : i32
785  return %2 : i32
786
787// CHECK-NEXT: ^bb2:
788^bb2:
789// CHECK-NEXT:  llvm.br ^bb1
790  br ^bb1
791}
792
793// CHECK-LABEL: func @fcmp(%arg0: !llvm.float, %arg1: !llvm.float) {
794func @fcmp(f32, f32) -> () {
795^bb0(%arg0: f32, %arg1: f32):
796  // CHECK:      llvm.fcmp "oeq" %arg0, %arg1 : !llvm.float
797  // CHECK-NEXT: llvm.fcmp "ogt" %arg0, %arg1 : !llvm.float
798  // CHECK-NEXT: llvm.fcmp "oge" %arg0, %arg1 : !llvm.float
799  // CHECK-NEXT: llvm.fcmp "olt" %arg0, %arg1 : !llvm.float
800  // CHECK-NEXT: llvm.fcmp "ole" %arg0, %arg1 : !llvm.float
801  // CHECK-NEXT: llvm.fcmp "one" %arg0, %arg1 : !llvm.float
802  // CHECK-NEXT: llvm.fcmp "ord" %arg0, %arg1 : !llvm.float
803  // CHECK-NEXT: llvm.fcmp "ueq" %arg0, %arg1 : !llvm.float
804  // CHECK-NEXT: llvm.fcmp "ugt" %arg0, %arg1 : !llvm.float
805  // CHECK-NEXT: llvm.fcmp "uge" %arg0, %arg1 : !llvm.float
806  // CHECK-NEXT: llvm.fcmp "ult" %arg0, %arg1 : !llvm.float
807  // CHECK-NEXT: llvm.fcmp "ule" %arg0, %arg1 : !llvm.float
808  // CHECK-NEXT: llvm.fcmp "une" %arg0, %arg1 : !llvm.float
809  // CHECK-NEXT: llvm.fcmp "uno" %arg0, %arg1 : !llvm.float
810  // CHECK-NEXT: llvm.return
811  %1 = cmpf "oeq", %arg0, %arg1 : f32
812  %2 = cmpf "ogt", %arg0, %arg1 : f32
813  %3 = cmpf "oge", %arg0, %arg1 : f32
814  %4 = cmpf "olt", %arg0, %arg1 : f32
815  %5 = cmpf "ole", %arg0, %arg1 : f32
816  %6 = cmpf "one", %arg0, %arg1 : f32
817  %7 = cmpf "ord", %arg0, %arg1 : f32
818  %8 = cmpf "ueq", %arg0, %arg1 : f32
819  %9 = cmpf "ugt", %arg0, %arg1 : f32
820  %10 = cmpf "uge", %arg0, %arg1 : f32
821  %11 = cmpf "ult", %arg0, %arg1 : f32
822  %12 = cmpf "ule", %arg0, %arg1 : f32
823  %13 = cmpf "une", %arg0, %arg1 : f32
824  %14 = cmpf "uno", %arg0, %arg1 : f32
825
826  return
827}
828
829// CHECK-LABEL: @vec_bin
830func @vec_bin(%arg0: vector<2x2x2xf32>) -> vector<2x2x2xf32> {
831  %0 = addf %arg0, %arg0 : vector<2x2x2xf32>
832  return %0 : vector<2x2x2xf32>
833
834//  CHECK-NEXT: llvm.mlir.undef : !llvm.array<2 x array<2 x vec<2 x float>>>
835
836// This block appears 2x2 times
837//  CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>>
838//  CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>>
839//  CHECK-NEXT: llvm.fadd %{{.*}} : !llvm.vec<2 x float>
840//  CHECK-NEXT: llvm.insertvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>>
841
842// We check the proper indexing of extract/insert in the remaining 3 positions.
843//       CHECK: llvm.extractvalue %{{.*}}[0, 1] : !llvm.array<2 x array<2 x vec<2 x float>>>
844//       CHECK: llvm.insertvalue %{{.*}}[0, 1] : !llvm.array<2 x array<2 x vec<2 x float>>>
845//       CHECK: llvm.extractvalue %{{.*}}[1, 0] : !llvm.array<2 x array<2 x vec<2 x float>>>
846//       CHECK: llvm.insertvalue %{{.*}}[1, 0] : !llvm.array<2 x array<2 x vec<2 x float>>>
847//       CHECK: llvm.extractvalue %{{.*}}[1, 1] : !llvm.array<2 x array<2 x vec<2 x float>>>
848//       CHECK: llvm.insertvalue %{{.*}}[1, 1] : !llvm.array<2 x array<2 x vec<2 x float>>>
849
850// And we're done
851//   CHECK-NEXT: return
852}
853
854// CHECK-LABEL: @splat
855// CHECK-SAME: %[[A:arg[0-9]+]]: !llvm.vec<4 x float>
856// CHECK-SAME: %[[ELT:arg[0-9]+]]: !llvm.float
857func @splat(%a: vector<4xf32>, %b: f32) -> vector<4xf32> {
858  %vb = splat %b : vector<4xf32>
859  %r = mulf %a, %vb : vector<4xf32>
860  return %r : vector<4xf32>
861}
862// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : !llvm.vec<4 x float>
863// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : !llvm.i32
864// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ELT]], %[[UNDEF]][%[[ZERO]] : !llvm.i32] : !llvm.vec<4 x float>
865// CHECK-NEXT: %[[SPLAT:[0-9]+]] = llvm.shufflevector %[[V]], %[[UNDEF]] [0 : i32, 0 : i32, 0 : i32, 0 : i32]
866// CHECK-NEXT: %[[SCALE:[0-9]+]] = llvm.fmul %[[A]], %[[SPLAT]] : !llvm.vec<4 x float>
867// CHECK-NEXT: llvm.return %[[SCALE]] : !llvm.vec<4 x float>
868
869// CHECK-LABEL: func @view(
870// CHECK: %[[ARG0:.*]]: !llvm.i64, %[[ARG1:.*]]: !llvm.i64, %[[ARG2:.*]]: !llvm.i64
871func @view(%arg0 : index, %arg1 : index, %arg2 : index) {
872  // CHECK: llvm.mlir.constant(2048 : index) : !llvm.i64
873  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)>
874  %0 = alloc() : memref<2048xi8>
875
876  // Test two dynamic sizes.
877  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
878  // CHECK: %[[BASE_PTR:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)>
879  // CHECK: %[[SHIFTED_BASE_PTR:.*]] = llvm.getelementptr %[[BASE_PTR]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8>
880  // CHECK: %[[CAST_SHIFTED_BASE_PTR:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR]] : !llvm.ptr<i8> to !llvm.ptr<float>
881  // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
882  // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
883  // CHECK: llvm.insertvalue %[[C0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
884  // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
885  // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64
886  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
887  // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
888  // CHECK: llvm.mul %{{.*}}, %[[ARG1]]
889  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
890  %1 = view %0[%arg2][%arg0, %arg1] : memref<2048xi8> to memref<?x?xf32>
891
892  // Test one dynamic size.
893  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
894  // CHECK: %[[BASE_PTR_2:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)>
895  // CHECK: %[[SHIFTED_BASE_PTR_2:.*]] = llvm.getelementptr %[[BASE_PTR_2]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8>
896  // CHECK: %[[CAST_SHIFTED_BASE_PTR_2:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_2]] : !llvm.ptr<i8> to !llvm.ptr<float>
897  // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_2]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
898  // CHECK: %[[C0_2:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
899  // CHECK: llvm.insertvalue %[[C0_2]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
900  // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
901  // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64
902  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
903  // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64
904  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
905  // CHECK: llvm.mul %{{.*}}, %[[ARG1]]
906  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
907  %3 = view %0[%arg2][%arg1] : memref<2048xi8> to memref<4x?xf32>
908
909  // Test static sizes.
910  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
911  // CHECK: %[[BASE_PTR_3:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)>
912  // CHECK: %[[SHIFTED_BASE_PTR_3:.*]] = llvm.getelementptr %[[BASE_PTR_3]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8>
913  // CHECK: %[[CAST_SHIFTED_BASE_PTR_3:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_3]] : !llvm.ptr<i8> to !llvm.ptr<float>
914  // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_3]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
915  // CHECK: %[[C0_3:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
916  // CHECK: llvm.insertvalue %[[C0_3]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
917  // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64
918  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
919  // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64
920  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
921  // CHECK: llvm.mlir.constant(64 : index) : !llvm.i64
922  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
923  // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64
924  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
925  %5 = view %0[%arg2][] : memref<2048xi8> to memref<64x4xf32>
926
927  // Test view memory space.
928  // CHECK: llvm.mlir.constant(2048 : index) : !llvm.i64
929  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<i8, 4>, ptr<i8, 4>, i64, array<1 x i64>, array<1 x i64>)>
930  %6 = alloc() : memref<2048xi8, 4>
931
932  // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
933  // CHECK: %[[BASE_PTR_4:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8, 4>, ptr<i8, 4>, i64, array<1 x i64>, array<1 x i64>)>
934  // CHECK: %[[SHIFTED_BASE_PTR_4:.*]] = llvm.getelementptr %[[BASE_PTR_4]][%[[ARG2]]] : (!llvm.ptr<i8, 4>, !llvm.i64) -> !llvm.ptr<i8, 4>
935  // CHECK: %[[CAST_SHIFTED_BASE_PTR_4:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_4]] : !llvm.ptr<i8, 4> to !llvm.ptr<float, 4>
936  // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_4]], %{{.*}}[1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
937  // CHECK: %[[C0_4:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
938  // CHECK: llvm.insertvalue %[[C0_4]], %{{.*}}[2] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
939  // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64
940  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
941  // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64
942  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
943  // CHECK: llvm.mlir.constant(64 : index) : !llvm.i64
944  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
945  // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64
946  // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)>
947  %7 = view %6[%arg2][] : memref<2048xi8, 4> to memref<64x4xf32, 4>
948
949  return
950}
951
952// CHECK-LABEL: func @subview(
953// CHECK-COUNT-2: !llvm.ptr<float>,
954// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64,
955// CHECK:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64,
956// CHECK:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64,
957// CHECK:         %[[ARG2:.*]]: !llvm.i64)
958// CHECK32-LABEL: func @subview(
959// CHECK32-COUNT-2: !llvm.ptr<float>,
960// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32,
961// CHECK32:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32,
962// CHECK32:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32,
963// CHECK32:         %[[ARG2:.*]]: !llvm.i32)
964func @subview(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) {
965  // The last "insertvalue" that populates the memref descriptor from the function arguments.
966  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
967  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
968
969  // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
970  // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
971  // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
972  // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
973  // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
974  // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
975  // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
976  // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
977  // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64
978  // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64
979  // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64
980  // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64
981  // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
982  // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
983  // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64
984  // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
985  // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
986  // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64
987  // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
988  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
989  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
990  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
991  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
992  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
993  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
994  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
995  // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
996  // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32
997  // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32
998  // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32
999  // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32
1000  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1001  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1002  // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32
1003  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1004  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1005  // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32
1006
1007  %1 = subview %0[%arg0, %arg1][%arg0, %arg1][%arg0, %arg1] :
1008    memref<64x4xf32, offset: 0, strides: [4, 1]>
1009  to memref<?x?xf32, offset: ?, strides: [?, ?]>
1010  return
1011}
1012
1013// CHECK-LABEL: func @subview_non_zero_addrspace(
1014// CHECK-COUNT-2: !llvm.ptr<float, 3>,
1015// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64,
1016// CHECK:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64,
1017// CHECK:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64,
1018// CHECK:         %[[ARG2:.*]]: !llvm.i64)
1019// CHECK32-LABEL: func @subview_non_zero_addrspace(
1020// CHECK32-COUNT-2: !llvm.ptr<float, 3>,
1021// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32,
1022// CHECK32:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32,
1023// CHECK32:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32,
1024// CHECK32:         %[[ARG2:.*]]: !llvm.i32)
1025func @subview_non_zero_addrspace(%0 : memref<64x4xf32, offset: 0, strides: [4, 1], 3>, %arg0 : index, %arg1 : index, %arg2 : index) {
1026  // The last "insertvalue" that populates the memref descriptor from the function arguments.
1027  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1028  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1029
1030  // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1031  // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3>
1032  // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1033  // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3>
1034  // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1035  // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1036  // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1037  // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1038  // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64
1039  // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64
1040  // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64
1041  // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64
1042  // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1043  // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1044  // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64
1045  // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1046  // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1047  // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64
1048  // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)>
1049  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1050  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3>
1051  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1052  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3>
1053  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1054  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1055  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1056  // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1057  // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32
1058  // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32
1059  // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32
1060  // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32
1061  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1062  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1063  // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32
1064  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1065  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)>
1066  // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32
1067
1068  %1 = subview %0[%arg0, %arg1][%arg0, %arg1][%arg0, %arg1] :
1069    memref<64x4xf32, offset: 0, strides: [4, 1], 3>
1070    to memref<?x?xf32, offset: ?, strides: [?, ?], 3>
1071  return
1072}
1073
1074// CHECK-LABEL: func @subview_const_size(
1075// CHECK-SAME:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1076// CHECK-SAME:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1077// CHECK-SAME:         %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64
1078// CHECK-SAME:         %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64
1079// CHECK-SAME:         %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64
1080// CHECK-SAME:         %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64
1081// CHECK-SAME:         %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64
1082// CHECK-SAME:         %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i64
1083// CHECK-SAME:         %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i64
1084// CHECK-SAME:         %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i64
1085// CHECK32-LABEL: func @subview_const_size(
1086// CHECK32-SAME:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1087// CHECK32-SAME:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1088// CHECK32-SAME:         %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i32
1089// CHECK32-SAME:         %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i32
1090// CHECK32-SAME:         %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i32
1091// CHECK32-SAME:         %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i32
1092// CHECK32-SAME:         %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i32
1093// CHECK32-SAME:         %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i32
1094// CHECK32-SAME:         %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i32
1095// CHECK32-SAME:         %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i32
1096func @subview_const_size(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) {
1097  // The last "insertvalue" that populates the memref descriptor from the function arguments.
1098  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1099  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1100
1101  // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1102  // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1103  // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1104  // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1105  // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1106  // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1107  // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1108  // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1109  // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64
1110  // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64
1111  // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64
1112  // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64
1113  // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1114  // CHECK: %[[CST2:.*]] = llvm.mlir.constant(2 : i64)
1115  // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[CST2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1116  // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64
1117  // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1118  // CHECK: %[[CST4:.*]] = llvm.mlir.constant(4 : i64)
1119  // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[CST4]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1120  // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64
1121  // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1122  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1123  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1124  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1125  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1126  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1127  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1128  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1129  // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1130  // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32
1131  // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32
1132  // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32
1133  // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32
1134  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1135  // CHECK32: %[[CST2:.*]] = llvm.mlir.constant(2 : i64)
1136  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[CST2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1137  // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32
1138  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1139  // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64)
1140  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST4]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1141  // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32
1142  // CHECK32: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1143  %1 = subview %0[%arg0, %arg1][4, 2][%arg0, %arg1] :
1144    memref<64x4xf32, offset: 0, strides: [4, 1]>
1145    to memref<4x2xf32, offset: ?, strides: [?, ?]>
1146  return
1147}
1148
1149// CHECK-LABEL: func @subview_const_stride(
1150// CHECK-SAME:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1151// CHECK-SAME:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1152// CHECK-SAME:         %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64
1153// CHECK-SAME:         %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64
1154// CHECK-SAME:         %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64
1155// CHECK-SAME:         %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64
1156// CHECK-SAME:         %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64
1157// CHECK-SAME:         %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i64
1158// CHECK-SAME:         %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i64
1159// CHECK-SAME:         %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i64
1160// CHECK32-LABEL: func @subview_const_stride(
1161// CHECK32-SAME:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1162// CHECK32-SAME:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>,
1163// CHECK32-SAME:         %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i32
1164// CHECK32-SAME:         %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i32
1165// CHECK32-SAME:         %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i32
1166// CHECK32-SAME:         %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i32
1167// CHECK32-SAME:         %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i32
1168// CHECK32-SAME:         %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i32
1169// CHECK32-SAME:         %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i32
1170// CHECK32-SAME:         %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i32
1171func @subview_const_stride(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) {
1172  // The last "insertvalue" that populates the memref descriptor from the function arguments.
1173  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1174  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1175
1176  // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1177  // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1178  // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1179  // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1180  // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1181  // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1182  // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1183  // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1184  // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64
1185  // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64
1186  // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64
1187  // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64
1188  // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1189  // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG8]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1190  // CHECK: %[[CST2:.*]] = llvm.mlir.constant(2 : i64)
1191  // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[CST2]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1192  // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG7]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1193  // CHECK: %[[CST4:.*]] = llvm.mlir.constant(4 : i64)
1194  // CHECK: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)>
1195  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1196  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1197  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1198  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1199  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1200  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1201  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1202  // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1203  // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32
1204  // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32
1205  // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32
1206  // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32
1207  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1208  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG8]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1209  // CHECK32: %[[CST2:.*]] = llvm.mlir.constant(2 : i64)
1210  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST2]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1211  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG7]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1212  // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64)
1213  // CHECK32: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1214  %1 = subview %0[%arg0, %arg1][%arg0, %arg1][1, 2] :
1215    memref<64x4xf32, offset: 0, strides: [4, 1]>
1216    to memref<?x?xf32, offset: ?, strides: [4, 2]>
1217  return
1218}
1219
1220// CHECK-LABEL: func @subview_const_stride_and_offset(
1221// CHECK32-LABEL: func @subview_const_stride_and_offset(
1222func @subview_const_stride_and_offset(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>) {
1223  // The last "insertvalue" that populates the memref descriptor from the function arguments.
1224  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1225  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1226
1227  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1228  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1229  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1230  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1231  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1232  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1233  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1234  // CHECK32: %[[CST8:.*]] = llvm.mlir.constant(8 : index)
1235  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[CST8]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1236  // CHECK32: %[[CST3:.*]] = llvm.mlir.constant(3 : i64)
1237  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[CST3]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1238  // CHECK32: %[[CST1:.*]] = llvm.mlir.constant(1 : i64)
1239  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1240  // CHECK32: %[[CST62:.*]] = llvm.mlir.constant(62 : i64)
1241  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST62]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1242  // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64)
1243  // CHECK32: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1244  %1 = subview %0[0, 8][62, 3][1, 1] :
1245    memref<64x4xf32, offset: 0, strides: [4, 1]>
1246    to memref<62x3xf32, offset: 8, strides: [4, 1]>
1247  return
1248}
1249
1250// CHECK-LABEL: func @subview_mixed_static_dynamic(
1251// CHECK-COUNT-2: !llvm.ptr<float>,
1252// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64,
1253// CHECK:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64,
1254// CHECK:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64,
1255// CHECK:         %[[ARG2:.*]]: !llvm.i64)
1256// CHECK32-LABEL: func @subview_mixed_static_dynamic(
1257// CHECK32-COUNT-2: !llvm.ptr<float>,
1258// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32,
1259// CHECK32:         %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32,
1260// CHECK32:         %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32,
1261// CHECK32:         %[[ARG2:.*]]: !llvm.i32)
1262func @subview_mixed_static_dynamic(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) {
1263  // The last "insertvalue" that populates the memref descriptor from the function arguments.
1264  // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1265  // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1]
1266
1267  // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1268  // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1269  // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1270  // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float>
1271  // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1272  // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1273  // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1274  // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1275  // CHECK32: %[[OFFM1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE0]] : !llvm.i32
1276  // CHECK32: %[[OFFA1:.*]] = llvm.add %[[OFF]], %[[OFFM1]] : !llvm.i32
1277  // CHECK32: %[[CST8:.*]] = llvm.mlir.constant(8 : i64) : !llvm.i32
1278  // CHECK32: %[[OFFM2:.*]] = llvm.mul %[[CST8]], %[[STRIDE1]] : !llvm.i32
1279  // CHECK32: %[[OFFA2:.*]] = llvm.add %[[OFFA1]], %[[OFFM2]] : !llvm.i32
1280  // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFFA2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1281
1282  // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1283  // CHECK32: %[[CST1:.*]] = llvm.mlir.constant(1 : i64) : !llvm.i32
1284  // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1285  // CHECK32: %[[CST62:.*]] = llvm.mlir.constant(62 : i64) : !llvm.i32
1286  // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST62]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1287  // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32
1288  // CHECK32: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)>
1289  %1 = subview %0[%arg1, 8][62, %arg2][%arg0, 1] :
1290    memref<64x4xf32, offset: 0, strides: [4, 1]>
1291    to memref<62x?xf32, offset: ?, strides: [?, 1]>
1292  return
1293}
1294
1295// -----
1296
1297// CHECK-LABEL: func @atomic_rmw
1298func @atomic_rmw(%I : memref<10xi32>, %ival : i32, %F : memref<10xf32>, %fval : f32, %i : index) {
1299  atomic_rmw "assign" %fval, %F[%i] : (f32, memref<10xf32>) -> f32
1300  // CHECK: llvm.atomicrmw xchg %{{.*}}, %{{.*}} acq_rel
1301  atomic_rmw "addi" %ival, %I[%i] : (i32, memref<10xi32>) -> i32
1302  // CHECK: llvm.atomicrmw add %{{.*}}, %{{.*}} acq_rel
1303  atomic_rmw "maxs" %ival, %I[%i] : (i32, memref<10xi32>) -> i32
1304  // CHECK: llvm.atomicrmw max %{{.*}}, %{{.*}} acq_rel
1305  atomic_rmw "mins" %ival, %I[%i] : (i32, memref<10xi32>) -> i32
1306  // CHECK: llvm.atomicrmw min %{{.*}}, %{{.*}} acq_rel
1307  atomic_rmw "maxu" %ival, %I[%i] : (i32, memref<10xi32>) -> i32
1308  // CHECK: llvm.atomicrmw umax %{{.*}}, %{{.*}} acq_rel
1309  atomic_rmw "minu" %ival, %I[%i] : (i32, memref<10xi32>) -> i32
1310  // CHECK: llvm.atomicrmw umin %{{.*}}, %{{.*}} acq_rel
1311  atomic_rmw "addf" %fval, %F[%i] : (f32, memref<10xf32>) -> f32
1312  // CHECK: llvm.atomicrmw fadd %{{.*}}, %{{.*}} acq_rel
1313  return
1314}
1315
1316// -----
1317
1318// CHECK-LABEL: func @generic_atomic_rmw
1319func @generic_atomic_rmw(%I : memref<10xi32>, %i : index) -> i32 {
1320  %x = generic_atomic_rmw %I[%i] : memref<10xi32> {
1321    ^bb0(%old_value : i32):
1322      %c1 = constant 1 : i32
1323      atomic_yield %c1 : i32
1324  }
1325  // CHECK: [[init:%.*]] = llvm.load %{{.*}} : !llvm.ptr<i32>
1326  // CHECK-NEXT: llvm.br ^bb1([[init]] : !llvm.i32)
1327  // CHECK-NEXT: ^bb1([[loaded:%.*]]: !llvm.i32):
1328  // CHECK-NEXT: [[c1:%.*]] = llvm.mlir.constant(1 : i32)
1329  // CHECK-NEXT: [[pair:%.*]] = llvm.cmpxchg %{{.*}}, [[loaded]], [[c1]]
1330  // CHECK-SAME:                    acq_rel monotonic : !llvm.i32
1331  // CHECK-NEXT: [[new:%.*]] = llvm.extractvalue [[pair]][0]
1332  // CHECK-NEXT: [[ok:%.*]] = llvm.extractvalue [[pair]][1]
1333  // CHECK-NEXT: llvm.cond_br [[ok]], ^bb2, ^bb1([[new]] : !llvm.i32)
1334  // CHECK-NEXT: ^bb2:
1335  %c2 = constant 2 : i32
1336  %add = addi %c2, %x : i32
1337  return %add : i32
1338  // CHECK-NEXT: [[c2:%.*]] = llvm.mlir.constant(2 : i32)
1339  // CHECK-NEXT: [[add:%.*]] = llvm.add [[c2]], [[new]] : !llvm.i32
1340  // CHECK-NEXT: llvm.return [[add]]
1341}
1342
1343// -----
1344
1345// CHECK-LABEL: func @assume_alignment
1346func @assume_alignment(%0 : memref<4x4xf16>) {
1347  // CHECK: %[[PTR:.*]] = llvm.extractvalue %[[MEMREF:.*]][1] : !llvm.struct<(ptr<half>, ptr<half>, i64, array<2 x i64>, array<2 x i64>)>
1348  // CHECK-NEXT: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
1349  // CHECK-NEXT: %[[MASK:.*]] = llvm.mlir.constant(15 : index) : !llvm.i64
1350  // CHECK-NEXT: %[[INT:.*]] = llvm.ptrtoint %[[PTR]] : !llvm.ptr<half> to !llvm.i64
1351  // CHECK-NEXT: %[[MASKED_PTR:.*]] = llvm.and %[[INT]], %[[MASK:.*]] : !llvm.i64
1352  // CHECK-NEXT: %[[CONDITION:.*]] = llvm.icmp "eq" %[[MASKED_PTR]], %[[ZERO]] : !llvm.i64
1353  // CHECK-NEXT: "llvm.intr.assume"(%[[CONDITION]]) : (!llvm.i1) -> ()
1354  assume_alignment %0, 16 : memref<4x4xf16>
1355  return
1356}
1357
1358// -----
1359
1360// CHECK-LABEL: func @mlir_cast_to_llvm
1361// CHECK-SAME: %[[ARG:.*]]:
1362func @mlir_cast_to_llvm(%0 : vector<2xf16>) -> !llvm.vec<2 x half> {
1363  %1 = llvm.mlir.cast %0 : vector<2xf16> to !llvm.vec<2 x half>
1364  // CHECK-NEXT: llvm.return %[[ARG]]
1365  return %1 : !llvm.vec<2 x half>
1366}
1367
1368// CHECK-LABEL: func @mlir_cast_from_llvm
1369// CHECK-SAME: %[[ARG:.*]]:
1370func @mlir_cast_from_llvm(%0 : !llvm.vec<2 x half>) -> vector<2xf16> {
1371  %1 = llvm.mlir.cast %0 : !llvm.vec<2 x half> to vector<2xf16>
1372  // CHECK-NEXT: llvm.return %[[ARG]]
1373  return %1 : vector<2xf16>
1374}
1375
1376// -----
1377
1378// CHECK-LABEL: func @mlir_cast_to_llvm
1379// CHECK-SAME: %[[ARG:.*]]:
1380func @mlir_cast_to_llvm(%0 : f16) -> !llvm.half {
1381  %1 = llvm.mlir.cast %0 : f16 to !llvm.half
1382  // CHECK-NEXT: llvm.return %[[ARG]]
1383  return %1 : !llvm.half
1384}
1385
1386// CHECK-LABEL: func @mlir_cast_from_llvm
1387// CHECK-SAME: %[[ARG:.*]]:
1388func @mlir_cast_from_llvm(%0 : !llvm.half) -> f16 {
1389  %1 = llvm.mlir.cast %0 : !llvm.half to f16
1390  // CHECK-NEXT: llvm.return %[[ARG]]
1391  return %1 : f16
1392}
1393
1394// -----
1395
1396// CHECK-LABEL: func @bfloat
1397// CHECK-SAME: !llvm.bfloat) -> !llvm.bfloat
1398func @bfloat(%arg0: bf16) -> bf16 {
1399  return %arg0 : bf16
1400}
1401// CHECK-NEXT: return %{{.*}} : !llvm.bfloat
1402
1403// -----
1404
1405// CHECK-LABEL: func @memref_index
1406// CHECK-SAME: %arg0: !llvm.ptr<i64>, %arg1: !llvm.ptr<i64>,
1407// CHECK-SAME: %arg2: !llvm.i64, %arg3: !llvm.i64, %arg4: !llvm.i64)
1408// CHECK-SAME: -> !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<1 x i64>, array<1 x i64>)>
1409// CHECK32-LABEL: func @memref_index
1410// CHECK32-SAME: %arg0: !llvm.ptr<i32>, %arg1: !llvm.ptr<i32>,
1411// CHECK32-SAME: %arg2: !llvm.i32, %arg3: !llvm.i32, %arg4: !llvm.i32)
1412// CHECK32-SAME: -> !llvm.struct<(ptr<i32>, ptr<i32>, i32, array<1 x i32>, array<1 x i32>)>
1413func @memref_index(%arg0: memref<32xindex>) -> memref<32xindex> {
1414  return %arg0 : memref<32xindex>
1415}
1416
1417// -----
1418
1419// CHECK-LABEL: func @rank_of_unranked
1420// CHECK32-LABEL: func @rank_of_unranked
1421func @rank_of_unranked(%unranked: memref<*xi32>) {
1422  %rank = rank %unranked : memref<*xi32>
1423  return
1424}
1425// CHECK-NEXT: llvm.mlir.undef
1426// CHECK-NEXT: llvm.insertvalue
1427// CHECK-NEXT: llvm.insertvalue
1428// CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i64, ptr<i8>)>
1429// CHECK32: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i32, ptr<i8>)>
1430
1431// CHECK-LABEL: func @rank_of_ranked
1432// CHECK32-LABEL: func @rank_of_ranked
1433func @rank_of_ranked(%ranked: memref<?xi32>) {
1434  %rank = rank %ranked : memref<?xi32>
1435  return
1436}
1437// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64
1438// CHECK32: llvm.mlir.constant(1 : index) : !llvm.i32
1439
1440// -----
1441
1442// CHECK-LABEL: func @dim_of_unranked
1443// CHECK32-LABEL: func @dim_of_unranked
1444func @dim_of_unranked(%unranked: memref<*xi32>) -> index {
1445  %c0 = constant 0 : index
1446  %dim = dim %unranked, %c0 : memref<*xi32>
1447  return %dim : index
1448}
1449// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(i64, ptr<i8>)>
1450// CHECK-NEXT: llvm.insertvalue
1451// CHECK-NEXT: %[[UNRANKED_DESC:.*]] = llvm.insertvalue
1452// CHECK-NEXT: %[[C0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
1453
1454// CHECK-NEXT: %[[RANKED_DESC:.*]] = llvm.extractvalue %[[UNRANKED_DESC]][1]
1455// CHECK-SAME:   : !llvm.struct<(i64, ptr<i8>)>
1456
1457// CHECK-NEXT: %[[ZERO_D_DESC:.*]] = llvm.bitcast %[[RANKED_DESC]]
1458// CHECK-SAME:   : !llvm.ptr<i8> to !llvm.ptr<struct<(ptr<i32>, ptr<i32>, i64)>>
1459
1460// CHECK-NEXT: %[[C2_i32:.*]] = llvm.mlir.constant(2 : i32) : !llvm.i32
1461// CHECK-NEXT: %[[C0_:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64
1462
1463// CHECK-NEXT: %[[OFFSET_PTR:.*]] = llvm.getelementptr %[[ZERO_D_DESC]]{{\[}}
1464// CHECK-SAME:   %[[C0_]], %[[C2_i32]]] : (!llvm.ptr<struct<(ptr<i32>, ptr<i32>,
1465// CHECK-SAME:   i64)>>, !llvm.i64, !llvm.i32) -> !llvm.ptr<i64>
1466
1467// CHECK-NEXT: %[[C1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64
1468// CHECK-NEXT: %[[INDEX_INC:.*]] = llvm.add %[[C1]], %[[C0]] : !llvm.i64
1469
1470// CHECK-NEXT: %[[SIZE_PTR:.*]] = llvm.getelementptr %[[OFFSET_PTR]]{{\[}}
1471// CHECK-SAME:   %[[INDEX_INC]]] : (!llvm.ptr<i64>, !llvm.i64) -> !llvm.ptr<i64>
1472
1473// CHECK-NEXT: %[[SIZE:.*]] = llvm.load %[[SIZE_PTR]] : !llvm.ptr<i64>
1474// CHECK-NEXT: llvm.return %[[SIZE]] : !llvm.i64
1475
1476// CHECK32: %[[SIZE:.*]] = llvm.load %{{.*}} : !llvm.ptr<i32>
1477// CHECK32-NEXT: llvm.return %[[SIZE]] : !llvm.i32
1478