1// RUN: mlir-opt %s -convert-vector-to-llvm -split-input-file | FileCheck %s
2
3
4func.func @bitcast_f32_to_i32_vector_0d(%input: vector<f32>) -> vector<i32> {
5  %0 = vector.bitcast %input : vector<f32> to vector<i32>
6  return %0 : vector<i32>
7}
8
9// CHECK-LABEL: @bitcast_f32_to_i32_vector_0d
10// CHECK-SAME:  %[[input:.*]]: vector<f32>
11// CHECK:       %[[vec_f32_1d:.*]] = builtin.unrealized_conversion_cast %[[input]] : vector<f32> to vector<1xf32>
12// CHECK:       %[[vec_i32_1d:.*]] = llvm.bitcast %[[vec_f32_1d]] : vector<1xf32> to vector<1xi32>
13// CHECK:       %[[vec_i32_0d:.*]] = builtin.unrealized_conversion_cast %[[vec_i32_1d]] : vector<1xi32> to vector<i32>
14// CHECK:       return %[[vec_i32_0d]] : vector<i32>
15
16// -----
17
18func.func @bitcast_f32_to_i32_vector(%input: vector<16xf32>) -> vector<16xi32> {
19  %0 = vector.bitcast %input : vector<16xf32> to vector<16xi32>
20  return %0 : vector<16xi32>
21}
22
23// CHECK-LABEL: @bitcast_f32_to_i32_vector
24// CHECK-SAME:  %[[input:.*]]: vector<16xf32>
25// CHECK:       llvm.bitcast %[[input]] : vector<16xf32> to vector<16xi32>
26
27// -----
28
29func.func @bitcast_i8_to_f32_vector(%input: vector<64xi8>) -> vector<16xf32> {
30  %0 = vector.bitcast %input : vector<64xi8> to vector<16xf32>
31  return %0 : vector<16xf32>
32}
33
34// CHECK-LABEL: @bitcast_i8_to_f32_vector
35// CHECK-SAME:  %[[input:.*]]: vector<64xi8>
36// CHECK:       llvm.bitcast %[[input]] : vector<64xi8> to vector<16xf32>
37
38// -----
39
40func.func @bitcast_index_to_i8_vector(%input: vector<16xindex>) -> vector<128xi8> {
41  %0 = vector.bitcast %input : vector<16xindex> to vector<128xi8>
42  return %0 : vector<128xi8>
43}
44
45// CHECK-LABEL: @bitcast_index_to_i8_vector
46// CHECK-SAME:  %[[input:.*]]: vector<16xindex>
47// CHECK:       %[[T0:.*]] = builtin.unrealized_conversion_cast %[[input]] : vector<16xindex> to vector<16xi64>
48// CHECK:       llvm.bitcast %[[T0]] : vector<16xi64> to vector<128xi8>
49
50// -----
51
52func.func @broadcast_vec0d_from_f32(%arg0: f32) -> vector<f32> {
53  %0 = vector.broadcast %arg0 : f32 to vector<f32>
54  return %0 : vector<f32>
55}
56// CHECK-LABEL: @broadcast_vec0d_from_f32
57// CHECK-SAME:  %[[A:.*]]: f32)
58// CHECK:       %[[T0:.*]] = llvm.insertelement %[[A]]
59// CHECK:       %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<1xf32> to vector<f32>
60// CHECK:       return %[[T1]] : vector<f32>
61
62// -----
63
64func.func @broadcast_vec0d_from_vec0d(%arg0: vector<f32>) -> vector<f32> {
65  %0 = vector.broadcast %arg0 : vector<f32> to vector<f32>
66  return %0 : vector<f32>
67}
68// CHECK-LABEL: @broadcast_vec0d_from_vec0d(
69// CHECK-SAME:  %[[A:.*]]: vector<f32>)
70// CHECK:       return %[[A]] : vector<f32>
71
72// -----
73
74func.func @broadcast_vec1d_from_f32(%arg0: f32) -> vector<2xf32> {
75  %0 = vector.broadcast %arg0 : f32 to vector<2xf32>
76  return %0 : vector<2xf32>
77}
78// CHECK-LABEL: @broadcast_vec1d_from_f32
79// CHECK-SAME:  %[[A:.*]]: f32)
80// CHECK:       %[[T0:.*]] = llvm.insertelement %[[A]]
81// CHECK:       %[[T1:.*]] = llvm.shufflevector %[[T0]]
82// CHECK:       return %[[T1]] : vector<2xf32>
83
84// -----
85
86func.func @broadcast_vec1d_from_index(%arg0: index) -> vector<2xindex> {
87  %0 = vector.broadcast %arg0 : index to vector<2xindex>
88  return %0 : vector<2xindex>
89}
90// CHECK-LABEL: @broadcast_vec1d_from_index
91// CHECK-SAME:  %[[A:.*]]: index)
92// CHECK:       %[[A1:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64
93// CHECK:       %[[T0:.*]] = llvm.insertelement %[[A1]]
94// CHECK:       %[[T1:.*]] = llvm.shufflevector %[[T0]]
95// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<2xi64> to vector<2xindex>
96// CHECK:       return %[[T2]] : vector<2xindex>
97
98// -----
99
100func.func @broadcast_vec2d_from_scalar(%arg0: f32) -> vector<2x3xf32> {
101  %0 = vector.broadcast %arg0 : f32 to vector<2x3xf32>
102  return %0 : vector<2x3xf32>
103}
104// CHECK-LABEL: @broadcast_vec2d_from_scalar(
105// CHECK-SAME:  %[[A:.*]]: f32)
106// CHECK:       %[[T0:.*]] = llvm.insertelement %[[A]]
107// CHECK:       %[[T1:.*]] = llvm.shufflevector %[[T0]]
108// CHECK:       %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0] : !llvm.array<2 x vector<3xf32>>
109// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1] : !llvm.array<2 x vector<3xf32>>
110// CHECK:       %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>
111// CHECK:       return %[[T4]] : vector<2x3xf32>
112
113// -----
114
115func.func @broadcast_vec3d_from_scalar(%arg0: f32) -> vector<2x3x4xf32> {
116  %0 = vector.broadcast %arg0 : f32 to vector<2x3x4xf32>
117  return %0 : vector<2x3x4xf32>
118}
119// CHECK-LABEL: @broadcast_vec3d_from_scalar(
120// CHECK-SAME:  %[[A:.*]]: f32)
121// CHECK:       %[[T0:.*]] = llvm.insertelement %[[A]]
122// CHECK:       %[[T1:.*]] = llvm.shufflevector %[[T0]]
123// CHECK:       %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0, 0] : !llvm.array<2 x array<3 x vector<4xf32>>>
124// ...
125// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1, 2] : !llvm.array<2 x array<3 x vector<4xf32>>>
126// CHECK:       %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x array<3 x vector<4xf32>>> to vector<2x3x4xf32>
127// CHECK:       return %[[T4]] : vector<2x3x4xf32>
128
129// -----
130
131func.func @broadcast_vec1d_from_vec1d(%arg0: vector<2xf32>) -> vector<2xf32> {
132  %0 = vector.broadcast %arg0 : vector<2xf32> to vector<2xf32>
133  return %0 : vector<2xf32>
134}
135// CHECK-LABEL: @broadcast_vec1d_from_vec1d(
136// CHECK-SAME:  %[[A:.*]]: vector<2xf32>)
137// CHECK:       return %[[A]] : vector<2xf32>
138
139// -----
140
141func.func @broadcast_vec2d_from_vec0d(%arg0: vector<f32>) -> vector<3x2xf32> {
142  %0 = vector.broadcast %arg0 : vector<f32> to vector<3x2xf32>
143  return %0 : vector<3x2xf32>
144}
145// CHECK-LABEL: @broadcast_vec2d_from_vec0d(
146// CHECK-SAME:  %[[A:.*]]: vector<f32>)
147//       CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32>
148//       CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32>
149//       CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>
150//       CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : index) : i64
151//       CHECK: %[[T5:.*]] = llvm.extractelement %[[T0]][%[[T4]] : i64] : vector<1xf32>
152//       CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]]
153//       CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]
154//       CHECK: %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>>
155//       CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][1] : !llvm.array<3 x vector<2xf32>>
156//       CHECK: %[[T9:.*]] = llvm.insertvalue %[[T6]], %[[T8]][2] : !llvm.array<3 x vector<2xf32>>
157//       CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32>
158//       CHECK: return %[[T10]] : vector<3x2xf32>
159
160// -----
161
162func.func @broadcast_vec2d_from_vec1d(%arg0: vector<2xf32>) -> vector<3x2xf32> {
163  %0 = vector.broadcast %arg0 : vector<2xf32> to vector<3x2xf32>
164  return %0 : vector<3x2xf32>
165}
166// CHECK-LABEL: @broadcast_vec2d_from_vec1d(
167// CHECK-SAME:  %[[A:.*]]: vector<2xf32>)
168// CHECK:       %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32>
169// CHECK:       %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>
170// CHECK:       %[[T2:.*]] = llvm.insertvalue %[[A]], %[[T1]][0] : !llvm.array<3 x vector<2xf32>>
171// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][1] : !llvm.array<3 x vector<2xf32>>
172// CHECK:       %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][2] : !llvm.array<3 x vector<2xf32>>
173// CHECK:       %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32>
174// CHECK:       return %[[T5]] : vector<3x2xf32>
175
176// -----
177
178func.func @broadcast_vec2d_from_index_vec1d(%arg0: vector<2xindex>) -> vector<3x2xindex> {
179  %0 = vector.broadcast %arg0 : vector<2xindex> to vector<3x2xindex>
180  return %0 : vector<3x2xindex>
181}
182// CHECK-LABEL: @broadcast_vec2d_from_index_vec1d(
183// CHECK-SAME:  %[[A:.*]]: vector<2xindex>)
184// CHECK:       %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64>
185// CHECK:       %[[T0:.*]] = arith.constant dense<0> : vector<3x2xindex>
186// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xindex> to !llvm.array<3 x vector<2xi64>>
187// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<3 x vector<2xi64>>
188
189// CHECK:       %[[T4:.*]] = builtin.unrealized_conversion_cast %{{.*}} : !llvm.array<3 x vector<2xi64>> to vector<3x2xindex>
190// CHECK:       return %[[T4]] : vector<3x2xindex>
191
192// -----
193
194func.func @broadcast_vec3d_from_vec1d(%arg0: vector<2xf32>) -> vector<4x3x2xf32> {
195  %0 = vector.broadcast %arg0 : vector<2xf32> to vector<4x3x2xf32>
196  return %0 : vector<4x3x2xf32>
197}
198// CHECK-LABEL: @broadcast_vec3d_from_vec1d(
199// CHECK-SAME:  %[[A:.*]]: vector<2xf32>)
200// CHECK:       %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32>
201// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>
202// CHECK:       %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32>
203// CHECK:       %[[T6:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>
204
205// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>>
206// CHECK:       %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][1] : !llvm.array<3 x vector<2xf32>>
207// CHECK:       %[[T5:.*]] = llvm.insertvalue %[[A]], %[[T4]][2] : !llvm.array<3 x vector<2xf32>>
208
209// CHECK:       %[[T7:.*]] = llvm.insertvalue %[[T5]], %[[T6]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>
210// CHECK:       %[[T8:.*]] = llvm.insertvalue %[[T5]], %[[T7]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>
211// CHECK:       %[[T9:.*]] = llvm.insertvalue %[[T5]], %[[T8]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>
212// CHECK:       %[[T10:.*]] = llvm.insertvalue %[[T5]], %[[T9]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>
213
214// CHECK:       %[[T11:.*]] = builtin.unrealized_conversion_cast %[[T10]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>
215// CHECK:       return %[[T11]] : vector<4x3x2xf32>
216
217// -----
218
219func.func @broadcast_vec3d_from_vec2d(%arg0: vector<3x2xf32>) -> vector<4x3x2xf32> {
220  %0 = vector.broadcast %arg0 : vector<3x2xf32> to vector<4x3x2xf32>
221  return %0 : vector<4x3x2xf32>
222}
223// CHECK-LABEL: @broadcast_vec3d_from_vec2d(
224// CHECK-SAME:  %[[A:.*]]: vector<3x2xf32>)
225// CHECK:       %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>
226// CHECK:       %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32>
227// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>
228// CHECK:       %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>
229// CHECK:       %[[T5:.*]] = llvm.insertvalue %[[T1]], %[[T3]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>
230// CHECK:       %[[T7:.*]] = llvm.insertvalue %[[T1]], %[[T5]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>
231// CHECK:       %[[T9:.*]] = llvm.insertvalue %[[T1]], %[[T7]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>
232// CHECK:       %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>
233// CHECK:       return %[[T10]] : vector<4x3x2xf32>
234
235
236// -----
237
238func.func @broadcast_stretch(%arg0: vector<1xf32>) -> vector<4xf32> {
239  %0 = vector.broadcast %arg0 : vector<1xf32> to vector<4xf32>
240  return %0 : vector<4xf32>
241}
242// CHECK-LABEL: @broadcast_stretch(
243// CHECK-SAME:  %[[A:.*]]: vector<1xf32>)
244// CHECK:       %[[T1:.*]] = llvm.mlir.constant(0 : i64) : i64
245// CHECK:       %[[T2:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T1]] : i64] : vector<1xf32>
246// CHECK:       %[[T3:.*]] = llvm.insertelement %[[T2]]
247// CHECK:       %[[T4:.*]] = llvm.shufflevector %[[T3]]
248// CHECK:       return %[[T4]] : vector<4xf32>
249
250// -----
251
252func.func @broadcast_stretch_at_start(%arg0: vector<1x4xf32>) -> vector<3x4xf32> {
253  %0 = vector.broadcast %arg0 : vector<1x4xf32> to vector<3x4xf32>
254  return %0 : vector<3x4xf32>
255}
256// CHECK-LABEL: @broadcast_stretch_at_start(
257// CHECK-SAME:  %[[A:.*]]: vector<1x4xf32>)
258// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>>
259// CHECK:       %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<3x4xf32>
260// CHECK:       %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x4xf32> to !llvm.array<3 x vector<4xf32>>
261// CHECK:       %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<1 x vector<4xf32>>
262// CHECK:       %[[T5:.*]] = llvm.insertvalue %[[T3]], %[[T4]][0] : !llvm.array<3 x vector<4xf32>>
263// CHECK:       %[[T6:.*]] = llvm.insertvalue %[[T3]], %[[T5]][1] : !llvm.array<3 x vector<4xf32>>
264// CHECK:       %[[T7:.*]] = llvm.insertvalue %[[T3]], %[[T6]][2] : !llvm.array<3 x vector<4xf32>>
265// CHECK:       %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32>
266// CHECK:       return %[[T8]] : vector<3x4xf32>
267
268// -----
269
270func.func @broadcast_stretch_at_end(%arg0: vector<4x1xf32>) -> vector<4x3xf32> {
271  %0 = vector.broadcast %arg0 : vector<4x1xf32> to vector<4x3xf32>
272  return %0 : vector<4x3xf32>
273}
274// CHECK-LABEL: @broadcast_stretch_at_end(
275// CHECK-SAME:  %[[A:.*]]: vector<4x1xf32>)
276// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1xf32> to !llvm.array<4 x vector<1xf32>>
277// CHECK:       %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3xf32>
278// CHECK:       %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3xf32> to !llvm.array<4 x vector<3xf32>>
279// CHECK:       %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<4 x vector<1xf32>>
280// CHECK:       %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64
281// CHECK:       %[[T5:.*]] = llvm.extractelement %[[T3]]{{\[}}%[[T4]] : i64] : vector<1xf32>
282// CHECK:       %[[T6Insert:.*]] = llvm.insertelement %[[T5]]
283// CHECK:       %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]
284// CHECK:       %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<4 x vector<3xf32>>
285// CHECK:       %[[T10:.*]] = llvm.extractvalue %[[T2]][1] : !llvm.array<4 x vector<1xf32>>
286// CHECK:       %[[T11:.*]] = llvm.mlir.constant(0 : i64) : i64
287// CHECK:       %[[T12:.*]] = llvm.extractelement %[[T10]]{{\[}}%[[T11]] : i64] : vector<1xf32>
288// CHECK:       %[[T13Insert:.*]] = llvm.insertelement %[[T12]]
289// CHECK:       %[[T13:.*]] = llvm.shufflevector %[[T13Insert]]
290// CHECK:       %[[T14:.*]] = llvm.insertvalue %[[T13]], %[[T8]][1] : !llvm.array<4 x vector<3xf32>>
291// CHECK:       %[[T16:.*]] = llvm.extractvalue %[[T2]][2] : !llvm.array<4 x vector<1xf32>>
292// CHECK:       %[[T17:.*]] = llvm.mlir.constant(0 : i64) : i64
293// CHECK:       %[[T18:.*]] = llvm.extractelement %[[T16]]{{\[}}%[[T17]] : i64] : vector<1xf32>
294// CHECK:       %[[T19Insert:.*]] = llvm.insertelement %[[T18]]
295// CHECK:       %[[T19:.*]] = llvm.shufflevector %[[T19Insert]]
296// CHECK:       %[[T20:.*]] = llvm.insertvalue %[[T19]], %[[T14]][2] : !llvm.array<4 x vector<3xf32>>
297// CHECK:       %[[T22:.*]] = llvm.extractvalue %[[T2]][3] : !llvm.array<4 x vector<1xf32>>
298// CHECK:       %[[T23:.*]] = llvm.mlir.constant(0 : i64) : i64
299// CHECK:       %[[T24:.*]] = llvm.extractelement %[[T22]]{{\[}}%[[T23]] : i64] : vector<1xf32>
300// CHECK:       %[[T25Insert:.*]] = llvm.insertelement %[[T24]]
301// CHECK:       %[[T25:.*]] = llvm.shufflevector %[[T25Insert]]
302// CHECK:       %[[T26:.*]] = llvm.insertvalue %[[T25]], %[[T20]][3] : !llvm.array<4 x vector<3xf32>>
303// CHECK:       %[[T27:.*]] = builtin.unrealized_conversion_cast %[[T26]] : !llvm.array<4 x vector<3xf32>> to vector<4x3xf32>
304// CHECK:       return %[[T27]] : vector<4x3xf32>
305
306// -----
307
308func.func @broadcast_stretch_in_middle(%arg0: vector<4x1x2xf32>) -> vector<4x3x2xf32> {
309  %0 = vector.broadcast %arg0 : vector<4x1x2xf32> to vector<4x3x2xf32>
310  return %0 : vector<4x3x2xf32>
311}
312// CHECK-LABEL: @broadcast_stretch_in_middle(
313// CHECK-SAME:  %[[A:.*]]: vector<4x1x2xf32>) -> vector<4x3x2xf32> {
314// CHECK:       %[[T3:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1x2xf32> to !llvm.array<4 x array<1 x vector<2xf32>>>
315// CHECK:       %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32>
316// CHECK:       %[[T9:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>>
317// CHECK:       %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32>
318// CHECK:       %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>>
319// CHECK:       %[[T4:.*]] = llvm.extractvalue %[[T3]][0, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>
320// CHECK:       %[[T6:.*]] = llvm.insertvalue %[[T4]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>
321// CHECK:       %[[T7:.*]] = llvm.insertvalue %[[T4]], %[[T6]][1] : !llvm.array<3 x vector<2xf32>>
322// CHECK:       %[[T8:.*]] = llvm.insertvalue %[[T4]], %[[T7]][2] : !llvm.array<3 x vector<2xf32>>
323// CHECK:       %[[T10:.*]] = llvm.insertvalue %[[T8]], %[[T9]][0] : !llvm.array<4 x array<3 x vector<2xf32>>>
324// CHECK:       %[[T12:.*]] = llvm.extractvalue %[[T3]][1, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>
325// CHECK:       %[[T14:.*]] = llvm.insertvalue %[[T12]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>
326// CHECK:       %[[T15:.*]] = llvm.insertvalue %[[T12]], %[[T14]][1] : !llvm.array<3 x vector<2xf32>>
327// CHECK:       %[[T16:.*]] = llvm.insertvalue %[[T12]], %[[T15]][2] : !llvm.array<3 x vector<2xf32>>
328// CHECK:       %[[T17:.*]] = llvm.insertvalue %[[T16]], %[[T10]][1] : !llvm.array<4 x array<3 x vector<2xf32>>>
329// CHECK:       %[[T19:.*]] = llvm.extractvalue %[[T3]][2, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>
330// CHECK:       %[[T21:.*]] = llvm.insertvalue %[[T19]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>
331// CHECK:       %[[T22:.*]] = llvm.insertvalue %[[T19]], %[[T21]][1] : !llvm.array<3 x vector<2xf32>>
332// CHECK:       %[[T23:.*]] = llvm.insertvalue %[[T19]], %[[T22]][2] : !llvm.array<3 x vector<2xf32>>
333// CHECK:       %[[T24:.*]] = llvm.insertvalue %[[T23]], %[[T17]][2] : !llvm.array<4 x array<3 x vector<2xf32>>>
334// CHECK:       %[[T26:.*]] = llvm.extractvalue %[[T3]][3, 0] : !llvm.array<4 x array<1 x vector<2xf32>>>
335// CHECK:       %[[T28:.*]] = llvm.insertvalue %[[T26]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>>
336// CHECK:       %[[T29:.*]] = llvm.insertvalue %[[T26]], %[[T28]][1] : !llvm.array<3 x vector<2xf32>>
337// CHECK:       %[[T30:.*]] = llvm.insertvalue %[[T26]], %[[T29]][2] : !llvm.array<3 x vector<2xf32>>
338// CHECK:       %[[T31:.*]] = llvm.insertvalue %[[T30]], %[[T24]][3] : !llvm.array<4 x array<3 x vector<2xf32>>>
339// CHECK:       %[[T32:.*]] = builtin.unrealized_conversion_cast %[[T31]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32>
340// CHECK:       return %[[T32]] : vector<4x3x2xf32>
341
342// -----
343
344func.func @outerproduct(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<2x3xf32> {
345  %2 = vector.outerproduct %arg0, %arg1 : vector<2xf32>, vector<3xf32>
346  return %2 : vector<2x3xf32>
347}
348// CHECK-LABEL: @outerproduct(
349// CHECK-SAME:  %[[A:.*]]: vector<2xf32>,
350// CHECK-SAME:  %[[B:.*]]: vector<3xf32>)
351// CHECK:       %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32>
352// CHECK:       %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>
353// CHECK:       %[[T3:.*]] = llvm.mlir.constant(0 : i64) : i64
354// CHECK:       %[[T4:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T3]] : i64] : vector<2xf32>
355// CHECK:       %[[T5Insert:.*]] = llvm.insertelement %[[T4]]
356// CHECK:       %[[T5:.*]] = llvm.shufflevector %[[T5Insert]]
357// CHECK:       %[[T6:.*]] = arith.mulf %[[T5]], %[[B]] : vector<3xf32>
358// CHECK:       %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<2 x vector<3xf32>>
359// CHECK:       %[[T9:.*]] = llvm.mlir.constant(1 : i64) : i64
360// CHECK:       %[[T10:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T9]] : i64] : vector<2xf32>
361// CHECK:       %[[T11Insert:.*]] = llvm.insertelement %[[T10]]
362// CHECK:       %[[T11:.*]] = llvm.shufflevector %[[T11Insert]]
363// CHECK:       %[[T12:.*]] = arith.mulf %[[T11]], %[[B]] : vector<3xf32>
364// CHECK:       %[[T13:.*]] = llvm.insertvalue %[[T12]], %[[T8]][1] : !llvm.array<2 x vector<3xf32>>
365// CHECK:       %[[T14:.*]] = builtin.unrealized_conversion_cast %[[T13]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>
366// CHECK:       return %[[T14]] : vector<2x3xf32>
367
368// -----
369
370func.func @outerproduct_index(%arg0: vector<2xindex>, %arg1: vector<3xindex>) -> vector<2x3xindex> {
371  %2 = vector.outerproduct %arg0, %arg1 : vector<2xindex>, vector<3xindex>
372  return %2 : vector<2x3xindex>
373}
374// CHECK-LABEL: @outerproduct_index(
375// CHECK-SAME:  %[[A:.*]]: vector<2xindex>,
376// CHECK-SAME:  %[[B:.*]]: vector<3xindex>)
377// CHECK:       %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64>
378// CHECK:       %[[T0:.*]] = arith.constant dense<0> : vector<2x3xindex>
379// CHECK:       %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<2x3xindex> to !llvm.array<2 x vector<3xi64>>
380// CHECK:       %[[T2:.*]] = llvm.mlir.constant(0 : i64) : i64
381// CHECK:       %[[T3:.*]] = llvm.extractelement %[[T1]]{{\[}}%[[T2]] : i64] : vector<2xi64>
382// CHECK:       %[[T4:.*]] = llvm.insertelement %[[T3]]
383// CHECK:       %[[T5:.*]] = llvm.shufflevector %[[T4]]
384// CHECK:       %[[T5Cast:.*]] = builtin.unrealized_conversion_cast %[[T5]] : vector<3xi64> to vector<3xindex>
385// CHECK:       %[[T6:.*]] = arith.muli %[[T5Cast]], %[[B]] : vector<3xindex>
386// CHECK:       %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T6]] : vector<3xindex> to vector<3xi64>
387// CHECK:       %{{.*}} = llvm.insertvalue %[[T7]], %[[T8]][0] : !llvm.array<2 x vector<3xi64>>
388
389// -----
390
391func.func @outerproduct_add(%arg0: vector<2xf32>, %arg1: vector<3xf32>, %arg2: vector<2x3xf32>) -> vector<2x3xf32> {
392  %2 = vector.outerproduct %arg0, %arg1, %arg2 : vector<2xf32>, vector<3xf32>
393  return %2 : vector<2x3xf32>
394}
395// CHECK-LABEL: @outerproduct_add(
396// CHECK-SAME:  %[[A:.*]]: vector<2xf32>,
397// CHECK-SAME:  %[[B:.*]]: vector<3xf32>,
398// CHECK-SAME:  %[[C:.*]]: vector<2x3xf32>) -> vector<2x3xf32>
399// CHECK:       %[[T7:.*]] = builtin.unrealized_conversion_cast %[[C]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>
400// CHECK:       %[[T3:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32>
401// CHECK:       %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T3]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>>
402// CHECK:       %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64
403// CHECK:       %[[T5:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T4]] : i64] : vector<2xf32>
404// CHECK:       %[[T6Insert:.*]] = llvm.insertelement %[[T5]]
405// CHECK:       %[[T6:.*]] = llvm.shufflevector %[[T6Insert]]
406// CHECK:       %[[T8:.*]] = llvm.extractvalue %[[T7]][0] : !llvm.array<2 x vector<3xf32>>
407// CHECK:       %[[T9:.*]] = "llvm.intr.fmuladd"(%[[T6]], %[[B]], %[[T8]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32>
408// CHECK:       %[[T11:.*]] = llvm.insertvalue %[[T9]], %[[T10]][0] : !llvm.array<2 x vector<3xf32>>
409// CHECK:       %[[T12:.*]] = llvm.mlir.constant(1 : i64) : i64
410// CHECK:       %[[T13:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T12]] : i64] : vector<2xf32>
411// CHECK:       %[[T14Insert:.*]] = llvm.insertelement %[[T13]]
412// CHECK:       %[[T14:.*]] = llvm.shufflevector %[[T14Insert]]
413// CHECK:       %[[T16:.*]] = llvm.extractvalue %[[T7]][1] : !llvm.array<2 x vector<3xf32>>
414// CHECK:       %[[T17:.*]] = "llvm.intr.fmuladd"(%[[T14]], %[[B]], %[[T16]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32>
415// CHECK:       %[[T18:.*]] = llvm.insertvalue %[[T17]], %[[T11]][1] : !llvm.array<2 x vector<3xf32>>
416// CHECK:       %[[T19:.*]] = builtin.unrealized_conversion_cast %[[T18]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32>
417// CHECK:       return %[[T19]] : vector<2x3xf32>
418
419// -----
420
421func.func @shuffle_1D_direct(%arg0: vector<2xf32>, %arg1: vector<2xf32>) -> vector<2xf32> {
422  %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xf32>, vector<2xf32>
423  return %1 : vector<2xf32>
424}
425// CHECK-LABEL: @shuffle_1D_direct(
426// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
427// CHECK-SAME: %[[B:.*]]: vector<2xf32>)
428//       CHECK:   return %[[A:.*]]: vector<2xf32>
429
430// -----
431
432func.func @shuffle_1D_index_direct(%arg0: vector<2xindex>, %arg1: vector<2xindex>) -> vector<2xindex> {
433  %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xindex>, vector<2xindex>
434  return %1 : vector<2xindex>
435}
436// CHECK-LABEL: @shuffle_1D_index_direct(
437// CHECK-SAME: %[[A:.*]]: vector<2xindex>,
438// CHECK-SAME: %[[B:.*]]: vector<2xindex>)
439//       CHECK:   return  %[[A:.*]]: vector<2xindex>
440
441// -----
442
443func.func @shuffle_1D(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<5xf32> {
444  %1 = vector.shuffle %arg0, %arg1 [4, 3, 2, 1, 0] : vector<2xf32>, vector<3xf32>
445  return %1 : vector<5xf32>
446}
447// CHECK-LABEL: @shuffle_1D(
448// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
449// CHECK-SAME: %[[B:.*]]: vector<3xf32>)
450//       CHECK:   %[[u0:.*]] = llvm.mlir.undef : vector<5xf32>
451//       CHECK:   %[[c2:.*]] = llvm.mlir.constant(2 : index) : i64
452//       CHECK:   %[[e1:.*]] = llvm.extractelement %[[B]][%[[c2]] : i64] : vector<3xf32>
453//       CHECK:   %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64
454//       CHECK:   %[[i1:.*]] = llvm.insertelement %[[e1]], %[[u0]][%[[c0]] : i64] : vector<5xf32>
455//       CHECK:   %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64
456//       CHECK:   %[[e2:.*]] = llvm.extractelement %[[B]][%[[c1]] : i64] : vector<3xf32>
457//       CHECK:   %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64
458//       CHECK:   %[[i2:.*]] = llvm.insertelement %[[e2]], %[[i1]][%[[c1]] : i64] : vector<5xf32>
459//       CHECK:   %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64
460//       CHECK:   %[[e3:.*]] = llvm.extractelement %[[B]][%[[c0]] : i64] : vector<3xf32>
461//       CHECK:   %[[c2:.*]] = llvm.mlir.constant(2 : index) : i64
462//       CHECK:   %[[i3:.*]] = llvm.insertelement %[[e3]], %[[i2]][%[[c2]] : i64] : vector<5xf32>
463//       CHECK:   %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64
464//       CHECK:   %[[e4:.*]] = llvm.extractelement %[[A]][%[[c1]] : i64] : vector<2xf32>
465//       CHECK:   %[[c3:.*]] = llvm.mlir.constant(3 : index) : i64
466//       CHECK:   %[[i4:.*]] = llvm.insertelement %[[e4]], %[[i3]][%[[c3]] : i64] : vector<5xf32>
467//       CHECK:   %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64
468//       CHECK:   %[[e5:.*]] = llvm.extractelement %[[A]][%[[c0]] : i64] : vector<2xf32>
469//       CHECK:   %[[c4:.*]] = llvm.mlir.constant(4 : index) : i64
470//       CHECK:   %[[i5:.*]] = llvm.insertelement %[[e5]], %[[i4]][%[[c4]] : i64] : vector<5xf32>
471//       CHECK:   return %[[i5]] : vector<5xf32>
472
473// -----
474
475func.func @shuffle_2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> {
476  %1 = vector.shuffle %a, %b[1, 0, 2] : vector<1x4xf32>, vector<2x4xf32>
477  return %1 : vector<3x4xf32>
478}
479// CHECK-LABEL: @shuffle_2D(
480// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>,
481// CHECK-SAME: %[[B:.*]]: vector<2x4xf32>)
482//       CHECK-DAG:   %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>>
483//       CHECK-DAG:   %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>>
484//       CHECK:   %[[u0:.*]] = llvm.mlir.undef : !llvm.array<3 x vector<4xf32>>
485//       CHECK:   %[[e1:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<4xf32>>
486//       CHECK:   %[[i1:.*]] = llvm.insertvalue %[[e1]], %[[u0]][0] : !llvm.array<3 x vector<4xf32>>
487//       CHECK:   %[[e2:.*]] = llvm.extractvalue %[[VAL_0]][0] : !llvm.array<1 x vector<4xf32>>
488//       CHECK:   %[[i2:.*]] = llvm.insertvalue %[[e2]], %[[i1]][1] : !llvm.array<3 x vector<4xf32>>
489//       CHECK:   %[[e3:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<4xf32>>
490//       CHECK:   %[[i3:.*]] = llvm.insertvalue %[[e3]], %[[i2]][2] : !llvm.array<3 x vector<4xf32>>
491//       CHECK:   %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[i3]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32>
492//       CHECK:   return %[[VAL_3]] : vector<3x4xf32>
493
494// -----
495
496// CHECK-LABEL: @extract_element_0d
497func.func @extract_element_0d(%a: vector<f32>) -> f32 {
498  // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
499  // CHECK: llvm.extractelement %{{.*}}[%[[C0]] : {{.*}}] : vector<1xf32>
500  %1 = vector.extractelement %a[] : vector<f32>
501  return %1 : f32
502}
503
504// -----
505
506func.func @extract_element(%arg0: vector<16xf32>) -> f32 {
507  %0 = arith.constant 15 : i32
508  %1 = vector.extractelement %arg0[%0 : i32]: vector<16xf32>
509  return %1 : f32
510}
511// CHECK-LABEL: @extract_element(
512// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
513//       CHECK:   %[[c:.*]] = arith.constant 15 : i32
514//       CHECK:   %[[x:.*]] = llvm.extractelement %[[A]][%[[c]] : i32] : vector<16xf32>
515//       CHECK:   return %[[x]] : f32
516
517// -----
518
519func.func @extract_element_index(%arg0: vector<16xf32>) -> f32 {
520  %0 = arith.constant 15 : index
521  %1 = vector.extractelement %arg0[%0 : index]: vector<16xf32>
522  return %1 : f32
523}
524// CHECK-LABEL: @extract_element_index(
525// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
526//       CHECK:   %[[c:.*]] = arith.constant 15 : index
527//       CHECK:   %[[i:.*]] = builtin.unrealized_conversion_cast %[[c]] : index to i64
528//       CHECK:   %[[x:.*]] = llvm.extractelement %[[A]][%[[i]] : i64] : vector<16xf32>
529//       CHECK:   return %[[x]] : f32
530
531// -----
532
533func.func @extract_element_from_vec_1d(%arg0: vector<16xf32>) -> f32 {
534  %0 = vector.extract %arg0[15]: vector<16xf32>
535  return %0 : f32
536}
537// CHECK-LABEL: @extract_element_from_vec_1d
538//       CHECK:   llvm.mlir.constant(15 : i64) : i64
539//       CHECK:   llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32>
540//       CHECK:   return {{.*}} : f32
541
542// -----
543
544func.func @extract_index_element_from_vec_1d(%arg0: vector<16xindex>) -> index {
545  %0 = vector.extract %arg0[15]: vector<16xindex>
546  return %0 : index
547}
548// CHECK-LABEL: @extract_index_element_from_vec_1d(
549// CHECK-SAME: %[[A:.*]]: vector<16xindex>)
550//       CHECK:   %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64>
551//       CHECK:   %[[T1:.*]] = llvm.mlir.constant(15 : i64) : i64
552//       CHECK:   %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<16xi64>
553//       CHECK:   %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : i64 to index
554//       CHECK:   return %[[T3]] : index
555
556// -----
557
558func.func @extract_vec_2d_from_vec_3d(%arg0: vector<4x3x16xf32>) -> vector<3x16xf32> {
559  %0 = vector.extract %arg0[0]: vector<4x3x16xf32>
560  return %0 : vector<3x16xf32>
561}
562// CHECK-LABEL: @extract_vec_2d_from_vec_3d
563//       CHECK:   llvm.extractvalue {{.*}}[0] : !llvm.array<4 x array<3 x vector<16xf32>>>
564//       CHECK:   return {{.*}} : vector<3x16xf32>
565
566// -----
567
568func.func @extract_vec_1d_from_vec_3d(%arg0: vector<4x3x16xf32>) -> vector<16xf32> {
569  %0 = vector.extract %arg0[0, 0]: vector<4x3x16xf32>
570  return %0 : vector<16xf32>
571}
572// CHECK-LABEL: @extract_vec_1d_from_vec_3d
573//       CHECK:   llvm.extractvalue {{.*}}[0, 0] : !llvm.array<4 x array<3 x vector<16xf32>>>
574//       CHECK:   return {{.*}} : vector<16xf32>
575
576// -----
577
578func.func @extract_element_from_vec_3d(%arg0: vector<4x3x16xf32>) -> f32 {
579  %0 = vector.extract %arg0[0, 0, 0]: vector<4x3x16xf32>
580  return %0 : f32
581}
582// CHECK-LABEL: @extract_element_from_vec_3d
583//       CHECK:   llvm.extractvalue {{.*}}[0, 0] : !llvm.array<4 x array<3 x vector<16xf32>>>
584//       CHECK:   llvm.mlir.constant(0 : i64) : i64
585//       CHECK:   llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32>
586//       CHECK:   return {{.*}} : f32
587
588// -----
589
590// CHECK-LABEL: @insert_element_0d
591// CHECK-SAME: %[[A:.*]]: f32,
592func.func @insert_element_0d(%a: f32, %b: vector<f32>) -> vector<f32> {
593  // CHECK: %[[B:.*]] =  builtin.unrealized_conversion_cast %{{.*}} :
594  // CHECK:   vector<f32> to vector<1xf32>
595  // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
596  // CHECK: %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[C0]] : {{.*}}] : vector<1xf32>
597  %1 = vector.insertelement %a, %b[] : vector<f32>
598  return %1 : vector<f32>
599}
600
601// -----
602
603func.func @insert_element(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> {
604  %0 = arith.constant 3 : i32
605  %1 = vector.insertelement %arg0, %arg1[%0 : i32] : vector<4xf32>
606  return %1 : vector<4xf32>
607}
608// CHECK-LABEL: @insert_element(
609// CHECK-SAME: %[[A:.*]]: f32,
610// CHECK-SAME: %[[B:.*]]: vector<4xf32>)
611//       CHECK:   %[[c:.*]] = arith.constant 3 : i32
612//       CHECK:   %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[c]] : i32] : vector<4xf32>
613//       CHECK:   return %[[x]] : vector<4xf32>
614
615// -----
616
617func.func @insert_element_index(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> {
618  %0 = arith.constant 3 : index
619  %1 = vector.insertelement %arg0, %arg1[%0 : index] : vector<4xf32>
620  return %1 : vector<4xf32>
621}
622// CHECK-LABEL: @insert_element_index(
623//  CHECK-SAME: %[[A:.*]]: f32,
624//  CHECK-SAME: %[[B:.*]]: vector<4xf32>)
625//       CHECK:   %[[c:.*]] = arith.constant 3 : index
626//       CHECK:   %[[i:.*]] = builtin.unrealized_conversion_cast %[[c]] : index to i64
627//       CHECK:   %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[i]] : i64] : vector<4xf32>
628//       CHECK:   return %[[x]] : vector<4xf32>
629
630// -----
631
632func.func @insert_element_into_vec_1d(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> {
633  %0 = vector.insert %arg0, %arg1[3] : f32 into vector<4xf32>
634  return %0 : vector<4xf32>
635}
636// CHECK-LABEL: @insert_element_into_vec_1d
637//       CHECK:   llvm.mlir.constant(3 : i64) : i64
638//       CHECK:   llvm.insertelement {{.*}}, {{.*}}[{{.*}} : i64] : vector<4xf32>
639//       CHECK:   return {{.*}} : vector<4xf32>
640
641// -----
642
643func.func @insert_index_element_into_vec_1d(%arg0: index, %arg1: vector<4xindex>) -> vector<4xindex> {
644  %0 = vector.insert %arg0, %arg1[3] : index into vector<4xindex>
645  return %0 : vector<4xindex>
646}
647// CHECK-LABEL: @insert_index_element_into_vec_1d(
648// CHECK-SAME: %[[A:.*]]: index,
649// CHECK-SAME: %[[B:.*]]: vector<4xindex>)
650//       CHECK-DAG:   %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64
651//       CHECK-DAG:   %[[T1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<4xindex> to vector<4xi64>
652//       CHECK:   %[[T3:.*]] = llvm.mlir.constant(3 : i64) : i64
653//       CHECK:   %[[T4:.*]] = llvm.insertelement %[[T0]], %[[T1]][%[[T3]] : i64] : vector<4xi64>
654//       CHECK:   %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : vector<4xi64> to vector<4xindex>
655//       CHECK:   return %[[T5]] : vector<4xindex>
656
657// -----
658
659func.func @insert_vec_2d_into_vec_3d(%arg0: vector<8x16xf32>, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> {
660  %0 = vector.insert %arg0, %arg1[3] : vector<8x16xf32> into vector<4x8x16xf32>
661  return %0 : vector<4x8x16xf32>
662}
663// CHECK-LABEL: @insert_vec_2d_into_vec_3d
664//       CHECK:   llvm.insertvalue {{.*}}, {{.*}}[3] : !llvm.array<4 x array<8 x vector<16xf32>>>
665//       CHECK:   return {{.*}} : vector<4x8x16xf32>
666
667// -----
668
669func.func @insert_vec_1d_into_vec_3d(%arg0: vector<16xf32>, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> {
670  %0 = vector.insert %arg0, %arg1[3, 7] : vector<16xf32> into vector<4x8x16xf32>
671  return %0 : vector<4x8x16xf32>
672}
673// CHECK-LABEL: @insert_vec_1d_into_vec_3d
674//       CHECK:   llvm.insertvalue {{.*}}, {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>>
675//       CHECK:   return {{.*}} : vector<4x8x16xf32>
676
677// -----
678
679func.func @insert_element_into_vec_3d(%arg0: f32, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> {
680  %0 = vector.insert %arg0, %arg1[3, 7, 15] : f32 into vector<4x8x16xf32>
681  return %0 : vector<4x8x16xf32>
682}
683// CHECK-LABEL: @insert_element_into_vec_3d
684//       CHECK:   llvm.extractvalue {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>>
685//       CHECK:   llvm.mlir.constant(15 : i64) : i64
686//       CHECK:   llvm.insertelement {{.*}}, {{.*}}[{{.*}} : i64] : vector<16xf32>
687//       CHECK:   llvm.insertvalue {{.*}}, {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>>
688//       CHECK:   return {{.*}} : vector<4x8x16xf32>
689
690// -----
691
692func.func @vector_type_cast(%arg0: memref<8x8x8xf32>) -> memref<vector<8x8x8xf32>> {
693  %0 = vector.type_cast %arg0: memref<8x8x8xf32> to memref<vector<8x8x8xf32>>
694  return %0 : memref<vector<8x8x8xf32>>
695}
696// CHECK-LABEL: @vector_type_cast
697//       CHECK:   llvm.mlir.undef : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)>
698//       CHECK:   %[[allocated:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<3 x i64>, array<3 x i64>)>
699//       CHECK:   %[[allocatedBit:.*]] = llvm.bitcast %[[allocated]] : !llvm.ptr<f32> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>>
700//       CHECK:   llvm.insertvalue %[[allocatedBit]], {{.*}}[0] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)>
701//       CHECK:   %[[aligned:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<3 x i64>, array<3 x i64>)>
702//       CHECK:   %[[alignedBit:.*]] = llvm.bitcast %[[aligned]] : !llvm.ptr<f32> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>>
703//       CHECK:   llvm.insertvalue %[[alignedBit]], {{.*}}[1] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)>
704//       CHECK:   llvm.mlir.constant(0 : index
705//       CHECK:   llvm.insertvalue {{.*}}[2] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)>
706
707// -----
708
709func.func @vector_index_type_cast(%arg0: memref<8x8x8xindex>) -> memref<vector<8x8x8xindex>> {
710  %0 = vector.type_cast %arg0: memref<8x8x8xindex> to memref<vector<8x8x8xindex>>
711  return %0 : memref<vector<8x8x8xindex>>
712}
713// CHECK-LABEL: @vector_index_type_cast(
714// CHECK-SAME: %[[A:.*]]: memref<8x8x8xindex>)
715//       CHECK:   %{{.*}} = builtin.unrealized_conversion_cast %[[A]] : memref<8x8x8xindex> to !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<3 x i64>, array<3 x i64>)>
716
717//       CHECK:   %{{.*}} = builtin.unrealized_conversion_cast %{{.*}} : !llvm.struct<(ptr<array<8 x array<8 x vector<8xi64>>>>, ptr<array<8 x array<8 x vector<8xi64>>>>, i64)> to memref<vector<8x8x8xindex>>
718
719// -----
720
721func.func @vector_type_cast_non_zero_addrspace(%arg0: memref<8x8x8xf32, 3>) -> memref<vector<8x8x8xf32>, 3> {
722  %0 = vector.type_cast %arg0: memref<8x8x8xf32, 3> to memref<vector<8x8x8xf32>, 3>
723  return %0 : memref<vector<8x8x8xf32>, 3>
724}
725// CHECK-LABEL: @vector_type_cast_non_zero_addrspace
726//       CHECK:   llvm.mlir.undef : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)>
727//       CHECK:   %[[allocated:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.struct<(ptr<f32, 3>, ptr<f32, 3>, i64, array<3 x i64>, array<3 x i64>)>
728//       CHECK:   %[[allocatedBit:.*]] = llvm.bitcast %[[allocated]] : !llvm.ptr<f32, 3> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>, 3>
729//       CHECK:   llvm.insertvalue %[[allocatedBit]], {{.*}}[0] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)>
730//       CHECK:   %[[aligned:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.struct<(ptr<f32, 3>, ptr<f32, 3>, i64, array<3 x i64>, array<3 x i64>)>
731//       CHECK:   %[[alignedBit:.*]] = llvm.bitcast %[[aligned]] : !llvm.ptr<f32, 3> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>, 3>
732//       CHECK:   llvm.insertvalue %[[alignedBit]], {{.*}}[1] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)>
733//       CHECK:   llvm.mlir.constant(0 : index
734//       CHECK:   llvm.insertvalue {{.*}}[2] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)>
735
736// -----
737
738func.func @vector_print_scalar_i1(%arg0: i1) {
739  vector.print %arg0 : i1
740  return
741}
742//
743// Type "boolean" always uses zero extension.
744//
745// CHECK-LABEL: @vector_print_scalar_i1(
746// CHECK-SAME: %[[A:.*]]: i1)
747//       CHECK: %[[S:.*]] = arith.extui %[[A]] : i1 to i64
748//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
749//       CHECK: llvm.call @printNewline() : () -> ()
750
751// -----
752
753func.func @vector_print_scalar_i4(%arg0: i4) {
754  vector.print %arg0 : i4
755  return
756}
757// CHECK-LABEL: @vector_print_scalar_i4(
758// CHECK-SAME: %[[A:.*]]: i4)
759//       CHECK: %[[S:.*]] = arith.extsi %[[A]] : i4 to i64
760//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
761//       CHECK: llvm.call @printNewline() : () -> ()
762
763// -----
764
765func.func @vector_print_scalar_si4(%arg0: si4) {
766  vector.print %arg0 : si4
767  return
768}
769// CHECK-LABEL: @vector_print_scalar_si4(
770// CHECK-SAME: %[[A:.*]]: si4)
771//       CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si4 to i4
772//       CHECK: %[[S:.*]] = arith.extsi %[[C]] : i4 to i64
773//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
774//       CHECK: llvm.call @printNewline() : () -> ()
775
776// -----
777
778func.func @vector_print_scalar_ui4(%arg0: ui4) {
779  vector.print %arg0 : ui4
780  return
781}
782// CHECK-LABEL: @vector_print_scalar_ui4(
783// CHECK-SAME: %[[A:.*]]: ui4)
784//       CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui4 to i4
785//       CHECK: %[[S:.*]] = arith.extui %[[C]] : i4 to i64
786//       CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()
787//       CHECK: llvm.call @printNewline() : () -> ()
788
789// -----
790
791func.func @vector_print_scalar_i32(%arg0: i32) {
792  vector.print %arg0 : i32
793  return
794}
795// CHECK-LABEL: @vector_print_scalar_i32(
796// CHECK-SAME: %[[A:.*]]: i32)
797//       CHECK: %[[S:.*]] = arith.extsi %[[A]] : i32 to i64
798//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
799//       CHECK: llvm.call @printNewline() : () -> ()
800
801// -----
802
803func.func @vector_print_scalar_ui32(%arg0: ui32) {
804  vector.print %arg0 : ui32
805  return
806}
807// CHECK-LABEL: @vector_print_scalar_ui32(
808// CHECK-SAME: %[[A:.*]]: ui32)
809//       CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui32 to i32
810//       CHECK: %[[S:.*]] = arith.extui %[[C]] : i32 to i64
811//       CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()
812
813// -----
814
815func.func @vector_print_scalar_i40(%arg0: i40) {
816  vector.print %arg0 : i40
817  return
818}
819// CHECK-LABEL: @vector_print_scalar_i40(
820// CHECK-SAME: %[[A:.*]]: i40)
821//       CHECK: %[[S:.*]] = arith.extsi %[[A]] : i40 to i64
822//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
823//       CHECK: llvm.call @printNewline() : () -> ()
824
825// -----
826
827func.func @vector_print_scalar_si40(%arg0: si40) {
828  vector.print %arg0 : si40
829  return
830}
831// CHECK-LABEL: @vector_print_scalar_si40(
832// CHECK-SAME: %[[A:.*]]: si40)
833//       CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si40 to i40
834//       CHECK: %[[S:.*]] = arith.extsi %[[C]] : i40 to i64
835//       CHECK: llvm.call @printI64(%[[S]]) : (i64) -> ()
836//       CHECK: llvm.call @printNewline() : () -> ()
837
838// -----
839
840func.func @vector_print_scalar_ui40(%arg0: ui40) {
841  vector.print %arg0 : ui40
842  return
843}
844// CHECK-LABEL: @vector_print_scalar_ui40(
845// CHECK-SAME: %[[A:.*]]: ui40)
846//       CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui40 to i40
847//       CHECK: %[[S:.*]] = arith.extui %[[C]] : i40 to i64
848//       CHECK: llvm.call @printU64(%[[S]]) : (i64) -> ()
849//       CHECK: llvm.call @printNewline() : () -> ()
850
851// -----
852
853func.func @vector_print_scalar_i64(%arg0: i64) {
854  vector.print %arg0 : i64
855  return
856}
857// CHECK-LABEL: @vector_print_scalar_i64(
858// CHECK-SAME: %[[A:.*]]: i64)
859//       CHECK:    llvm.call @printI64(%[[A]]) : (i64) -> ()
860//       CHECK:    llvm.call @printNewline() : () -> ()
861
862// -----
863
864func.func @vector_print_scalar_ui64(%arg0: ui64) {
865  vector.print %arg0 : ui64
866  return
867}
868// CHECK-LABEL: @vector_print_scalar_ui64(
869// CHECK-SAME: %[[A:.*]]: ui64)
870//       CHECK:    %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui64 to i64
871//       CHECK:    llvm.call @printU64(%[[C]]) : (i64) -> ()
872//       CHECK:    llvm.call @printNewline() : () -> ()
873
874// -----
875
876func.func @vector_print_scalar_index(%arg0: index) {
877  vector.print %arg0 : index
878  return
879}
880// CHECK-LABEL: @vector_print_scalar_index(
881// CHECK-SAME: %[[A:.*]]: index)
882//       CHECK:    %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64
883//       CHECK:    llvm.call @printU64(%[[C]]) : (i64) -> ()
884//       CHECK:    llvm.call @printNewline() : () -> ()
885
886// -----
887
888func.func @vector_print_scalar_f32(%arg0: f32) {
889  vector.print %arg0 : f32
890  return
891}
892// CHECK-LABEL: @vector_print_scalar_f32(
893// CHECK-SAME: %[[A:.*]]: f32)
894//       CHECK:    llvm.call @printF32(%[[A]]) : (f32) -> ()
895//       CHECK:    llvm.call @printNewline() : () -> ()
896
897// -----
898
899func.func @vector_print_scalar_f64(%arg0: f64) {
900  vector.print %arg0 : f64
901  return
902}
903// CHECK-LABEL: @vector_print_scalar_f64(
904// CHECK-SAME: %[[A:.*]]: f64)
905//       CHECK:    llvm.call @printF64(%[[A]]) : (f64) -> ()
906//       CHECK:    llvm.call @printNewline() : () -> ()
907
908// -----
909
910func.func @vector_print_vector_0d(%arg0: vector<f32>) {
911  vector.print %arg0 : vector<f32>
912  return
913}
914// CHECK-LABEL: @vector_print_vector_0d(
915// CHECK-SAME: %[[A:.*]]: vector<f32>)
916//       CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32>
917//       CHECK: llvm.call @printOpen() : () -> ()
918//       CHECK: %[[T1:.*]] = llvm.mlir.constant(0 : index) : i64
919//       CHECK: %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<1xf32>
920//       CHECK: llvm.call @printF32(%[[T2]]) : (f32) -> ()
921//       CHECK: llvm.call @printClose() : () -> ()
922//       CHECK: llvm.call @printNewline() : () -> ()
923//       CHECK: return
924
925// -----
926
927func.func @vector_print_vector(%arg0: vector<2x2xf32>) {
928  vector.print %arg0 : vector<2x2xf32>
929  return
930}
931// CHECK-LABEL: @vector_print_vector(
932// CHECK-SAME: %[[A:.*]]: vector<2x2xf32>)
933//       CHECK:    %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>>
934//       CHECK:    llvm.call @printOpen() : () -> ()
935//       CHECK:    %[[x0:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<2xf32>>
936//       CHECK:    llvm.call @printOpen() : () -> ()
937//       CHECK:    %[[x1:.*]] = llvm.mlir.constant(0 : index) : i64
938//       CHECK:    %[[x2:.*]] = llvm.extractelement %[[x0]][%[[x1]] : i64] : vector<2xf32>
939//       CHECK:    llvm.call @printF32(%[[x2]]) : (f32) -> ()
940//       CHECK:    llvm.call @printComma() : () -> ()
941//       CHECK:    %[[x3:.*]] = llvm.mlir.constant(1 : index) : i64
942//       CHECK:    %[[x4:.*]] = llvm.extractelement %[[x0]][%[[x3]] : i64] : vector<2xf32>
943//       CHECK:    llvm.call @printF32(%[[x4]]) : (f32) -> ()
944//       CHECK:    llvm.call @printClose() : () -> ()
945//       CHECK:    llvm.call @printComma() : () -> ()
946//       CHECK:    %[[x5:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<2xf32>>
947//       CHECK:    llvm.call @printOpen() : () -> ()
948//       CHECK:    %[[x6:.*]] = llvm.mlir.constant(0 : index) : i64
949//       CHECK:    %[[x7:.*]] = llvm.extractelement %[[x5]][%[[x6]] : i64] : vector<2xf32>
950//       CHECK:    llvm.call @printF32(%[[x7]]) : (f32) -> ()
951//       CHECK:    llvm.call @printComma() : () -> ()
952//       CHECK:    %[[x8:.*]] = llvm.mlir.constant(1 : index) : i64
953//       CHECK:    %[[x9:.*]] = llvm.extractelement %[[x5]][%[[x8]] : i64] : vector<2xf32>
954//       CHECK:    llvm.call @printF32(%[[x9]]) : (f32) -> ()
955//       CHECK:    llvm.call @printClose() : () -> ()
956//       CHECK:    llvm.call @printClose() : () -> ()
957//       CHECK:    llvm.call @printNewline() : () -> ()
958
959// -----
960
961func.func @extract_strided_slice1(%arg0: vector<4xf32>) -> vector<2xf32> {
962  %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32>
963  return %0 : vector<2xf32>
964}
965// CHECK-LABEL: @extract_strided_slice1(
966//  CHECK-SAME:    %[[A:.*]]: vector<4xf32>)
967//       CHECK:    %[[T0:.*]] = llvm.shufflevector %[[A]], %[[A]] [2, 3] : vector<4xf32>, vector<4xf32>
968//       CHECK:    return %[[T0]] : vector<2xf32>
969
970// -----
971
972func.func @extract_strided_index_slice1(%arg0: vector<4xindex>) -> vector<2xindex> {
973  %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xindex> to vector<2xindex>
974  return %0 : vector<2xindex>
975}
976// CHECK-LABEL: @extract_strided_index_slice1(
977//  CHECK-SAME:    %[[A:.*]]: vector<4xindex>)
978//       CHECK:    %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4xindex> to vector<4xi64>
979//       CHECK:    %[[T2:.*]] = llvm.shufflevector %[[T0]], %[[T0]] [2, 3] : vector<4xi64>, vector<4xi64>
980//       CHECK:    %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2xi64> to vector<2xindex>
981//       CHECK:    return %[[T3]] : vector<2xindex>
982
983// -----
984
985func.func @extract_strided_slice2(%arg0: vector<4x8xf32>) -> vector<2x8xf32> {
986  %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4x8xf32> to vector<2x8xf32>
987  return %0 : vector<2x8xf32>
988}
989// CHECK-LABEL: @extract_strided_slice2(
990//  CHECK-SAME:    %[[ARG:.*]]: vector<4x8xf32>)
991//       CHECK:    %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>>
992//       CHECK:    %[[T0:.*]] = llvm.mlir.undef : !llvm.array<2 x vector<8xf32>>
993//       CHECK:    %[[T1:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>>
994//       CHECK:    %[[T2:.*]] = llvm.insertvalue %[[T1]], %[[T0]][0] : !llvm.array<2 x vector<8xf32>>
995//       CHECK:    %[[T3:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>>
996//       CHECK:    %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[T2]][1] : !llvm.array<2 x vector<8xf32>>
997//       CHECK:    %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<2 x vector<8xf32>> to vector<2x8xf32>
998//       CHECK:    return %[[T5]]
999
1000// -----
1001
1002func.func @extract_strided_slice3(%arg0: vector<4x8xf32>) -> vector<2x2xf32> {
1003  %0 = vector.extract_strided_slice %arg0 {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8xf32> to vector<2x2xf32>
1004  return %0 : vector<2x2xf32>
1005}
1006// CHECK-LABEL: @extract_strided_slice3(
1007//  CHECK-SAME:    %[[ARG:.*]]: vector<4x8xf32>)
1008//       CHECK:    %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>>
1009//       CHECK:    %[[VAL_2:.*]] = arith.constant dense<0.000000e+00> : vector<2x2xf32>
1010//       CHECK:    %[[VAL_6:.*]] = builtin.unrealized_conversion_cast %[[VAL_2]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>>
1011//       CHECK:    %[[T2:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>>
1012//       CHECK:    %[[T3:.*]] = llvm.shufflevector %[[T2]], %[[T2]] [2, 3] : vector<8xf32>, vector<8xf32>
1013//       CHECK:    %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[VAL_6]][0] : !llvm.array<2 x vector<2xf32>>
1014//       CHECK:    %[[T5:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>>
1015//       CHECK:    %[[T6:.*]] = llvm.shufflevector %[[T5]], %[[T5]] [2, 3] : vector<8xf32>, vector<8xf32>
1016//       CHECK:    %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T4]][1] : !llvm.array<2 x vector<2xf32>>
1017//       CHECK:    %[[VAL_12:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<2 x vector<2xf32>> to vector<2x2xf32>
1018//       CHECK:    return %[[VAL_12]] : vector<2x2xf32>
1019
1020// -----
1021
1022func.func @insert_strided_slice1(%b: vector<4x4xf32>, %c: vector<4x4x4xf32>) -> vector<4x4x4xf32> {
1023  %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xf32> into vector<4x4x4xf32>
1024  return %0 : vector<4x4x4xf32>
1025}
1026// CHECK-LABEL: @insert_strided_slice1
1027//       CHECK:    llvm.extractvalue {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xf32>>>
1028//       CHECK:    llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xf32>>>
1029
1030// -----
1031
1032func.func @insert_strided_index_slice1(%b: vector<4x4xindex>, %c: vector<4x4x4xindex>) -> vector<4x4x4xindex> {
1033  %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xindex> into vector<4x4x4xindex>
1034  return %0 : vector<4x4x4xindex>
1035}
1036// CHECK-LABEL: @insert_strided_index_slice1(
1037//       CHECK:    llvm.extractvalue {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xi64>>>
1038//       CHECK:    llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xi64>>>
1039
1040// -----
1041
1042func.func @insert_strided_slice2(%a: vector<2x2xf32>, %b: vector<4x4xf32>) -> vector<4x4xf32> {
1043  %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32>
1044  return %0 : vector<4x4xf32>
1045}
1046
1047// CHECK-LABEL: @insert_strided_slice2
1048//
1049// Subvector vector<2xf32> @0 into vector<4xf32> @2
1050//       CHECK:    %[[V2_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<2xf32>>
1051//       CHECK:    %[[V4_0:.*]] = llvm.extractvalue {{.*}}[2] : !llvm.array<4 x vector<4xf32>>
1052// Element @0 -> element @2
1053//       CHECK:    %[[R4_0:.*]] = llvm.shufflevector %[[V2_0]], %[[V2_0]] [0, 1, 0, 0] : vector<2xf32>, vector<2xf32>
1054//       CHECK:    %[[R4_1:.*]] = llvm.shufflevector %[[R4_0]], %[[V4_0]] [4, 5, 0, 1] : vector<4xf32>, vector<4xf32>
1055//       CHECK:    llvm.insertvalue %[[R4_1]], {{.*}}[2] : !llvm.array<4 x vector<4xf32>>
1056//
1057// Subvector vector<2xf32> @1 into vector<4xf32> @3
1058//       CHECK:    %[[V2_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<2xf32>>
1059//       CHECK:    %[[V4_3:.*]] = llvm.extractvalue {{.*}}[3] : !llvm.array<4 x vector<4xf32>>
1060// Element @0 -> element @2
1061//       CHECK:    %[[R4_2:.*]] = llvm.shufflevector %[[V2_1]], %[[V2_1]] [0, 1, 0, 0] : vector<2xf32>, vector<2xf32>
1062//       CHECK:    %[[R4_3:.*]] = llvm.shufflevector %[[R4_2]], %[[V4_3]] [4, 5, 0, 1] : vector<4xf32>, vector<4xf32>
1063//       CHECK:    llvm.insertvalue %[[R4_3]], {{.*}}[3] : !llvm.array<4 x vector<4xf32>>
1064
1065// -----
1066
1067func.func @insert_strided_slice3(%arg0: vector<2x4xf32>, %arg1: vector<16x4x8xf32>) -> vector<16x4x8xf32> {
1068  %0 = vector.insert_strided_slice %arg0, %arg1 {offsets = [0, 0, 2], strides = [1, 1]}:
1069        vector<2x4xf32> into vector<16x4x8xf32>
1070  return %0 : vector<16x4x8xf32>
1071}
1072// CHECK-LABEL: func @insert_strided_slice3
1073//       CHECK:    %[[V4_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<4xf32>>
1074//       CHECK:    %[[V4_0_0:.*]] = llvm.extractvalue {{.*}}[0, 0] : !llvm.array<16 x array<4 x vector<8xf32>>>
1075//       CHECK:    %[[R8_0:.*]] = llvm.shufflevector %[[V4_0]], %[[V4_0]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>, vector<4xf32>
1076//       CHECK:    %[[R8_1:.*]] = llvm.shufflevector %[[R8_0:.*]], %[[V4_0_0]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>, vector<8xf32>
1077//       CHECK:    llvm.insertvalue %[[R8_1]], {{.*}}[0] : !llvm.array<4 x vector<8xf32>>
1078
1079//       CHECK:    %[[V4_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<4xf32>>
1080//       CHECK:    %[[V4_0_1:.*]] = llvm.extractvalue {{.*}}[0, 1] : !llvm.array<16 x array<4 x vector<8xf32>>>
1081//       CHECK:    %[[R8_2:.*]] = llvm.shufflevector %[[V4_1]], %[[V4_1]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>, vector<4xf32>
1082//       CHECK:    %[[R8_3:.*]] = llvm.shufflevector %[[R8_2]], %[[V4_0_1]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>, vector<8xf32>
1083//       CHECK:    llvm.insertvalue %[[R8_3]], {{.*}}[1] : !llvm.array<4 x vector<8xf32>>
1084
1085// -----
1086
1087func.func @vector_fma(%a: vector<8xf32>, %b: vector<2x4xf32>, %c: vector<1x1x1xf32>) -> (vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32>) {
1088  // CHECK-LABEL: @vector_fma
1089  //  CHECK-SAME: %[[A:.*]]: vector<8xf32>
1090  //  CHECK-SAME: %[[B:.*]]: vector<2x4xf32>
1091  //  CHECK-SAME: %[[C:.*]]: vector<1x1x1xf32>
1092  //       CHECK: %[[BL:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>>
1093  //       CHECK: "llvm.intr.fmuladd"
1094  //  CHECK-SAME:   (vector<8xf32>, vector<8xf32>, vector<8xf32>) -> vector<8xf32>
1095  %0 = vector.fma %a, %a, %a : vector<8xf32>
1096
1097  //       CHECK: %[[b00:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>>
1098  //       CHECK: %[[b01:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>>
1099  //       CHECK: %[[b02:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>>
1100  //       CHECK: %[[B0:.*]] = "llvm.intr.fmuladd"(%[[b00]], %[[b01]], %[[b02]]) :
1101  //  CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32>
1102  //       CHECK: llvm.insertvalue %[[B0]], {{.*}}[0] : !llvm.array<2 x vector<4xf32>>
1103  //       CHECK: %[[b10:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>>
1104  //       CHECK: %[[b11:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>>
1105  //       CHECK: %[[b12:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>>
1106  //       CHECK: %[[B1:.*]] = "llvm.intr.fmuladd"(%[[b10]], %[[b11]], %[[b12]]) :
1107  //  CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32>
1108  //       CHECK: llvm.insertvalue %[[B1]], {{.*}}[1] : !llvm.array<2 x vector<4xf32>>
1109  %1 = vector.fma %b, %b, %b : vector<2x4xf32>
1110
1111  //       CHECK: %[[C0:.*]] = "llvm.intr.fmuladd"
1112  //  CHECK-SAME:   (vector<1xf32>, vector<1xf32>, vector<1xf32>) -> vector<1xf32>
1113  %2 = vector.fma %c, %c, %c : vector<1x1x1xf32>
1114
1115  return %0, %1, %2: vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32>
1116}
1117
1118// -----
1119
1120func.func @reduce_f16(%arg0: vector<16xf16>) -> f16 {
1121  %0 = vector.reduction <add>, %arg0 : vector<16xf16> into f16
1122  return %0 : f16
1123}
1124// CHECK-LABEL: @reduce_f16(
1125// CHECK-SAME: %[[A:.*]]: vector<16xf16>)
1126//      CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f16) : f16
1127//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]])
1128// CHECK-SAME: {reassoc = false} : (f16, vector<16xf16>) -> f16
1129//      CHECK: return %[[V]] : f16
1130
1131// -----
1132
1133func.func @reduce_f32(%arg0: vector<16xf32>) -> f32 {
1134  %0 = vector.reduction <add>, %arg0 : vector<16xf32> into f32
1135  return %0 : f32
1136}
1137// CHECK-LABEL: @reduce_f32(
1138// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
1139//      CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f32) : f32
1140//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]])
1141// CHECK-SAME: {reassoc = false} : (f32, vector<16xf32>) -> f32
1142//      CHECK: return %[[V]] : f32
1143
1144// -----
1145
1146func.func @reduce_f64(%arg0: vector<16xf64>) -> f64 {
1147  %0 = vector.reduction <add>, %arg0 : vector<16xf64> into f64
1148  return %0 : f64
1149}
1150// CHECK-LABEL: @reduce_f64(
1151// CHECK-SAME: %[[A:.*]]: vector<16xf64>)
1152//      CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f64) : f64
1153//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]])
1154// CHECK-SAME: {reassoc = false} : (f64, vector<16xf64>) -> f64
1155//      CHECK: return %[[V]] : f64
1156
1157// -----
1158
1159func.func @reduce_i8(%arg0: vector<16xi8>) -> i8 {
1160  %0 = vector.reduction <add>, %arg0 : vector<16xi8> into i8
1161  return %0 : i8
1162}
1163// CHECK-LABEL: @reduce_i8(
1164// CHECK-SAME: %[[A:.*]]: vector<16xi8>)
1165//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]])
1166//      CHECK: return %[[V]] : i8
1167
1168// -----
1169
1170func.func @reduce_i32(%arg0: vector<16xi32>) -> i32 {
1171  %0 = vector.reduction <add>, %arg0 : vector<16xi32> into i32
1172  return %0 : i32
1173}
1174// CHECK-LABEL: @reduce_i32(
1175// CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1176//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]])
1177//      CHECK: return %[[V]] : i32
1178
1179// -----
1180
1181func.func @reduce_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1182  %0 = vector.reduction <add>, %arg0, %arg1 : vector<16xi32> into i32
1183  return %0 : i32
1184}
1185// CHECK-LABEL: @reduce_acc_i32(
1186//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1187//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.add"(%[[A]])
1188//       CHECK: %[[V:.*]] = llvm.add %[[ACC]], %[[R]]
1189//       CHECK: return %[[V]] : i32
1190
1191// -----
1192
1193func.func @reduce_mul_i32(%arg0: vector<16xi32>) -> i32 {
1194  %0 = vector.reduction <mul>, %arg0 : vector<16xi32> into i32
1195  return %0 : i32
1196}
1197// CHECK-LABEL: @reduce_mul_i32(
1198//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1199//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.mul"(%[[A]])
1200//       CHECK: return %[[V]] : i32
1201
1202// -----
1203
1204func.func @reduce_mul_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1205  %0 = vector.reduction <mul>, %arg0, %arg1 : vector<16xi32> into i32
1206  return %0 : i32
1207}
1208// CHECK-LABEL: @reduce_mul_acc_i32(
1209//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1210//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.mul"(%[[A]])
1211//       CHECK: %[[V:.*]] = llvm.mul %[[ACC]], %[[R]]
1212//       CHECK: return %[[V]] : i32
1213
1214// -----
1215
1216func.func @reduce_fmax_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 {
1217  %0 = vector.reduction <maxf>, %arg0, %arg1 : vector<16xf32> into f32
1218  return %0 : f32
1219}
1220// CHECK-LABEL: @reduce_fmax_f32(
1221// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32)
1222//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fmax"(%[[A]]) : (vector<16xf32>) -> f32
1223//      CHECK: %[[C0:.*]] = llvm.fcmp "ogt" %[[V]], %[[B]] : f32
1224//      CHECK: %[[S0:.*]] = llvm.select %[[C0]], %[[V]], %[[B]] : i1, f32
1225//      CHECK: %[[C1:.*]] = llvm.fcmp "uno" %[[V]], %[[B]] : f32
1226//      CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7FC00000 : f32) : f32
1227//      CHECK: %[[R:.*]] = llvm.select %[[C1]], %[[NAN]], %[[S0]] : i1, f32
1228//      CHECK: return %[[R]] : f32
1229
1230// -----
1231
1232func.func @reduce_fmin_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 {
1233  %0 = vector.reduction <minf>, %arg0, %arg1 : vector<16xf32> into f32
1234  return %0 : f32
1235}
1236// CHECK-LABEL: @reduce_fmin_f32(
1237// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32)
1238//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fmin"(%[[A]]) : (vector<16xf32>) -> f32
1239//      CHECK: %[[C0:.*]] = llvm.fcmp "olt" %[[V]], %[[B]] : f32
1240//      CHECK: %[[S0:.*]] = llvm.select %[[C0]], %[[V]], %[[B]] : i1, f32
1241//      CHECK: %[[C1:.*]] = llvm.fcmp "uno" %[[V]], %[[B]] : f32
1242//      CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7FC00000 : f32) : f32
1243//      CHECK: %[[R:.*]] = llvm.select %[[C1]], %[[NAN]], %[[S0]] : i1, f32
1244//      CHECK: return %[[R]] : f32
1245
1246// -----
1247
1248func.func @reduce_minui_i32(%arg0: vector<16xi32>) -> i32 {
1249  %0 = vector.reduction <minui>, %arg0 : vector<16xi32> into i32
1250  return %0 : i32
1251}
1252// CHECK-LABEL: @reduce_minui_i32(
1253//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1254//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.umin"(%[[A]])
1255//       CHECK: return %[[V]] : i32
1256
1257// -----
1258
1259func.func @reduce_minui_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1260  %0 = vector.reduction <minui>, %arg0, %arg1 : vector<16xi32> into i32
1261  return %0 : i32
1262}
1263// CHECK-LABEL: @reduce_minui_acc_i32(
1264//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1265//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.umin"(%[[A]])
1266//       CHECK: %[[S:.*]] = llvm.icmp "ule" %[[ACC]], %[[R]]
1267//       CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]]
1268//       CHECK: return %[[V]] : i32
1269
1270// -----
1271
1272func.func @reduce_maxui_i32(%arg0: vector<16xi32>) -> i32 {
1273  %0 = vector.reduction <maxui>, %arg0 : vector<16xi32> into i32
1274  return %0 : i32
1275}
1276// CHECK-LABEL: @reduce_maxui_i32(
1277//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1278//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.umax"(%[[A]])
1279//       CHECK: return %[[V]] : i32
1280
1281// -----
1282
1283func.func @reduce_maxui_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1284  %0 = vector.reduction <maxui>, %arg0, %arg1 : vector<16xi32> into i32
1285  return %0 : i32
1286}
1287// CHECK-LABEL: @reduce_maxui_acc_i32(
1288//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1289//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.umax"(%[[A]])
1290//       CHECK: %[[S:.*]] = llvm.icmp "uge" %[[ACC]], %[[R]]
1291//       CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]]
1292//       CHECK: return %[[V]] : i32
1293
1294// -----
1295
1296func.func @reduce_minsi_i32(%arg0: vector<16xi32>) -> i32 {
1297  %0 = vector.reduction <minsi>, %arg0 : vector<16xi32> into i32
1298  return %0 : i32
1299}
1300// CHECK-LABEL: @reduce_minsi_i32(
1301//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1302//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.smin"(%[[A]])
1303//       CHECK: return %[[V]] : i32
1304
1305// -----
1306
1307func.func @reduce_minsi_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1308  %0 = vector.reduction <minsi>, %arg0, %arg1 : vector<16xi32> into i32
1309  return %0 : i32
1310}
1311// CHECK-LABEL: @reduce_minsi_acc_i32(
1312//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1313//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.smin"(%[[A]])
1314//       CHECK: %[[S:.*]] = llvm.icmp "sle" %[[ACC]], %[[R]]
1315//       CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]]
1316//       CHECK: return %[[V]] : i32
1317
1318// -----
1319
1320func.func @reduce_maxsi_i32(%arg0: vector<16xi32>) -> i32 {
1321  %0 = vector.reduction <maxsi>, %arg0 : vector<16xi32> into i32
1322  return %0 : i32
1323}
1324// CHECK-LABEL: @reduce_maxsi_i32(
1325//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1326//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.smax"(%[[A]])
1327//       CHECK: return %[[V]] : i32
1328
1329// -----
1330
1331func.func @reduce_maxsi_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1332  %0 = vector.reduction <maxsi>, %arg0, %arg1 : vector<16xi32> into i32
1333  return %0 : i32
1334}
1335// CHECK-LABEL: @reduce_maxsi_acc_i32(
1336//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1337//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.smax"(%[[A]])
1338//       CHECK: %[[S:.*]] = llvm.icmp "sge" %[[ACC]], %[[R]]
1339//       CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]]
1340//       CHECK: return %[[V]] : i32
1341
1342// -----
1343
1344func.func @reduce_and_i32(%arg0: vector<16xi32>) -> i32 {
1345  %0 = vector.reduction <and>, %arg0 : vector<16xi32> into i32
1346  return %0 : i32
1347}
1348// CHECK-LABEL: @reduce_and_i32(
1349//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1350//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.and"(%[[A]])
1351//       CHECK: return %[[V]] : i32
1352
1353// -----
1354
1355func.func @reduce_and_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1356  %0 = vector.reduction <and>, %arg0, %arg1 : vector<16xi32> into i32
1357  return %0 : i32
1358}
1359// CHECK-LABEL: @reduce_and_acc_i32(
1360//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1361//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.and"(%[[A]])
1362//       CHECK: %[[V:.*]] = llvm.and %[[ACC]], %[[R]]
1363//       CHECK: return %[[V]] : i32
1364
1365// -----
1366
1367func.func @reduce_or_i32(%arg0: vector<16xi32>) -> i32 {
1368  %0 = vector.reduction <or>, %arg0 : vector<16xi32> into i32
1369  return %0 : i32
1370}
1371// CHECK-LABEL: @reduce_or_i32(
1372//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1373//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.or"(%[[A]])
1374//       CHECK: return %[[V]] : i32
1375
1376// -----
1377
1378func.func @reduce_or_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1379  %0 = vector.reduction <or>, %arg0, %arg1 : vector<16xi32> into i32
1380  return %0 : i32
1381}
1382// CHECK-LABEL: @reduce_or_acc_i32(
1383//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1384//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.or"(%[[A]])
1385//       CHECK: %[[V:.*]] = llvm.or %[[ACC]], %[[R]]
1386//       CHECK: return %[[V]] : i32
1387
1388// -----
1389
1390func.func @reduce_xor_i32(%arg0: vector<16xi32>) -> i32 {
1391  %0 = vector.reduction <xor>, %arg0 : vector<16xi32> into i32
1392  return %0 : i32
1393}
1394// CHECK-LABEL: @reduce_xor_i32(
1395//  CHECK-SAME: %[[A:.*]]: vector<16xi32>)
1396//       CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.xor"(%[[A]])
1397//       CHECK: return %[[V]] : i32
1398
1399// -----
1400
1401func.func @reduce_xor_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 {
1402  %0 = vector.reduction <xor>, %arg0, %arg1 : vector<16xi32> into i32
1403  return %0 : i32
1404}
1405// CHECK-LABEL: @reduce_xor_acc_i32(
1406//  CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32)
1407//       CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.xor"(%[[A]])
1408//       CHECK: %[[V:.*]] = llvm.xor %[[ACC]], %[[R]]
1409//       CHECK: return %[[V]] : i32
1410
1411// -----
1412
1413func.func @reduce_i64(%arg0: vector<16xi64>) -> i64 {
1414  %0 = vector.reduction <add>, %arg0 : vector<16xi64> into i64
1415  return %0 : i64
1416}
1417// CHECK-LABEL: @reduce_i64(
1418// CHECK-SAME: %[[A:.*]]: vector<16xi64>)
1419//      CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]])
1420//      CHECK: return %[[V]] : i64
1421
1422// -----
1423
1424func.func @reduce_index(%arg0: vector<16xindex>) -> index {
1425  %0 = vector.reduction <add>, %arg0 : vector<16xindex> into index
1426  return %0 : index
1427}
1428// CHECK-LABEL: @reduce_index(
1429// CHECK-SAME: %[[A:.*]]: vector<16xindex>)
1430//      CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64>
1431//      CHECK: %[[T1:.*]] = "llvm.intr.vector.reduce.add"(%[[T0]])
1432//      CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : i64 to index
1433//      CHECK: return %[[T2]] : index
1434
1435//                          4x16                16x3               4x3
1436// -----
1437
1438func.func @matrix_ops(%A: vector<64xf64>, %B: vector<48xf64>) -> vector<12xf64> {
1439  %C = vector.matrix_multiply %A, %B
1440    { lhs_rows = 4: i32, lhs_columns = 16: i32 , rhs_columns = 3: i32 } :
1441    (vector<64xf64>, vector<48xf64>) -> vector<12xf64>
1442  return %C: vector<12xf64>
1443}
1444// CHECK-LABEL: @matrix_ops
1445//       CHECK:   llvm.intr.matrix.multiply %{{.*}}, %{{.*}} {
1446//  CHECK-SAME: lhs_columns = 16 : i32, lhs_rows = 4 : i32, rhs_columns = 3 : i32
1447//  CHECK-SAME: } : (vector<64xf64>, vector<48xf64>) -> vector<12xf64>
1448
1449// -----
1450
1451func.func @matrix_ops_index(%A: vector<64xindex>, %B: vector<48xindex>) -> vector<12xindex> {
1452  %C = vector.matrix_multiply %A, %B
1453    { lhs_rows = 4: i32, lhs_columns = 16: i32 , rhs_columns = 3: i32 } :
1454    (vector<64xindex>, vector<48xindex>) -> vector<12xindex>
1455  return %C: vector<12xindex>
1456}
1457// CHECK-LABEL: @matrix_ops_index
1458//       CHECK:   llvm.intr.matrix.multiply %{{.*}}, %{{.*}} {
1459//  CHECK-SAME: lhs_columns = 16 : i32, lhs_rows = 4 : i32, rhs_columns = 3 : i32
1460//  CHECK-SAME: } : (vector<64xi64>, vector<48xi64>) -> vector<12xi64>
1461
1462// -----
1463
1464func.func @transfer_read_1d(%A : memref<?xf32>, %base: index) -> vector<17xf32> {
1465  %f7 = arith.constant 7.0: f32
1466  %f = vector.transfer_read %A[%base], %f7
1467      {permutation_map = affine_map<(d0) -> (d0)>} :
1468    memref<?xf32>, vector<17xf32>
1469  vector.transfer_write %f, %A[%base]
1470      {permutation_map = affine_map<(d0) -> (d0)>} :
1471    vector<17xf32>, memref<?xf32>
1472  return %f: vector<17xf32>
1473}
1474// CHECK-LABEL: func @transfer_read_1d
1475//  CHECK-SAME: %[[MEM:.*]]: memref<?xf32>,
1476//  CHECK-SAME: %[[BASE:.*]]: index) -> vector<17xf32>
1477//       CHECK: %[[C7:.*]] = arith.constant 7.0
1478//
1479// 1. Let dim be the memref dimension, compute the in-bound index (dim - offset)
1480//       CHECK: %[[C0:.*]] = arith.constant 0 : index
1481//       CHECK: %[[DIM:.*]] = memref.dim %[[MEM]], %[[C0]] : memref<?xf32>
1482//       CHECK: %[[BOUND:.*]] = arith.subi %[[DIM]],  %[[BASE]] : index
1483//
1484// 2. Create a vector with linear indices [ 0 .. vector_length - 1 ].
1485//       CHECK: %[[linearIndex:.*]] = arith.constant dense
1486//  CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> :
1487//  CHECK-SAME: vector<17xi32>
1488//
1489// 3. Create bound vector to compute in-bound mask:
1490//    [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ]
1491//       CHECK: %[[btrunc:.*]] = arith.index_cast %[[BOUND]] : index to i32
1492//       CHECK: %[[boundVecInsert:.*]] = llvm.insertelement %[[btrunc]]
1493//       CHECK: %[[boundVect:.*]] = llvm.shufflevector %[[boundVecInsert]]
1494//       CHECK: %[[mask:.*]] = arith.cmpi slt, %[[linearIndex]], %[[boundVect]]
1495//  CHECK-SAME: : vector<17xi32>
1496//
1497// 4. Create pass-through vector.
1498//       CHECK: %[[PASS_THROUGH:.*]] = arith.constant dense<7.{{.*}}> : vector<17xf32>
1499//
1500// 5. Bitcast to vector form.
1501//       CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}} :
1502//  CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1503//       CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] :
1504//  CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>>
1505//
1506// 6. Rewrite as a masked read.
1507//       CHECK: %[[loaded:.*]] = llvm.intr.masked.load %[[vecPtr]], %[[mask]],
1508//  CHECK-SAME: %[[PASS_THROUGH]] {alignment = 4 : i32} :
1509//
1510// 1. Let dim be the memref dimension, compute the in-bound index (dim - offset)
1511//       CHECK: %[[C0_b:.*]] = arith.constant 0 : index
1512//       CHECK: %[[DIM_b:.*]] = memref.dim %[[MEM]], %[[C0_b]] : memref<?xf32>
1513//       CHECK: %[[BOUND_b:.*]] = arith.subi %[[DIM_b]], %[[BASE]] : index
1514//
1515// 2. Create a vector with linear indices [ 0 .. vector_length - 1 ].
1516//       CHECK: %[[linearIndex_b:.*]] = arith.constant dense
1517//  CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> :
1518//  CHECK-SAME: vector<17xi32>
1519//
1520// 3. Create bound vector to compute in-bound mask:
1521//    [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ]
1522//       CHECK: %[[btrunc_b:.*]] = arith.index_cast %[[BOUND_b]] : index to i32
1523//       CHECK: %[[boundVecInsert_b:.*]] = llvm.insertelement %[[btrunc_b]]
1524//       CHECK: %[[boundVect_b:.*]] = llvm.shufflevector %[[boundVecInsert_b]]
1525//       CHECK: %[[mask_b:.*]] = arith.cmpi slt, %[[linearIndex_b]],
1526//  CHECK-SAME: %[[boundVect_b]] : vector<17xi32>
1527//
1528// 4. Bitcast to vector form.
1529//       CHECK: %[[gep_b:.*]] = llvm.getelementptr {{.*}} :
1530//  CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1531//       CHECK: %[[vecPtr_b:.*]] = llvm.bitcast %[[gep_b]] :
1532//  CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>>
1533//
1534// 5. Rewrite as a masked write.
1535//       CHECK: llvm.intr.masked.store %[[loaded]], %[[vecPtr_b]], %[[mask_b]]
1536//  CHECK-SAME: {alignment = 4 : i32} :
1537//  CHECK-SAME: vector<17xf32>, vector<17xi1> into !llvm.ptr<vector<17xf32>>
1538
1539// -----
1540
1541func.func @transfer_read_index_1d(%A : memref<?xindex>, %base: index) -> vector<17xindex> {
1542  %f7 = arith.constant 7: index
1543  %f = vector.transfer_read %A[%base], %f7
1544      {permutation_map = affine_map<(d0) -> (d0)>} :
1545    memref<?xindex>, vector<17xindex>
1546  vector.transfer_write %f, %A[%base]
1547      {permutation_map = affine_map<(d0) -> (d0)>} :
1548    vector<17xindex>, memref<?xindex>
1549  return %f: vector<17xindex>
1550}
1551// CHECK-LABEL: func @transfer_read_index_1d
1552//  CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xindex>
1553//       CHECK: %[[SPLAT:.*]] = arith.constant dense<7> : vector<17xindex>
1554//       CHECK: %{{.*}} = builtin.unrealized_conversion_cast %[[SPLAT]] : vector<17xindex> to vector<17xi64>
1555
1556//       CHECK: %[[loaded:.*]] = llvm.intr.masked.load %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} :
1557//  CHECK-SAME: (!llvm.ptr<vector<17xi64>>, vector<17xi1>, vector<17xi64>) -> vector<17xi64>
1558
1559//       CHECK: llvm.intr.masked.store %[[loaded]], %{{.*}}, %{{.*}} {alignment = 8 : i32} :
1560//  CHECK-SAME: vector<17xi64>, vector<17xi1> into !llvm.ptr<vector<17xi64>>
1561
1562// -----
1563
1564func.func @transfer_read_2d_to_1d(%A : memref<?x?xf32>, %base0: index, %base1: index) -> vector<17xf32> {
1565  %f7 = arith.constant 7.0: f32
1566  %f = vector.transfer_read %A[%base0, %base1], %f7
1567      {permutation_map = affine_map<(d0, d1) -> (d1)>} :
1568    memref<?x?xf32>, vector<17xf32>
1569  return %f: vector<17xf32>
1570}
1571// CHECK-LABEL: func @transfer_read_2d_to_1d
1572//  CHECK-SAME: %[[BASE_0:[a-zA-Z0-9]*]]: index, %[[BASE_1:[a-zA-Z0-9]*]]: index) -> vector<17xf32>
1573//       CHECK: %[[c1:.*]] = arith.constant 1 : index
1574//       CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<?x?xf32>
1575//
1576// Compute the in-bound index (dim - offset)
1577//       CHECK: %[[BOUND:.*]] = arith.subi %[[DIM]], %[[BASE_1]] : index
1578//
1579// Create a vector with linear indices [ 0 .. vector_length - 1 ].
1580//       CHECK: %[[linearIndex:.*]] = arith.constant dense
1581//  CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> :
1582//  CHECK-SAME: vector<17xi32>
1583//
1584// Create bound vector to compute in-bound mask:
1585//    [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ]
1586//       CHECK: %[[btrunc:.*]] = arith.index_cast %[[BOUND]] : index to i32
1587//       CHECK: %[[boundVecInsert:.*]] = llvm.insertelement %[[btrunc]]
1588//       CHECK: %[[boundVect:.*]] = llvm.shufflevector %[[boundVecInsert]]
1589//       CHECK: %[[mask:.*]] = arith.cmpi slt, %[[linearIndex]], %[[boundVect]]
1590
1591// -----
1592
1593func.func @transfer_read_1d_non_zero_addrspace(%A : memref<?xf32, 3>, %base: index) -> vector<17xf32> {
1594  %f7 = arith.constant 7.0: f32
1595  %f = vector.transfer_read %A[%base], %f7
1596      {permutation_map = affine_map<(d0) -> (d0)>} :
1597    memref<?xf32, 3>, vector<17xf32>
1598  vector.transfer_write %f, %A[%base]
1599      {permutation_map = affine_map<(d0) -> (d0)>} :
1600    vector<17xf32>, memref<?xf32, 3>
1601  return %f: vector<17xf32>
1602}
1603// CHECK-LABEL: func @transfer_read_1d_non_zero_addrspace
1604//  CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xf32>
1605//
1606// 1. Check address space for GEP is correct.
1607//       CHECK: %[[gep:.*]] = llvm.getelementptr {{.*}} :
1608//  CHECK-SAME: (!llvm.ptr<f32, 3>, i64) -> !llvm.ptr<f32, 3>
1609//       CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] :
1610//  CHECK-SAME: !llvm.ptr<f32, 3> to !llvm.ptr<vector<17xf32>, 3>
1611//
1612// 2. Check address space of the memref is correct.
1613//       CHECK: %[[c0:.*]] = arith.constant 0 : index
1614//       CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[c0]] : memref<?xf32, 3>
1615//
1616// 3. Check address space for GEP is correct.
1617//       CHECK: %[[gep_b:.*]] = llvm.getelementptr {{.*}} :
1618//  CHECK-SAME: (!llvm.ptr<f32, 3>, i64) -> !llvm.ptr<f32, 3>
1619//       CHECK: %[[vecPtr_b:.*]] = llvm.bitcast %[[gep_b]] :
1620//  CHECK-SAME: !llvm.ptr<f32, 3> to !llvm.ptr<vector<17xf32>, 3>
1621
1622// -----
1623
1624func.func @transfer_read_1d_inbounds(%A : memref<?xf32>, %base: index) -> vector<17xf32> {
1625  %f7 = arith.constant 7.0: f32
1626  %f = vector.transfer_read %A[%base], %f7 {in_bounds = [true]} :
1627    memref<?xf32>, vector<17xf32>
1628  return %f: vector<17xf32>
1629}
1630// CHECK-LABEL: func @transfer_read_1d_inbounds
1631//  CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xf32>
1632//
1633// 1. Bitcast to vector form.
1634//       CHECK: %[[gep:.*]] = llvm.getelementptr {{.*}} :
1635//  CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1636//       CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] :
1637//  CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>>
1638//
1639// 2. Rewrite as a load.
1640//       CHECK: %[[loaded:.*]] = llvm.load %[[vecPtr]] {alignment = 4 : i64} : !llvm.ptr<vector<17xf32>>
1641
1642// -----
1643
1644// CHECK-LABEL: func @transfer_read_1d_mask
1645// CHECK: %[[mask1:.*]] = arith.constant dense<[false, false, true, false, true]>
1646// CHECK: %[[cmpi:.*]] = arith.cmpi slt
1647// CHECK: %[[mask2:.*]] = arith.andi %[[cmpi]], %[[mask1]]
1648// CHECK: %[[r:.*]] = llvm.intr.masked.load %{{.*}}, %[[mask2]]
1649// CHECK: return %[[r]]
1650func.func @transfer_read_1d_mask(%A : memref<?xf32>, %base : index) -> vector<5xf32> {
1651  %m = arith.constant dense<[0, 0, 1, 0, 1]> : vector<5xi1>
1652  %f7 = arith.constant 7.0: f32
1653  %f = vector.transfer_read %A[%base], %f7, %m : memref<?xf32>, vector<5xf32>
1654  return %f: vector<5xf32>
1655}
1656
1657// -----
1658
1659func.func @genbool_0d_f() -> vector<i1> {
1660  %0 = vector.constant_mask [0] : vector<i1>
1661  return %0 : vector<i1>
1662}
1663// CHECK-LABEL: func @genbool_0d_f
1664// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<i1>
1665// CHECK: return %[[VAL_0]] : vector<i1>
1666
1667// -----
1668
1669func.func @genbool_0d_t() -> vector<i1> {
1670  %0 = vector.constant_mask [1] : vector<i1>
1671  return %0 : vector<i1>
1672}
1673// CHECK-LABEL: func @genbool_0d_t
1674// CHECK: %[[VAL_0:.*]] = arith.constant dense<true> : vector<i1>
1675// CHECK: return %[[VAL_0]] : vector<i1>
1676
1677// -----
1678
1679func.func @genbool_1d() -> vector<8xi1> {
1680  %0 = vector.constant_mask [4] : vector<8xi1>
1681  return %0 : vector<8xi1>
1682}
1683// CHECK-LABEL: func @genbool_1d
1684// CHECK: %[[VAL_0:.*]] = arith.constant dense<[true, true, true, true, false, false, false, false]> : vector<8xi1>
1685// CHECK: return %[[VAL_0]] : vector<8xi1>
1686
1687// -----
1688
1689func.func @genbool_1d_scalable() -> vector<[8]xi1> {
1690  %0 = vector.constant_mask [0] : vector<[8]xi1>
1691  return %0 : vector<[8]xi1>
1692}
1693// CHECK-LABEL: func @genbool_1d_scalable
1694// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<[8]xi1>
1695// CHECK: return %[[VAL_0]] : vector<[8]xi1>
1696
1697// -----
1698
1699func.func @genbool_2d() -> vector<4x4xi1> {
1700  %v = vector.constant_mask [2, 2] : vector<4x4xi1>
1701  return %v: vector<4x4xi1>
1702}
1703
1704// CHECK-LABEL: func @genbool_2d
1705// CHECK: %[[VAL_0:.*]] = arith.constant dense<[true, true, false, false]> : vector<4xi1>
1706// CHECK: %[[VAL_1:.*]] = arith.constant dense<false> : vector<4x4xi1>
1707// CHECK: %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[VAL_1]] : vector<4x4xi1> to !llvm.array<4 x vector<4xi1>>
1708// CHECK: %[[VAL_3:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_2]][0] : !llvm.array<4 x vector<4xi1>>
1709// CHECK: %[[VAL_4:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_3]][1] : !llvm.array<4 x vector<4xi1>>
1710// CHECK: %[[VAL_5:.*]] = builtin.unrealized_conversion_cast %[[VAL_4]] : !llvm.array<4 x vector<4xi1>> to vector<4x4xi1>
1711// CHECK: return %[[VAL_5]] : vector<4x4xi1>
1712
1713// -----
1714
1715func.func @create_mask_0d(%a : index) -> vector<i1> {
1716  %v = vector.create_mask %a : vector<i1>
1717  return %v: vector<i1>
1718}
1719
1720// CHECK-LABEL: func @create_mask_0d
1721// CHECK-SAME: %[[arg:.*]]: index
1722// CHECK:  %[[indices:.*]] = arith.constant dense<0> : vector<i32>
1723// CHECK:  %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32
1724// CHECK:  %[[bounds:.*]] = llvm.insertelement %[[arg_i32]]
1725// CHECK:  %[[boundsCast:.*]] = builtin.unrealized_conversion_cast %[[bounds]] : vector<1xi32> to vector<i32>
1726// CHECK:  %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[boundsCast]] : vector<i32>
1727// CHECK:  return %[[result]] : vector<i1>
1728
1729// -----
1730
1731func.func @create_mask_1d(%a : index) -> vector<4xi1> {
1732  %v = vector.create_mask %a : vector<4xi1>
1733  return %v: vector<4xi1>
1734}
1735
1736// CHECK-LABEL: func @create_mask_1d
1737// CHECK-SAME: %[[arg:.*]]: index
1738// CHECK:  %[[indices:.*]] = arith.constant dense<[0, 1, 2, 3]> : vector<4xi32>
1739// CHECK:  %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32
1740// CHECK:  %[[boundsInsert:.*]] = llvm.insertelement %[[arg_i32]]
1741// CHECK:  %[[bounds:.*]] = llvm.shufflevector %[[boundsInsert]]
1742// CHECK:  %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[bounds]] : vector<4xi32>
1743// CHECK:  return %[[result]] : vector<4xi1>
1744
1745func.func @create_mask_1d_scalable(%a : index) -> vector<[4]xi1> {
1746  %v = vector.create_mask %a : vector<[4]xi1>
1747  return %v: vector<[4]xi1>
1748}
1749
1750// CHECK-LABEL: func @create_mask_1d_scalable
1751// CHECK-SAME: %[[arg:.*]]: index
1752// CHECK:  %[[indices:.*]] = llvm.intr.experimental.stepvector : vector<[4]xi32>
1753// CHECK:  %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32
1754// CHECK:  %[[boundsInsert:.*]] = llvm.insertelement %[[arg_i32]], {{.*}} : vector<[4]xi32>
1755// CHECK:  %[[bounds:.*]] = llvm.shufflevector %[[boundsInsert]], {{.*}} : vector<[4]xi32>, vector<[4]xi32>
1756// CHECK:  %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[bounds]] : vector<[4]xi32>
1757// CHECK: return %[[result]] : vector<[4]xi1>
1758
1759// -----
1760
1761func.func @flat_transpose(%arg0: vector<16xf32>) -> vector<16xf32> {
1762  %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 }
1763     : vector<16xf32> -> vector<16xf32>
1764  return %0 : vector<16xf32>
1765}
1766
1767// CHECK-LABEL: func @flat_transpose
1768// CHECK-SAME:  %[[A:.*]]: vector<16xf32>
1769// CHECK:       %[[T:.*]] = llvm.intr.matrix.transpose %[[A]]
1770// CHECK-SAME:      {columns = 4 : i32, rows = 4 : i32} :
1771// CHECK-SAME:      vector<16xf32> into vector<16xf32>
1772// CHECK:       return %[[T]] : vector<16xf32>
1773
1774// -----
1775
1776func.func @flat_transpose_index(%arg0: vector<16xindex>) -> vector<16xindex> {
1777  %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 }
1778     : vector<16xindex> -> vector<16xindex>
1779  return %0 : vector<16xindex>
1780}
1781// CHECK-LABEL: func @flat_transpose_index
1782// CHECK-SAME:  %[[A:.*]]: vector<16xindex>
1783// CHECK:       %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64>
1784// CHECK:       %[[T1:.*]] = llvm.intr.matrix.transpose %[[T0]]
1785// CHECK-SAME:      {columns = 4 : i32, rows = 4 : i32} :
1786// CHECK-SAME:      vector<16xi64> into vector<16xi64>
1787// CHECK:       %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<16xi64> to vector<16xindex>
1788// CHECK:       return %[[T2]] : vector<16xindex>
1789
1790// -----
1791
1792func.func @vector_load_op(%memref : memref<200x100xf32>, %i : index, %j : index) -> vector<8xf32> {
1793  %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<8xf32>
1794  return %0 : vector<8xf32>
1795}
1796
1797// CHECK-LABEL: func @vector_load_op
1798// CHECK: %[[c100:.*]] = llvm.mlir.constant(100 : index) : i64
1799// CHECK: %[[mul:.*]] = llvm.mul %{{.*}}, %[[c100]]  : i64
1800// CHECK: %[[add:.*]] = llvm.add %[[mul]], %{{.*}}  : i64
1801// CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}}[%[[add]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1802// CHECK: %[[bcast:.*]] = llvm.bitcast %[[gep]] : !llvm.ptr<f32> to !llvm.ptr<vector<8xf32>>
1803// CHECK: llvm.load %[[bcast]] {alignment = 4 : i64} : !llvm.ptr<vector<8xf32>>
1804
1805// -----
1806
1807func.func @vector_load_op_index(%memref : memref<200x100xindex>, %i : index, %j : index) -> vector<8xindex> {
1808  %0 = vector.load %memref[%i, %j] : memref<200x100xindex>, vector<8xindex>
1809  return %0 : vector<8xindex>
1810}
1811// CHECK-LABEL: func @vector_load_op_index
1812// CHECK: %[[T0:.*]] = llvm.load %{{.*}} {alignment = 8 : i64} : !llvm.ptr<vector<8xi64>>
1813// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<8xi64> to vector<8xindex>
1814// CHECK: return %[[T1]] : vector<8xindex>
1815
1816// -----
1817
1818func.func @vector_store_op(%memref : memref<200x100xf32>, %i : index, %j : index) {
1819  %val = arith.constant dense<11.0> : vector<4xf32>
1820  vector.store %val, %memref[%i, %j] : memref<200x100xf32>, vector<4xf32>
1821  return
1822}
1823
1824// CHECK-LABEL: func @vector_store_op
1825// CHECK: %[[c100:.*]] = llvm.mlir.constant(100 : index) : i64
1826// CHECK: %[[mul:.*]] = llvm.mul %{{.*}}, %[[c100]]  : i64
1827// CHECK: %[[add:.*]] = llvm.add %[[mul]], %{{.*}}  : i64
1828// CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}}[%[[add]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1829// CHECK: %[[bcast:.*]] = llvm.bitcast %[[gep]] : !llvm.ptr<f32> to !llvm.ptr<vector<4xf32>>
1830// CHECK: llvm.store %{{.*}}, %[[bcast]] {alignment = 4 : i64} : !llvm.ptr<vector<4xf32>>
1831
1832// -----
1833
1834func.func @vector_store_op_index(%memref : memref<200x100xindex>, %i : index, %j : index) {
1835  %val = arith.constant dense<11> : vector<4xindex>
1836  vector.store %val, %memref[%i, %j] : memref<200x100xindex>, vector<4xindex>
1837  return
1838}
1839// CHECK-LABEL: func @vector_store_op_index
1840// CHECK: llvm.store %{{.*}}, %{{.*}} {alignment = 8 : i64} : !llvm.ptr<vector<4xi64>>
1841
1842// -----
1843
1844func.func @masked_load_op(%arg0: memref<?xf32>, %arg1: vector<16xi1>, %arg2: vector<16xf32>) -> vector<16xf32> {
1845  %c0 = arith.constant 0: index
1846  %0 = vector.maskedload %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32>
1847  return %0 : vector<16xf32>
1848}
1849
1850// CHECK-LABEL: func @masked_load_op
1851// CHECK: %[[CO:.*]] = arith.constant 0 : index
1852// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64
1853// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1854// CHECK: %[[B:.*]] = llvm.bitcast %[[P]] : !llvm.ptr<f32> to !llvm.ptr<vector<16xf32>>
1855// CHECK: %[[L:.*]] = llvm.intr.masked.load %[[B]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.ptr<vector<16xf32>>, vector<16xi1>, vector<16xf32>) -> vector<16xf32>
1856// CHECK: return %[[L]] : vector<16xf32>
1857
1858// -----
1859
1860func.func @masked_load_op_index(%arg0: memref<?xindex>, %arg1: vector<16xi1>, %arg2: vector<16xindex>) -> vector<16xindex> {
1861  %c0 = arith.constant 0: index
1862  %0 = vector.maskedload %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<16xi1>, vector<16xindex> into vector<16xindex>
1863  return %0 : vector<16xindex>
1864}
1865// CHECK-LABEL: func @masked_load_op_index
1866// CHECK: %{{.*}} = llvm.intr.masked.load %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : (!llvm.ptr<vector<16xi64>>, vector<16xi1>, vector<16xi64>) -> vector<16xi64>
1867
1868// -----
1869
1870func.func @masked_store_op(%arg0: memref<?xf32>, %arg1: vector<16xi1>, %arg2: vector<16xf32>) {
1871  %c0 = arith.constant 0: index
1872  vector.maskedstore %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<16xi1>, vector<16xf32>
1873  return
1874}
1875
1876// CHECK-LABEL: func @masked_store_op
1877// CHECK: %[[CO:.*]] = arith.constant 0 : index
1878// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64
1879// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1880// CHECK: %[[B:.*]] = llvm.bitcast %[[P]] : !llvm.ptr<f32> to !llvm.ptr<vector<16xf32>>
1881// CHECK: llvm.intr.masked.store %{{.*}}, %[[B]], %{{.*}} {alignment = 4 : i32} : vector<16xf32>, vector<16xi1> into !llvm.ptr<vector<16xf32>>
1882
1883// -----
1884
1885func.func @masked_store_op_index(%arg0: memref<?xindex>, %arg1: vector<16xi1>, %arg2: vector<16xindex>) {
1886  %c0 = arith.constant 0: index
1887  vector.maskedstore %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<16xi1>, vector<16xindex>
1888  return
1889}
1890// CHECK-LABEL: func @masked_store_op_index
1891// CHECK: llvm.intr.masked.store %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : vector<16xi64>, vector<16xi1> into !llvm.ptr<vector<16xi64>>
1892
1893// -----
1894
1895func.func @gather_op(%arg0: memref<?xf32>, %arg1: vector<3xi32>, %arg2: vector<3xi1>, %arg3: vector<3xf32>) -> vector<3xf32> {
1896  %0 = arith.constant 0: index
1897  %1 = vector.gather %arg0[%0][%arg1], %arg2, %arg3 : memref<?xf32>, vector<3xi32>, vector<3xi1>, vector<3xf32> into vector<3xf32>
1898  return %1 : vector<3xf32>
1899}
1900
1901// CHECK-LABEL: func @gather_op
1902// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, vector<3xi32>) -> !llvm.vec<3 x ptr<f32>>
1903// CHECK: %[[G:.*]] = llvm.intr.masked.gather %[[P]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.vec<3 x ptr<f32>>, vector<3xi1>, vector<3xf32>) -> vector<3xf32>
1904// CHECK: return %[[G]] : vector<3xf32>
1905
1906// -----
1907
1908func.func @gather_op_index(%arg0: memref<?xindex>, %arg1: vector<3xindex>, %arg2: vector<3xi1>, %arg3: vector<3xindex>) -> vector<3xindex> {
1909  %0 = arith.constant 0: index
1910  %1 = vector.gather %arg0[%0][%arg1], %arg2, %arg3 : memref<?xindex>, vector<3xindex>, vector<3xi1>, vector<3xindex> into vector<3xindex>
1911  return %1 : vector<3xindex>
1912}
1913
1914// CHECK-LABEL: func @gather_op_index
1915// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<i64>, vector<3xi64>) -> !llvm.vec<3 x ptr<i64>>
1916// CHECK: %[[G:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : (!llvm.vec<3 x ptr<i64>>, vector<3xi1>, vector<3xi64>) -> vector<3xi64>
1917// CHECK: %{{.*}} = builtin.unrealized_conversion_cast %[[G]] : vector<3xi64> to vector<3xindex>
1918
1919// -----
1920
1921func.func @gather_2d_op(%arg0: memref<4x4xf32>, %arg1: vector<4xi32>, %arg2: vector<4xi1>, %arg3: vector<4xf32>) -> vector<4xf32> {
1922  %0 = arith.constant 3 : index
1923  %1 = vector.gather %arg0[%0, %0][%arg1], %arg2, %arg3 : memref<4x4xf32>, vector<4xi32>, vector<4xi1>, vector<4xf32> into vector<4xf32>
1924  return %1 : vector<4xf32>
1925}
1926
1927// CHECK-LABEL: func @gather_2d_op
1928// CHECK: %[[B:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1929// CHECK: %[[P:.*]] = llvm.getelementptr %[[B]][%{{.*}}] : (!llvm.ptr<f32>, vector<4xi32>) -> !llvm.vec<4 x ptr<f32>>
1930// CHECK: %[[G:.*]] = llvm.intr.masked.gather %[[P]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.vec<4 x ptr<f32>>, vector<4xi1>, vector<4xf32>) -> vector<4xf32>
1931// CHECK: return %[[G]] : vector<4xf32>
1932
1933// -----
1934
1935func.func @scatter_op(%arg0: memref<?xf32>, %arg1: vector<3xi32>, %arg2: vector<3xi1>, %arg3: vector<3xf32>) {
1936  %0 = arith.constant 0: index
1937  vector.scatter %arg0[%0][%arg1], %arg2, %arg3 : memref<?xf32>, vector<3xi32>, vector<3xi1>, vector<3xf32>
1938  return
1939}
1940
1941// CHECK-LABEL: func @scatter_op
1942// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, vector<3xi32>) -> !llvm.vec<3 x ptr<f32>>
1943// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 4 : i32} : vector<3xf32>, vector<3xi1> into !llvm.vec<3 x ptr<f32>>
1944
1945// -----
1946
1947func.func @scatter_op_index(%arg0: memref<?xindex>, %arg1: vector<3xindex>, %arg2: vector<3xi1>, %arg3: vector<3xindex>) {
1948  %0 = arith.constant 0: index
1949  vector.scatter %arg0[%0][%arg1], %arg2, %arg3 : memref<?xindex>, vector<3xindex>, vector<3xi1>, vector<3xindex>
1950  return
1951}
1952
1953// CHECK-LABEL: func @scatter_op_index
1954// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<i64>, vector<3xi64>) -> !llvm.vec<3 x ptr<i64>>
1955// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 8 : i32} : vector<3xi64>, vector<3xi1> into !llvm.vec<3 x ptr<i64>>
1956
1957// -----
1958
1959func.func @scatter_2d_op(%arg0: memref<4x4xf32>, %arg1: vector<4xi32>, %arg2: vector<4xi1>, %arg3: vector<4xf32>) {
1960  %0 = arith.constant 3 : index
1961  vector.scatter %arg0[%0, %0][%arg1], %arg2, %arg3 : memref<4x4xf32>, vector<4xi32>, vector<4xi1>, vector<4xf32>
1962  return
1963}
1964
1965// CHECK-LABEL: func @scatter_2d_op
1966// CHECK: %[[B:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1967// CHECK: %[[P:.*]] = llvm.getelementptr %[[B]][%{{.*}}] : (!llvm.ptr<f32>, vector<4xi32>) -> !llvm.vec<4 x ptr<f32>>
1968// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 4 : i32} : vector<4xf32>, vector<4xi1> into !llvm.vec<4 x ptr<f32>>
1969
1970// -----
1971
1972func.func @expand_load_op(%arg0: memref<?xf32>, %arg1: vector<11xi1>, %arg2: vector<11xf32>) -> vector<11xf32> {
1973  %c0 = arith.constant 0: index
1974  %0 = vector.expandload %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<11xi1>, vector<11xf32> into vector<11xf32>
1975  return %0 : vector<11xf32>
1976}
1977
1978// CHECK-LABEL: func @expand_load_op
1979// CHECK: %[[CO:.*]] = arith.constant 0 : index
1980// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64
1981// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
1982// CHECK: %[[E:.*]] = "llvm.intr.masked.expandload"(%[[P]], %{{.*}}, %{{.*}}) : (!llvm.ptr<f32>, vector<11xi1>, vector<11xf32>) -> vector<11xf32>
1983// CHECK: return %[[E]] : vector<11xf32>
1984
1985// -----
1986
1987func.func @expand_load_op_index(%arg0: memref<?xindex>, %arg1: vector<11xi1>, %arg2: vector<11xindex>) -> vector<11xindex> {
1988  %c0 = arith.constant 0: index
1989  %0 = vector.expandload %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<11xi1>, vector<11xindex> into vector<11xindex>
1990  return %0 : vector<11xindex>
1991}
1992// CHECK-LABEL: func @expand_load_op_index
1993// CHECK: %{{.*}} = "llvm.intr.masked.expandload"(%{{.*}}, %{{.*}}, %{{.*}}) : (!llvm.ptr<i64>, vector<11xi1>, vector<11xi64>) -> vector<11xi64>
1994
1995// -----
1996
1997func.func @compress_store_op(%arg0: memref<?xf32>, %arg1: vector<11xi1>, %arg2: vector<11xf32>) {
1998  %c0 = arith.constant 0: index
1999  vector.compressstore %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<11xi1>, vector<11xf32>
2000  return
2001}
2002
2003// CHECK-LABEL: func @compress_store_op
2004// CHECK: %[[CO:.*]] = arith.constant 0 : index
2005// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64
2006// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
2007// CHECK: "llvm.intr.masked.compressstore"(%{{.*}}, %[[P]], %{{.*}}) : (vector<11xf32>, !llvm.ptr<f32>, vector<11xi1>) -> ()
2008
2009// -----
2010
2011func.func @compress_store_op_index(%arg0: memref<?xindex>, %arg1: vector<11xi1>, %arg2: vector<11xindex>) {
2012  %c0 = arith.constant 0: index
2013  vector.compressstore %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<11xi1>, vector<11xindex>
2014  return
2015}
2016// CHECK-LABEL: func @compress_store_op_index
2017// CHECK: "llvm.intr.masked.compressstore"(%{{.*}}, %{{.*}}, %{{.*}}) : (vector<11xi64>, !llvm.ptr<i64>, vector<11xi1>) -> ()
2018
2019// -----
2020
2021// CHECK-LABEL: @splat_0d
2022// CHECK-SAME: %[[ARG:.*]]: f32
2023func.func @splat_0d(%a: f32) -> vector<f32> {
2024  %v = vector.splat %a : vector<f32>
2025  return %v : vector<f32>
2026}
2027// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : vector<1xf32>
2028// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : i32
2029// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ARG]], %[[UNDEF]][%[[ZERO]] : i32] : vector<1xf32>
2030// CHECK-NEXT: %[[VCAST:[0-9]+]] = builtin.unrealized_conversion_cast %[[V]] : vector<1xf32> to vector<f32>
2031// CHECK-NEXT: return %[[VCAST]] : vector<f32>
2032
2033// -----
2034
2035// CHECK-LABEL: @splat
2036// CHECK-SAME: %[[A:arg[0-9]+]]: vector<4xf32>
2037// CHECK-SAME: %[[ELT:arg[0-9]+]]: f32
2038func.func @splat(%a: vector<4xf32>, %b: f32) -> vector<4xf32> {
2039  %vb = vector.splat %b : vector<4xf32>
2040  %r = arith.mulf %a, %vb : vector<4xf32>
2041  return %r : vector<4xf32>
2042}
2043// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : vector<4xf32>
2044// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : i32
2045// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ELT]], %[[UNDEF]][%[[ZERO]] : i32] : vector<4xf32>
2046// CHECK-NEXT: %[[SPLAT:[0-9]+]] = llvm.shufflevector %[[V]], %[[UNDEF]] [0 : i32, 0 : i32, 0 : i32, 0 : i32]
2047// CHECK-NEXT: %[[SCALE:[0-9]+]] = arith.mulf %[[A]], %[[SPLAT]] : vector<4xf32>
2048// CHECK-NEXT: return %[[SCALE]] : vector<4xf32>
2049