[RISCV] Fix the code alignment for GroupFloatVectors. NFC
[llvm-project.git] / mlir / test / Conversion / ArithmeticToLLVM / arith-to-llvm.mlir
blobecc173dc44f0b21cdddee9ba18d315e0b77dcbd9
1 // RUN: mlir-opt -convert-arith-to-llvm %s -split-input-file | FileCheck %s
3 // CHECK-LABEL: @vector_ops
4 func @vector_ops(%arg0: vector<4xf32>, %arg1: vector<4xi1>, %arg2: vector<4xi64>, %arg3: vector<4xi64>) -> vector<4xf32> {
5 // CHECK-NEXT:  %0 = llvm.mlir.constant(dense<4.200000e+01> : vector<4xf32>) : vector<4xf32>
6   %0 = arith.constant dense<42.> : vector<4xf32>
7 // CHECK-NEXT:  %1 = llvm.fadd %arg0, %0 : vector<4xf32>
8   %1 = arith.addf %arg0, %0 : vector<4xf32>
9 // CHECK-NEXT:  %2 = llvm.sdiv %arg2, %arg2 : vector<4xi64>
10   %3 = arith.divsi %arg2, %arg2 : vector<4xi64>
11 // CHECK-NEXT:  %3 = llvm.udiv %arg2, %arg2 : vector<4xi64>
12   %4 = arith.divui %arg2, %arg2 : vector<4xi64>
13 // CHECK-NEXT:  %4 = llvm.srem %arg2, %arg2 : vector<4xi64>
14   %5 = arith.remsi %arg2, %arg2 : vector<4xi64>
15 // CHECK-NEXT:  %5 = llvm.urem %arg2, %arg2 : vector<4xi64>
16   %6 = arith.remui %arg2, %arg2 : vector<4xi64>
17 // CHECK-NEXT:  %6 = llvm.fdiv %arg0, %0 : vector<4xf32>
18   %7 = arith.divf %arg0, %0 : vector<4xf32>
19 // CHECK-NEXT:  %7 = llvm.frem %arg0, %0 : vector<4xf32>
20   %8 = arith.remf %arg0, %0 : vector<4xf32>
21 // CHECK-NEXT:  %8 = llvm.and %arg2, %arg3 : vector<4xi64>
22   %9 = arith.andi %arg2, %arg3 : vector<4xi64>
23 // CHECK-NEXT:  %9 = llvm.or %arg2, %arg3 : vector<4xi64>
24   %10 = arith.ori %arg2, %arg3 : vector<4xi64>
25 // CHECK-NEXT:  %10 = llvm.xor %arg2, %arg3 : vector<4xi64>
26   %11 = arith.xori %arg2, %arg3 : vector<4xi64>
27 // CHECK-NEXT:  %11 = llvm.shl %arg2, %arg2 : vector<4xi64>
28   %12 = arith.shli %arg2, %arg2 : vector<4xi64>
29 // CHECK-NEXT:  %12 = llvm.ashr %arg2, %arg2 : vector<4xi64>
30   %13 = arith.shrsi %arg2, %arg2 : vector<4xi64>
31 // CHECK-NEXT:  %13 = llvm.lshr %arg2, %arg2 : vector<4xi64>
32   %14 = arith.shrui %arg2, %arg2 : vector<4xi64>
33   return %1 : vector<4xf32>
36 // CHECK-LABEL: @ops
37 func @ops(f32, f32, i32, i32, f64) -> (f32, i32) {
38 ^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64):
39 // CHECK:  = llvm.fsub %arg0, %arg1 : f32
40   %0 = arith.subf %arg0, %arg1: f32
41 // CHECK: = llvm.sub %arg2, %arg3 : i32
42   %1 = arith.subi %arg2, %arg3: i32
43 // CHECK: = llvm.icmp "slt" %arg2, %1 : i32
44   %2 = arith.cmpi slt, %arg2, %1 : i32
45 // CHECK: = llvm.sdiv %arg2, %arg3 : i32
46   %3 = arith.divsi %arg2, %arg3 : i32
47 // CHECK: = llvm.udiv %arg2, %arg3 : i32
48   %4 = arith.divui %arg2, %arg3 : i32
49 // CHECK: = llvm.srem %arg2, %arg3 : i32
50   %5 = arith.remsi %arg2, %arg3 : i32
51 // CHECK: = llvm.urem %arg2, %arg3 : i32
52   %6 = arith.remui %arg2, %arg3 : i32
53 // CHECK: = llvm.fdiv %arg0, %arg1 : f32
54   %8 = arith.divf %arg0, %arg1 : f32
55 // CHECK: = llvm.frem %arg0, %arg1 : f32
56   %9 = arith.remf %arg0, %arg1 : f32
57 // CHECK: = llvm.and %arg2, %arg3 : i32
58   %10 = arith.andi %arg2, %arg3 : i32
59 // CHECK: = llvm.or %arg2, %arg3 : i32
60   %11 = arith.ori %arg2, %arg3 : i32
61 // CHECK: = llvm.xor %arg2, %arg3 : i32
62   %12 = arith.xori %arg2, %arg3 : i32
63 // CHECK: = llvm.mlir.constant(7.900000e-01 : f64) : f64
64   %15 = arith.constant 7.9e-01 : f64
65 // CHECK: = llvm.shl %arg2, %arg3 : i32
66   %16 = arith.shli %arg2, %arg3 : i32
67 // CHECK: = llvm.ashr %arg2, %arg3 : i32
68   %17 = arith.shrsi %arg2, %arg3 : i32
69 // CHECK: = llvm.lshr %arg2, %arg3 : i32
70   %18 = arith.shrui %arg2, %arg3 : i32
71   return %0, %4 : f32, i32
74 // Checking conversion of index types to integers using i1, assuming no target
75 // system would have a 1-bit address space.  Otherwise, we would have had to
76 // make this test dependent on the pointer size on the target system.
77 // CHECK-LABEL: @index_cast
78 func @index_cast(%arg0: index, %arg1: i1) {
79 // CHECK: = llvm.trunc %0 : i{{.*}} to i1
80   %0 = arith.index_cast %arg0: index to i1
81 // CHECK-NEXT: = llvm.sext %arg1 : i1 to i{{.*}}
82   %1 = arith.index_cast %arg1: i1 to index
83   return
86 // CHECK-LABEL: @vector_index_cast
87 func @vector_index_cast(%arg0: vector<2xindex>, %arg1: vector<2xi1>) {
88 // CHECK: = llvm.trunc %{{.*}} : vector<2xi{{.*}}> to vector<2xi1>
89   %0 = arith.index_cast %arg0: vector<2xindex> to vector<2xi1>
90 // CHECK-NEXT: = llvm.sext %{{.*}} : vector<2xi1> to vector<2xi{{.*}}>
91   %1 = arith.index_cast %arg1: vector<2xi1> to vector<2xindex>
92   return
95 // Checking conversion of signed integer types to floating point.
96 // CHECK-LABEL: @sitofp
97 func @sitofp(%arg0 : i32, %arg1 : i64) {
98 // CHECK-NEXT: = llvm.sitofp {{.*}} : i32 to f32
99   %0 = arith.sitofp %arg0: i32 to f32
100 // CHECK-NEXT: = llvm.sitofp {{.*}} : i32 to f64
101   %1 = arith.sitofp %arg0: i32 to f64
102 // CHECK-NEXT: = llvm.sitofp {{.*}} : i64 to f32
103   %2 = arith.sitofp %arg1: i64 to f32
104 // CHECK-NEXT: = llvm.sitofp {{.*}} : i64 to f64
105   %3 = arith.sitofp %arg1: i64 to f64
106   return
109 // Checking conversion of integer vectors to floating point vector types.
110 // CHECK-LABEL: @sitofp_vector
111 func @sitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
112 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi16> to vector<2xf32>
113   %0 = arith.sitofp %arg0: vector<2xi16> to vector<2xf32>
114 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi16> to vector<2xf64>
115   %1 = arith.sitofp %arg0: vector<2xi16> to vector<2xf64>
116 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi32> to vector<2xf32>
117   %2 = arith.sitofp %arg1: vector<2xi32> to vector<2xf32>
118 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi32> to vector<2xf64>
119   %3 = arith.sitofp %arg1: vector<2xi32> to vector<2xf64>
120 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi64> to vector<2xf32>
121   %4 = arith.sitofp %arg2: vector<2xi64> to vector<2xf32>
122 // CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi64> to vector<2xf64>
123   %5 = arith.sitofp %arg2: vector<2xi64> to vector<2xf64>
124   return
127 // Checking conversion of unsigned integer types to floating point.
128 // CHECK-LABEL: @uitofp
129 func @uitofp(%arg0 : i32, %arg1 : i64) {
130 // CHECK-NEXT: = llvm.uitofp {{.*}} : i32 to f32
131   %0 = arith.uitofp %arg0: i32 to f32
132 // CHECK-NEXT: = llvm.uitofp {{.*}} : i32 to f64
133   %1 = arith.uitofp %arg0: i32 to f64
134 // CHECK-NEXT: = llvm.uitofp {{.*}} : i64 to f32
135   %2 = arith.uitofp %arg1: i64 to f32
136 // CHECK-NEXT: = llvm.uitofp {{.*}} : i64 to f64
137   %3 = arith.uitofp %arg1: i64 to f64
138   return
141 // Checking conversion of integer types to floating point.
142 // CHECK-LABEL: @fpext
143 func @fpext(%arg0 : f16, %arg1 : f32) {
144 // CHECK-NEXT: = llvm.fpext {{.*}} : f16 to f32
145   %0 = arith.extf %arg0: f16 to f32
146 // CHECK-NEXT: = llvm.fpext {{.*}} : f16 to f64
147   %1 = arith.extf %arg0: f16 to f64
148 // CHECK-NEXT: = llvm.fpext {{.*}} : f32 to f64
149   %2 = arith.extf %arg1: f32 to f64
150   return
153 // Checking conversion of integer types to floating point.
154 // CHECK-LABEL: @fpext
155 func @fpext_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>) {
156 // CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf16> to vector<2xf32>
157   %0 = arith.extf %arg0: vector<2xf16> to vector<2xf32>
158 // CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf16> to vector<2xf64>
159   %1 = arith.extf %arg0: vector<2xf16> to vector<2xf64>
160 // CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf32> to vector<2xf64>
161   %2 = arith.extf %arg1: vector<2xf32> to vector<2xf64>
162   return
165 // Checking conversion of floating point to integer types.
166 // CHECK-LABEL: @fptosi
167 func @fptosi(%arg0 : f32, %arg1 : f64) {
168 // CHECK-NEXT: = llvm.fptosi {{.*}} : f32 to i32
169   %0 = arith.fptosi %arg0: f32 to i32
170 // CHECK-NEXT: = llvm.fptosi {{.*}} : f32 to i64
171   %1 = arith.fptosi %arg0: f32 to i64
172 // CHECK-NEXT: = llvm.fptosi {{.*}} : f64 to i32
173   %2 = arith.fptosi %arg1: f64 to i32
174 // CHECK-NEXT: = llvm.fptosi {{.*}} : f64 to i64
175   %3 = arith.fptosi %arg1: f64 to i64
176   return
179 // Checking conversion of floating point vectors to integer vector types.
180 // CHECK-LABEL: @fptosi_vector
181 func @fptosi_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
182 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf16> to vector<2xi32>
183   %0 = arith.fptosi %arg0: vector<2xf16> to vector<2xi32>
184 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf16> to vector<2xi64>
185   %1 = arith.fptosi %arg0: vector<2xf16> to vector<2xi64>
186 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf32> to vector<2xi32>
187   %2 = arith.fptosi %arg1: vector<2xf32> to vector<2xi32>
188 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf32> to vector<2xi64>
189   %3 = arith.fptosi %arg1: vector<2xf32> to vector<2xi64>
190 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf64> to vector<2xi32>
191   %4 = arith.fptosi %arg2: vector<2xf64> to vector<2xi32>
192 // CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf64> to vector<2xi64>
193   %5 = arith.fptosi %arg2: vector<2xf64> to vector<2xi64>
194   return
197 // Checking conversion of floating point to integer types.
198 // CHECK-LABEL: @fptoui
199 func @fptoui(%arg0 : f32, %arg1 : f64) {
200 // CHECK-NEXT: = llvm.fptoui {{.*}} : f32 to i32
201   %0 = arith.fptoui %arg0: f32 to i32
202 // CHECK-NEXT: = llvm.fptoui {{.*}} : f32 to i64
203   %1 = arith.fptoui %arg0: f32 to i64
204 // CHECK-NEXT: = llvm.fptoui {{.*}} : f64 to i32
205   %2 = arith.fptoui %arg1: f64 to i32
206 // CHECK-NEXT: = llvm.fptoui {{.*}} : f64 to i64
207   %3 = arith.fptoui %arg1: f64 to i64
208   return
211 // Checking conversion of floating point vectors to integer vector types.
212 // CHECK-LABEL: @fptoui_vector
213 func @fptoui_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
214 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf16> to vector<2xi32>
215   %0 = arith.fptoui %arg0: vector<2xf16> to vector<2xi32>
216 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf16> to vector<2xi64>
217   %1 = arith.fptoui %arg0: vector<2xf16> to vector<2xi64>
218 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf32> to vector<2xi32>
219   %2 = arith.fptoui %arg1: vector<2xf32> to vector<2xi32>
220 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf32> to vector<2xi64>
221   %3 = arith.fptoui %arg1: vector<2xf32> to vector<2xi64>
222 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf64> to vector<2xi32>
223   %4 = arith.fptoui %arg2: vector<2xf64> to vector<2xi32>
224 // CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf64> to vector<2xi64>
225   %5 = arith.fptoui %arg2: vector<2xf64> to vector<2xi64>
226   return
229 // Checking conversion of integer vectors to floating point vector types.
230 // CHECK-LABEL: @uitofp_vector
231 func @uitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
232 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi16> to vector<2xf32>
233   %0 = arith.uitofp %arg0: vector<2xi16> to vector<2xf32>
234 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi16> to vector<2xf64>
235   %1 = arith.uitofp %arg0: vector<2xi16> to vector<2xf64>
236 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi32> to vector<2xf32>
237   %2 = arith.uitofp %arg1: vector<2xi32> to vector<2xf32>
238 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi32> to vector<2xf64>
239   %3 = arith.uitofp %arg1: vector<2xi32> to vector<2xf64>
240 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi64> to vector<2xf32>
241   %4 = arith.uitofp %arg2: vector<2xi64> to vector<2xf32>
242 // CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi64> to vector<2xf64>
243   %5 = arith.uitofp %arg2: vector<2xi64> to vector<2xf64>
244   return
247 // Checking conversion of integer types to floating point.
248 // CHECK-LABEL: @fptrunc
249 func @fptrunc(%arg0 : f32, %arg1 : f64) {
250 // CHECK-NEXT: = llvm.fptrunc {{.*}} : f32 to f16
251   %0 = arith.truncf %arg0: f32 to f16
252 // CHECK-NEXT: = llvm.fptrunc {{.*}} : f64 to f16
253   %1 = arith.truncf %arg1: f64 to f16
254 // CHECK-NEXT: = llvm.fptrunc {{.*}} : f64 to f32
255   %2 = arith.truncf %arg1: f64 to f32
256   return
259 // Checking conversion of integer types to floating point.
260 // CHECK-LABEL: @fptrunc
261 func @fptrunc_vector(%arg0 : vector<2xf32>, %arg1 : vector<2xf64>) {
262 // CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf32> to vector<2xf16>
263   %0 = arith.truncf %arg0: vector<2xf32> to vector<2xf16>
264 // CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf64> to vector<2xf16>
265   %1 = arith.truncf %arg1: vector<2xf64> to vector<2xf16>
266 // CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf64> to vector<2xf32>
267   %2 = arith.truncf %arg1: vector<2xf64> to vector<2xf32>
268   return
271 // Check sign and zero extension and truncation of integers.
272 // CHECK-LABEL: @integer_extension_and_truncation
273 func @integer_extension_and_truncation(%arg0 : i3) {
274 // CHECK-NEXT: = llvm.sext %arg0 : i3 to i6
275   %0 = arith.extsi %arg0 : i3 to i6
276 // CHECK-NEXT: = llvm.zext %arg0 : i3 to i6
277   %1 = arith.extui %arg0 : i3 to i6
278 // CHECK-NEXT: = llvm.trunc %arg0 : i3 to i2
279    %2 = arith.trunci %arg0 : i3 to i2
280   return
283 // CHECK-LABEL: func @fcmp(%arg0: f32, %arg1: f32) {
284 func @fcmp(f32, f32) -> () {
285 ^bb0(%arg0: f32, %arg1: f32):
286   // CHECK:      llvm.fcmp "oeq" %arg0, %arg1 : f32
287   // CHECK-NEXT: llvm.fcmp "ogt" %arg0, %arg1 : f32
288   // CHECK-NEXT: llvm.fcmp "oge" %arg0, %arg1 : f32
289   // CHECK-NEXT: llvm.fcmp "olt" %arg0, %arg1 : f32
290   // CHECK-NEXT: llvm.fcmp "ole" %arg0, %arg1 : f32
291   // CHECK-NEXT: llvm.fcmp "one" %arg0, %arg1 : f32
292   // CHECK-NEXT: llvm.fcmp "ord" %arg0, %arg1 : f32
293   // CHECK-NEXT: llvm.fcmp "ueq" %arg0, %arg1 : f32
294   // CHECK-NEXT: llvm.fcmp "ugt" %arg0, %arg1 : f32
295   // CHECK-NEXT: llvm.fcmp "uge" %arg0, %arg1 : f32
296   // CHECK-NEXT: llvm.fcmp "ult" %arg0, %arg1 : f32
297   // CHECK-NEXT: llvm.fcmp "ule" %arg0, %arg1 : f32
298   // CHECK-NEXT: llvm.fcmp "une" %arg0, %arg1 : f32
299   // CHECK-NEXT: llvm.fcmp "uno" %arg0, %arg1 : f32
300   // CHECK-NEXT: return
301   %1 = arith.cmpf oeq, %arg0, %arg1 : f32
302   %2 = arith.cmpf ogt, %arg0, %arg1 : f32
303   %3 = arith.cmpf oge, %arg0, %arg1 : f32
304   %4 = arith.cmpf olt, %arg0, %arg1 : f32
305   %5 = arith.cmpf ole, %arg0, %arg1 : f32
306   %6 = arith.cmpf one, %arg0, %arg1 : f32
307   %7 = arith.cmpf ord, %arg0, %arg1 : f32
308   %8 = arith.cmpf ueq, %arg0, %arg1 : f32
309   %9 = arith.cmpf ugt, %arg0, %arg1 : f32
310   %10 = arith.cmpf uge, %arg0, %arg1 : f32
311   %11 = arith.cmpf ult, %arg0, %arg1 : f32
312   %12 = arith.cmpf ule, %arg0, %arg1 : f32
313   %13 = arith.cmpf une, %arg0, %arg1 : f32
314   %14 = arith.cmpf uno, %arg0, %arg1 : f32
316   return
319 // -----
321 // CHECK-LABEL: @index_vector
322 func @index_vector(%arg0: vector<4xindex>) {
323   // CHECK: %[[CST:.*]] = llvm.mlir.constant(dense<[0, 1, 2, 3]> : vector<4xindex>) : vector<4xi64>
324   %0 = arith.constant dense<[0, 1, 2, 3]> : vector<4xindex>
325   // CHECK: %[[V:.*]] = llvm.add %{{.*}}, %[[CST]] : vector<4xi64>
326   %1 = arith.addi %arg0, %0 : vector<4xindex>
327   std.return
330 // -----
332 // CHECK-LABEL: @bitcast_1d
333 func @bitcast_1d(%arg0: vector<2xf32>) {
334   // CHECK: llvm.bitcast %{{.*}} : vector<2xf32> to vector<2xi32>
335   arith.bitcast %arg0 : vector<2xf32> to vector<2xi32>
336   return
339 // -----
341 // CHECK-LABEL: func @cmpf_2dvector(
342 func @cmpf_2dvector(%arg0 : vector<4x3xf32>, %arg1 : vector<4x3xf32>) {
343   // CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
344   // CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
345   // CHECK: %[[EXTRACT1:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.array<4 x vector<3xf32>>
346   // CHECK: %[[EXTRACT2:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.array<4 x vector<3xf32>>
347   // CHECK: %[[CMP:.*]] = llvm.fcmp "olt" %[[EXTRACT1]], %[[EXTRACT2]] : vector<3xf32>
348   // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[CMP]], %2[0] : !llvm.array<4 x vector<3xi1>>
349   %0 = arith.cmpf olt, %arg0, %arg1 : vector<4x3xf32>
350   std.return
353 // -----
355 // CHECK-LABEL: func @cmpi_0dvector(
356 func @cmpi_0dvector(%arg0 : vector<i32>, %arg1 : vector<i32>) {
357   // CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
358   // CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
359   // CHECK: %[[CMP:.*]] = llvm.icmp "ult" %[[ARG0]], %[[ARG1]] : vector<1xi32>
360   %0 = arith.cmpi ult, %arg0, %arg1 : vector<i32>
361   std.return
364 // -----
366 // CHECK-LABEL: func @cmpi_2dvector(
367 func @cmpi_2dvector(%arg0 : vector<4x3xi32>, %arg1 : vector<4x3xi32>) {
368   // CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
369   // CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
370   // CHECK: %[[EXTRACT1:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.array<4 x vector<3xi32>>
371   // CHECK: %[[EXTRACT2:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.array<4 x vector<3xi32>>
372   // CHECK: %[[CMP:.*]] = llvm.icmp "ult" %[[EXTRACT1]], %[[EXTRACT2]] : vector<3xi32>
373   // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[CMP]], %2[0] : !llvm.array<4 x vector<3xi1>>
374   %0 = arith.cmpi ult, %arg0, %arg1 : vector<4x3xi32>
375   std.return