xref: /llvm-project/mlir/test/Dialect/Arith/emulate-wide-int.mlir (revision 9816edc9f3ce198d41e364dd3467caa839a0c220)
1// RUN: mlir-opt --arith-emulate-wide-int="widest-int-supported=32" %s | FileCheck %s
2
3// Expect no conversions, i32 is supported.
4// CHECK-LABEL: func @addi_same_i32
5// CHECK-SAME:    ([[ARG:%.+]]: i32) -> i32
6// CHECK-NEXT:    [[X:%.+]] = arith.addi [[ARG]], [[ARG]] : i32
7// CHECK-NEXT:    return [[X]] : i32
8func.func @addi_same_i32(%a : i32) -> i32 {
9    %x = arith.addi %a, %a : i32
10    return %x : i32
11}
12
13// Expect no conversions, index is not sized.
14// CHECK-LABEL: func @addi_same_index
15// CHECK-SAME:    ([[ARG:%.+]]: index) -> index
16// CHECK-NEXT:    [[X:%.+]] = arith.addi [[ARG]], [[ARG]] : index
17// CHECK-NEXT:    return [[X]] : index
18func.func @addi_same_index(%a : index) -> index {
19    %x = arith.addi %a, %a : index
20    return %x : index
21}
22
23// Expect no conversions, f64 is not an integer type.
24// CHECK-LABEL: func @identity_f64
25// CHECK-SAME:    ([[ARG:%.+]]: f64) -> f64
26// CHECK-NEXT:    return [[ARG]] : f64
27func.func @identity_f64(%a : f64) -> f64 {
28    return %a : f64
29}
30
31// Expect no conversions, i32 is supported.
32// CHECK-LABEL: func @addi_same_vector_i32
33// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> vector<2xi32>
34// CHECK-NEXT:    [[X:%.+]] = arith.addi [[ARG]], [[ARG]] : vector<2xi32>
35// CHECK-NEXT:    return [[X]] : vector<2xi32>
36func.func @addi_same_vector_i32(%a : vector<2xi32>) -> vector<2xi32> {
37    %x = arith.addi %a, %a : vector<2xi32>
38    return %x : vector<2xi32>
39}
40
41// CHECK-LABEL: func @identity_scalar
42// CHECK-SAME:     ([[ARG:%.+]]: vector<2xi32>) -> vector<2xi32>
43// CHECK-NEXT:     return [[ARG]] : vector<2xi32>
44func.func @identity_scalar(%x : i64) -> i64 {
45    return %x : i64
46}
47
48// CHECK-LABEL: func @identity_vector
49// CHECK-SAME:     ([[ARG:%.+]]: vector<4x2xi32>) -> vector<4x2xi32>
50// CHECK-NEXT:     return [[ARG]] : vector<4x2xi32>
51func.func @identity_vector(%x : vector<4xi64>) -> vector<4xi64> {
52    return %x : vector<4xi64>
53}
54
55// CHECK-LABEL: func @identity_vector2d
56// CHECK-SAME:     ([[ARG:%.+]]: vector<3x4x2xi32>) -> vector<3x4x2xi32>
57// CHECK-NEXT:     return [[ARG]] : vector<3x4x2xi32>
58func.func @identity_vector2d(%x : vector<3x4xi64>) -> vector<3x4xi64> {
59    return %x : vector<3x4xi64>
60}
61
62// CHECK-LABEL: func @call
63// CHECK-SAME:     ([[ARG:%.+]]: vector<4x2xi32>) -> vector<4x2xi32>
64// CHECK-NEXT:     [[RES:%.+]] = call @identity_vector([[ARG]]) : (vector<4x2xi32>) -> vector<4x2xi32>
65// CHECK-NEXT:     return [[RES]] : vector<4x2xi32>
66func.func @call(%a : vector<4xi64>) -> vector<4xi64> {
67    %res = func.call @identity_vector(%a) : (vector<4xi64>) -> vector<4xi64>
68    return %res : vector<4xi64>
69}
70
71// CHECK-LABEL: func @constant_scalar
72// CHECK-SAME:     () -> vector<2xi32>
73// CHECK-NEXT:     [[C0:%.+]] = arith.constant dense<0> : vector<2xi32>
74// CHECK-NEXT:     [[C1:%.+]] = arith.constant dense<[0, 1]> : vector<2xi32>
75// CHECK-NEXT:     [[C2:%.+]] = arith.constant dense<[-7, -1]> : vector<2xi32>
76// CHECK-NEXT:     return [[C0]] : vector<2xi32>
77func.func @constant_scalar() -> i64 {
78    %c0 = arith.constant 0 : i64
79    %c1 = arith.constant 4294967296 : i64
80    %c2 = arith.constant -7 : i64
81    return %c0 : i64
82}
83
84// CHECK-LABEL: func @constant_vector
85// CHECK-SAME:     () -> vector<3x2xi32>
86// CHECK-NEXT:     [[C0:%.+]] = arith.constant dense
87// CHECK-SAME{LITERAL}:                             <[[0, 1], [0, 1], [0, 1]]> : vector<3x2xi32>
88// CHECK-NEXT:     [[C1:%.+]] = arith.constant dense
89// CHECK-SAME{LITERAL}:                             <[[0, 0], [1, 0], [-2, -1]]> : vector<3x2xi32>
90// CHECK-NEXT:     return [[C0]] : vector<3x2xi32>
91func.func @constant_vector() -> vector<3xi64> {
92    %c0 = arith.constant dense<4294967296> : vector<3xi64>
93    %c1 = arith.constant dense<[0, 1, -2]> : vector<3xi64>
94    return %c0 : vector<3xi64>
95}
96
97// CHECK-LABEL: func @addi_scalar_a_b
98// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
99// CHECK-NEXT:    [[LOW0:%.+]]   = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
100// CHECK-NEXT:    [[HIGH0:%.+]]  = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
101// CHECK-NEXT:    [[LOW1:%.+]]   = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
102// CHECK-NEXT:    [[HIGH1:%.+]]  = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
103// CHECK-NEXT:    [[SUM_L:%.+]], [[CB:%.+]] = arith.addui_extended [[LOW0]], [[LOW1]] : i32, i1
104// CHECK-NEXT:    [[CARRY:%.+]]  = arith.extui [[CB]] : i1 to i32
105// CHECK-NEXT:    [[SUM_H0:%.+]] = arith.addi [[CARRY]], [[HIGH0]] : i32
106// CHECK-NEXT:    [[SUM_H1:%.+]] = arith.addi [[SUM_H0]], [[HIGH1]] : i32
107// CHECK:         [[INS0:%.+]]   = vector.insert [[SUM_L]], {{%.+}} [0] : i32 into vector<2xi32>
108// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert [[SUM_H1]], [[INS0]] [1] : i32 into vector<2xi32>
109// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
110func.func @addi_scalar_a_b(%a : i64, %b : i64) -> i64 {
111    %x = arith.addi %a, %b : i64
112    return %x : i64
113}
114
115// CHECK-LABEL: func @addi_vector_a_b
116// CHECK-SAME:    ([[ARG0:%.+]]: vector<4x2xi32>, [[ARG1:%.+]]: vector<4x2xi32>) -> vector<4x2xi32>
117// CHECK-NEXT:    [[LOW0:%.+]]   = vector.extract_strided_slice [[ARG0]] {offsets = [0, 0], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
118// CHECK-NEXT:    [[HIGH0:%.+]]  = vector.extract_strided_slice [[ARG0]] {offsets = [0, 1], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
119// CHECK-NEXT:    [[LOW1:%.+]]   = vector.extract_strided_slice [[ARG1]] {offsets = [0, 0], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
120// CHECK-NEXT:    [[HIGH1:%.+]]  = vector.extract_strided_slice [[ARG1]] {offsets = [0, 1], sizes = [4, 1], strides = [1, 1]} : vector<4x2xi32> to vector<4x1xi32>
121// CHECK-NEXT:    [[SUM_L:%.+]], [[CB:%.+]] = arith.addui_extended [[LOW0]], [[LOW1]] : vector<4x1xi32>, vector<4x1xi1>
122// CHECK-NEXT:    [[CARRY:%.+]]  = arith.extui [[CB]] : vector<4x1xi1> to vector<4x1xi32>
123// CHECK-NEXT:    [[SUM_H0:%.+]] = arith.addi [[CARRY]], [[HIGH0]] : vector<4x1xi32>
124// CHECK-NEXT:    [[SUM_H1:%.+]] = arith.addi [[SUM_H0]], [[HIGH1]] : vector<4x1xi32>
125// CHECK:         [[INS0:%.+]]   = vector.insert_strided_slice [[SUM_L]], {{%.+}} {offsets = [0, 0], strides = [1, 1]} : vector<4x1xi32> into vector<4x2xi32>
126// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert_strided_slice [[SUM_H1]], [[INS0]] {offsets = [0, 1], strides = [1, 1]} : vector<4x1xi32> into vector<4x2xi32>
127// CHECK-NEXT:    return [[INS1]] : vector<4x2xi32>
128func.func @addi_vector_a_b(%a : vector<4xi64>, %b : vector<4xi64>) -> vector<4xi64> {
129    %x = arith.addi %a, %b : vector<4xi64>
130    return %x : vector<4xi64>
131}
132
133// CHECK-LABEL: func.func @cmpi_eq_scalar
134// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
135// CHECK-NEXT:    [[LHSLOW:%.+]]  = vector.extract [[LHS]][0] : i32 from vector<2xi32>
136// CHECK-NEXT:    [[LHSHIGH:%.+]] = vector.extract [[LHS]][1] : i32 from vector<2xi32>
137// CHECK-NEXT:    [[RHSLOW:%.+]]  = vector.extract [[RHS]][0] : i32 from vector<2xi32>
138// CHECK-NEXT:    [[RHSHIGH:%.+]] = vector.extract [[RHS]][1] : i32 from vector<2xi32>
139// CHECK-NEXT:    [[CLOW:%.+]]  = arith.cmpi eq, [[LHSLOW]], [[RHSLOW]] : i32
140// CHECK-NEXT:    [[CHIGH:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
141// CHECK-NEXT:    [[RES:%.+]]   = arith.andi [[CLOW]], [[CHIGH]] : i1
142// CHECK:         return [[RES]] : i1
143func.func @cmpi_eq_scalar(%a : i64, %b : i64) -> i1 {
144    %r = arith.cmpi eq, %a, %b : i64
145    return %r : i1
146}
147
148// CHECK-LABEL: func.func @cmpi_eq_vector
149// CHECK-SAME:    ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3xi1>
150// CHECK-NEXT:    [[LOW0:%.+]]  = vector.extract_strided_slice [[ARG0]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
151// CHECK-NEXT:    [[HIGH0:%.+]] = vector.extract_strided_slice [[ARG0]] {offsets = [0, 1], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
152// CHECK-NEXT:    [[LOW1:%.+]]  = vector.extract_strided_slice [[ARG1]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
153// CHECK-NEXT:    [[HIGH1:%.+]] = vector.extract_strided_slice [[ARG1]] {offsets = [0, 1], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
154// CHECK-NEXT:    [[CLOW:%.+]]  = arith.cmpi eq, [[LOW0]], [[LOW1]] : vector<3x1xi32>
155// CHECK-NEXT:    [[CHIGH:%.+]] = arith.cmpi eq, [[HIGH0]], [[HIGH1]] : vector<3x1xi32>
156// CHECK-NEXT:    [[RES:%.+]]   = arith.andi [[CLOW]], [[CHIGH]] : vector<3x1xi1>
157// CHECK-NEXT:    [[CAST:%.+]]  = vector.shape_cast [[RES]] : vector<3x1xi1> to vector<3xi1>
158// CHECK:         return [[CAST]] : vector<3xi1>
159func.func @cmpi_eq_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi1> {
160    %r = arith.cmpi eq, %a, %b : vector<3xi64>
161    return %r : vector<3xi1>
162}
163
164// CHECK-LABEL: func.func @cmpi_ne_scalar
165// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
166// CHECK-NEXT:    [[LHSLOW:%.+]]  = vector.extract [[LHS]][0] : i32 from vector<2xi32>
167// CHECK-NEXT:    [[LHSHIGH:%.+]] = vector.extract [[LHS]][1] : i32 from vector<2xi32>
168// CHECK-NEXT:    [[RHSLOW:%.+]]  = vector.extract [[RHS]][0] : i32 from vector<2xi32>
169// CHECK-NEXT:    [[RHSHIGH:%.+]] = vector.extract [[RHS]][1] : i32 from vector<2xi32>
170// CHECK-NEXT:    [[CLOW:%.+]]  = arith.cmpi ne, [[LHSLOW]], [[RHSLOW]] : i32
171// CHECK-NEXT:    [[CHIGH:%.+]] = arith.cmpi ne, [[LHSHIGH]], [[RHSHIGH]] : i32
172// CHECK-NEXT:    [[RES:%.+]]   = arith.ori [[CLOW]], [[CHIGH]] : i1
173// CHECK:         return [[RES]] : i1
174func.func @cmpi_ne_scalar(%a : i64, %b : i64) -> i1 {
175    %r = arith.cmpi ne, %a, %b : i64
176    return %r : i1
177}
178
179// CHECK-LABEL: func.func @cmpi_ne_vector
180// CHECK-SAME:    ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3xi1>
181// CHECK:         [[CLOW:%.+]]  = arith.cmpi ne, {{%.+}}, {{%.+}} : vector<3x1xi32>
182// CHECK-NEXT:    [[CHIGH:%.+]] = arith.cmpi ne, {{%.+}}, {{%.+}} : vector<3x1xi32>
183// CHECK-NEXT:    [[RES:%.+]]   = arith.ori [[CLOW]], [[CHIGH]] : vector<3x1xi1>
184// CHECK-NEXT:    [[CAST:%.+]]  = vector.shape_cast [[RES]] : vector<3x1xi1> to vector<3xi1>
185// CHECK:         return [[CAST]] : vector<3xi1>
186func.func @cmpi_ne_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi1> {
187    %r = arith.cmpi ne, %a, %b : vector<3xi64>
188    return %r : vector<3xi1>
189}
190
191// CHECK-LABEL: func.func @cmpi_sge_scalar
192// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
193// CHECK-NEXT:    [[LHSLOW:%.+]]  = vector.extract [[LHS]][0] : i32 from vector<2xi32>
194// CHECK-NEXT:    [[LHSHIGH:%.+]] = vector.extract [[LHS]][1] : i32 from vector<2xi32>
195// CHECK-NEXT:    [[RHSLOW:%.+]]  = vector.extract [[RHS]][0] : i32 from vector<2xi32>
196// CHECK-NEXT:    [[RHSHIGH:%.+]] = vector.extract [[RHS]][1] : i32 from vector<2xi32>
197// CHECK-NEXT:    [[CLOW:%.+]]   = arith.cmpi uge, [[LHSLOW]], [[RHSLOW]] : i32
198// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi sge, [[LHSHIGH]], [[RHSHIGH]] : i32
199// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
200// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
201// CHECK:         return [[RES]] : i1
202func.func @cmpi_sge_scalar(%a : i64, %b : i64) -> i1 {
203    %r = arith.cmpi sge, %a, %b : i64
204    return %r : i1
205}
206
207// CHECK-LABEL: func.func @cmpi_sge_vector
208// CHECK-SAME:    ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3xi1>
209// CHECK:         [[CLOW:%.+]]   = arith.cmpi uge, {{%.+}}, {{%.+}} : vector<3x1xi32>
210// CHECK:         [[CHIGH:%.+]]  = arith.cmpi sge, {{%.+}}, {{%.+}} : vector<3x1xi32>
211// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, {{%.+}}, {{%.+}} : vector<3x1xi32>
212// CHECK-NEXT:    [[RES:%.+]]    = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : vector<3x1xi1>
213// CHECK-NEXT:    [[CAST:%.+]]   = vector.shape_cast [[RES]] : vector<3x1xi1> to vector<3xi1>
214// CHECK:         return [[CAST]] : vector<3xi1>
215func.func @cmpi_sge_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi1> {
216    %r = arith.cmpi sge, %a, %b : vector<3xi64>
217    return %r : vector<3xi1>
218}
219
220// CHECK-LABEL: func.func @cmpi_sgt_scalar
221// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
222// CHECK:         [[CLOW:%.+]]   = arith.cmpi ugt, {{%.+}}, {{%.+}} : i32
223// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi sgt, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
224// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
225// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
226// CHECK:         return [[RES]] : i1
227func.func @cmpi_sgt_scalar(%a : i64, %b : i64) -> i1 {
228    %r = arith.cmpi sgt, %a, %b : i64
229    return %r : i1
230}
231
232// CHECK-LABEL: func.func @cmpi_sle_scalar
233// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
234// CHECK:         [[CLOW:%.+]]   = arith.cmpi ule, {{%.+}}, {{%.+}} : i32
235// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi sle, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
236// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
237// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
238// CHECK:         return [[RES]] : i1
239func.func @cmpi_sle_scalar(%a : i64, %b : i64) -> i1 {
240    %r = arith.cmpi sle, %a, %b : i64
241    return %r : i1
242}
243
244// CHECK-LABEL: func.func @cmpi_slt_scalar
245// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
246// CHECK:         [[CLOW:%.+]]   = arith.cmpi ult, {{%.+}}, {{%.+}} : i32
247// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi slt, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
248// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
249// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
250// CHECK:         return [[RES]] : i1
251func.func @cmpi_slt_scalar(%a : i64, %b : i64) -> i1 {
252    %r = arith.cmpi slt, %a, %b : i64
253    return %r : i1
254}
255
256// CHECK-LABEL: func.func @cmpi_uge_scalar
257// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
258// CHECK:         [[CLOW:%.+]]   = arith.cmpi uge, {{%.+}}, {{%.+}} : i32
259// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi uge, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
260// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
261// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
262// CHECK:         return [[RES]] : i1
263func.func @cmpi_uge_scalar(%a : i64, %b : i64) -> i1 {
264    %r = arith.cmpi uge, %a, %b : i64
265    return %r : i1
266}
267
268// CHECK-LABEL: func.func @cmpi_ugt_scalar
269// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
270// CHECK:         [[CLOW:%.+]]   = arith.cmpi ugt, {{%.+}}, {{%.+}} : i32
271// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi ugt, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
272// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
273// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
274// CHECK:         return [[RES]] : i1
275func.func @cmpi_ugt_scalar(%a : i64, %b : i64) -> i1 {
276    %r = arith.cmpi ugt, %a, %b : i64
277    return %r : i1
278}
279
280// CHECK-LABEL: func.func @cmpi_ule_scalar
281// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
282// CHECK:         [[CLOW:%.+]]   = arith.cmpi ule, {{%.+}}, {{%.+}} : i32
283// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi ule, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
284// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
285// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
286// CHECK:         return [[RES]] : i1
287func.func @cmpi_ule_scalar(%a : i64, %b : i64) -> i1 {
288    %r = arith.cmpi ule, %a, %b : i64
289    return %r : i1
290}
291
292// CHECK-LABEL: func.func @cmpi_ult_scalar
293// CHECK-SAME:    ([[LHS:%.+]]: vector<2xi32>, [[RHS:%.+]]: vector<2xi32>)
294// CHECK:         [[CLOW:%.+]]   = arith.cmpi ult, {{%.+}}, {{%.+}} : i32
295// CHECK-NEXT:    [[CHIGH:%.+]]  = arith.cmpi ult, [[LHSHIGH:%.+]], [[RHSHIGH:%.+]] : i32
296// CHECK-NEXT:    [[HIGHEQ:%.+]] = arith.cmpi eq, [[LHSHIGH]], [[RHSHIGH]] : i32
297// CHECK-NEXT:    [[RES:%.+]]   = arith.select [[HIGHEQ]], [[CLOW]], [[CHIGH]] : i1
298// CHECK:         return [[RES]] : i1
299func.func @cmpi_ult_scalar(%a : i64, %b : i64) -> i1 {
300    %r = arith.cmpi ult, %a, %b : i64
301    return %r : i1
302}
303
304// CHECK-LABEL: func @extsi_scalar
305// CHECK-SAME:    ([[ARG:%.+]]: i16) -> vector<2xi32>
306// CHECK-NEXT:    [[EXT:%.+]]  = arith.extsi [[ARG]] : i16 to i32
307// CHECK-NEXT:    [[SZ:%.+]]   = arith.constant 0 : i32
308// CHECK-NEXT:    [[SB:%.+]]   = arith.cmpi slt, [[EXT]], [[SZ]] : i32
309// CHECK-NEXT:    [[SV:%.+]]   = arith.extsi [[SB]] : i1 to i32
310// CHECK-NEXT:    [[VZ:%.+]]   = arith.constant dense<0> : vector<2xi32>
311// CHECK-NEXT:    [[INS0:%.+]] = vector.insert [[EXT]], [[VZ]] [0] : i32 into vector<2xi32>
312// CHECK-NEXT:    [[INS1:%.+]] = vector.insert [[SV]], [[INS0]] [1] : i32 into vector<2xi32>
313// CHECK:         return [[INS1]] : vector<2xi32>
314func.func @extsi_scalar(%a : i16) -> i64 {
315    %r = arith.extsi %a : i16 to i64
316    return %r : i64
317}
318
319// CHECK-LABEL: func @extsi_vector
320// CHECK-SAME:    ([[ARG:%.+]]: vector<3xi16>) -> vector<3x2xi32>
321// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[ARG]] : vector<3xi16> to vector<3x1xi16>
322// CHECK-NEXT:    [[EXT:%.+]]   = arith.extsi [[SHAPE]] : vector<3x1xi16> to vector<3x1xi32>
323// CHECK-NEXT:    [[CSTE:%.+]]  = arith.constant dense<0> : vector<3x1xi32>
324// CHECK-NEXT:    [[CMP:%.+]]   = arith.cmpi slt, [[EXT]], [[CSTE]] : vector<3x1xi32>
325// CHECK-NEXT:    [[HIGH:%.+]]  = arith.extsi [[CMP]] : vector<3x1xi1> to vector<3x1xi32>
326// CHECK-NEXT:    [[CSTZ:%.+]]  = arith.constant dense<0> : vector<3x2xi32>
327// CHECK-NEXT:    [[INS0:%.+]]  = vector.insert_strided_slice [[EXT]], [[CSTZ]] {offsets = [0, 0], strides = [1, 1]} : vector<3x1xi32> into vector<3x2xi32>
328// CHECK-NEXT:    [[INS1:%.+]]  = vector.insert_strided_slice [[HIGH]], [[INS0]] {offsets = [0, 1], strides = [1, 1]} : vector<3x1xi32> into vector<3x2xi32>
329// CHECK-NEXT:    return [[INS1]] : vector<3x2xi32>
330func.func @extsi_vector(%a : vector<3xi16>) -> vector<3xi64> {
331    %r = arith.extsi %a : vector<3xi16> to vector<3xi64>
332    return %r : vector<3xi64>
333}
334
335// CHECK-LABEL: func @extui_scalar1
336// CHECK-SAME:    ([[ARG:%.+]]: i16) -> vector<2xi32>
337// CHECK-NEXT:    [[EXT:%.+]]  = arith.extui [[ARG]] : i16 to i32
338// CHECK-NEXT:    [[VZ:%.+]]   = arith.constant dense<0> : vector<2xi32>
339// CHECK-NEXT:    [[INS0:%.+]] = vector.insert [[EXT]], [[VZ]] [0] : i32 into vector<2xi32>
340// CHECK:         return [[INS0]] : vector<2xi32>
341func.func @extui_scalar1(%a : i16) -> i64 {
342    %r = arith.extui %a : i16 to i64
343    return %r : i64
344}
345
346// CHECK-LABEL: func @extui_scalar2
347// CHECK-SAME:    ([[ARG:%.+]]: i32) -> vector<2xi32>
348// CHECK-NEXT:    [[VZ:%.+]]   = arith.constant dense<0> : vector<2xi32>
349// CHECK-NEXT:    [[INS0:%.+]] = vector.insert [[ARG]], [[VZ]] [0] : i32 into vector<2xi32>
350// CHECK:         return [[INS0]] : vector<2xi32>
351func.func @extui_scalar2(%a : i32) -> i64 {
352    %r = arith.extui %a : i32 to i64
353    return %r : i64
354}
355
356// CHECK-LABEL: func @extui_vector
357// CHECK-SAME:    ([[ARG:%.+]]: vector<3xi16>) -> vector<3x2xi32>
358// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[ARG]] : vector<3xi16> to vector<3x1xi16>
359// CHECK-NEXT:    [[EXT:%.+]]   = arith.extui [[SHAPE]] : vector<3x1xi16> to vector<3x1xi32>
360// CHECK-NEXT:    [[CST:%.+]]   = arith.constant dense<0> : vector<3x2xi32>
361// CHECK-NEXT:    [[INS0:%.+]]  = vector.insert_strided_slice [[EXT]], [[CST]] {offsets = [0, 0], strides = [1, 1]} : vector<3x1xi32> into vector<3x2xi32>
362// CHECK:         return [[INS0]] : vector<3x2xi32>
363func.func @extui_vector(%a : vector<3xi16>) -> vector<3xi64> {
364    %r = arith.extui %a : vector<3xi16> to vector<3xi64>
365    return %r : vector<3xi64>
366}
367
368// CHECK-LABEL: func @index_cast_int_to_index_scalar
369// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> index
370// CHECK-NEXT:    [[EXT:%.+]]  = vector.extract [[ARG]][0] : i32 from vector<2xi32>
371// CHECK-NEXT:    [[RES:%.+]]  = arith.index_cast [[EXT]] : i32 to index
372// CHECK-NEXT:    return [[RES]] : index
373func.func @index_cast_int_to_index_scalar(%a : i64) -> index {
374    %r = arith.index_cast %a : i64 to index
375    return %r : index
376}
377
378// CHECK-LABEL: func @index_cast_int_to_index_vector
379// CHECK-SAME:    ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xindex>
380// CHECK-NEXT:    [[EXT:%.+]]   = vector.extract_strided_slice [[ARG]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
381// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[EXT]] : vector<3x1xi32> to vector<3xi32>
382// CHECK-NEXT:    [[RES:%.+]]   = arith.index_cast [[SHAPE]] : vector<3xi32> to vector<3xindex>
383// CHECK-NEXT:    return [[RES]] : vector<3xindex>
384func.func @index_cast_int_to_index_vector(%a : vector<3xi64>) -> vector<3xindex> {
385    %r = arith.index_cast %a : vector<3xi64> to vector<3xindex>
386    return %r : vector<3xindex>
387}
388
389// CHECK-LABEL: func @index_castui_int_to_index_scalar
390// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> index
391// CHECK-NEXT:    [[EXT:%.+]]  = vector.extract [[ARG]][0] : i32 from vector<2xi32>
392// CHECK-NEXT:    [[RES:%.+]]  = arith.index_castui [[EXT]] : i32 to index
393// CHECK-NEXT:    return [[RES]] : index
394func.func @index_castui_int_to_index_scalar(%a : i64) -> index {
395    %r = arith.index_castui %a : i64 to index
396    return %r : index
397}
398
399// CHECK-LABEL: func @index_castui_int_to_index_vector
400// CHECK-SAME:    ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xindex>
401// CHECK-NEXT:    [[EXT:%.+]]   = vector.extract_strided_slice [[ARG]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
402// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[EXT]] : vector<3x1xi32> to vector<3xi32>
403// CHECK-NEXT:    [[RES:%.+]]   = arith.index_castui [[SHAPE]] : vector<3xi32> to vector<3xindex>
404// CHECK-NEXT:    return [[RES]] : vector<3xindex>
405func.func @index_castui_int_to_index_vector(%a : vector<3xi64>) -> vector<3xindex> {
406    %r = arith.index_castui %a : vector<3xi64> to vector<3xindex>
407    return %r : vector<3xindex>
408}
409
410// CHECK-LABEL: func @index_cast_index_to_int_scalar
411// CHECK-SAME:    ([[ARG:%.+]]: index) -> vector<2xi32>
412// CHECK-NEXT:    [[CAST:%.+]]  = arith.index_cast [[ARG]] : index to i32
413// CHECK-NEXT:    [[C0I32:%.+]] = arith.constant 0 : i32
414// CHECK-NEXT:    [[NEG:%.+]]   = arith.cmpi slt, [[CAST]], [[C0I32]] : i32
415// CHECK-NEXT:    [[EXT:%.+]]   = arith.extsi [[NEG]] : i1 to i32
416// CHECK-NEXT:    [[VZ:%.+]]    = arith.constant dense<0> : vector<2xi32>
417// CHECK-NEXT:    [[INS0:%.+]]  = vector.insert [[CAST]], [[VZ]] [0] : i32 into vector<2xi32>
418// CHECK-NEXT:    [[INS1:%.+]]  = vector.insert [[EXT]], [[INS0]] [1] : i32 into vector<2xi32>
419// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
420func.func @index_cast_index_to_int_scalar(%a : index) -> i64 {
421    %r = arith.index_cast %a : index to i64
422    return %r : i64
423}
424
425// CHECK-LABEL: func @index_cast_index_to_int_vector
426// CHECK-SAME:    ([[ARG:%.+]]: vector<3xindex>) -> vector<3x2xi32>
427// CHECK-NEXT:    arith.index_cast [[ARG]] : vector<3xindex> to vector<3xi32>
428// CHECK-NEXT:    vector.shape_cast
429// CHECK-NEXT:    arith.constant dense<0> : vector<3x1xi32>
430// CHECK-NEXT:    arith.cmpi slt
431// CHECK-NEXT:    arith.extsi
432// CHECK-NEXT:    arith.constant dense<0> : vector<3x2xi32>
433// CHECK-NEXT:    vector.insert_strided_slice
434// CHECK-NEXT:    vector.insert_strided_slice
435// CHECK-NEXT:    return {{%.+}} : vector<3x2xi32>
436func.func @index_cast_index_to_int_vector(%a : vector<3xindex>) -> vector<3xi64> {
437    %r = arith.index_cast %a : vector<3xindex> to vector<3xi64>
438    return %r : vector<3xi64>
439}
440
441// CHECK-LABEL: func @index_castui_index_to_int_scalar
442// CHECK-SAME:    ([[ARG:%.+]]: index) -> vector<2xi32>
443// CHECK-NEXT:    [[CAST:%.+]]  = arith.index_castui [[ARG]] : index to i32
444// CHECK-NEXT:    [[VZ:%.+]]    = arith.constant dense<0> : vector<2xi32>
445// CHECK-NEXT:    [[RES:%.+]]   = vector.insert [[CAST]], [[VZ]] [0] : i32 into vector<2xi32>
446// CHECK-NEXT:    return [[RES]] : vector<2xi32>
447func.func @index_castui_index_to_int_scalar(%a : index) -> i64 {
448    %r = arith.index_castui %a : index to i64
449    return %r : i64
450}
451
452// CHECK-LABEL: func @index_castui_index_to_int_vector
453// CHECK-SAME:    ([[ARG:%.+]]: vector<3xindex>) -> vector<3x2xi32>
454// CHECK-NEXT:    [[CAST:%.+]]  = arith.index_castui [[ARG]] : vector<3xindex> to vector<3xi32>
455// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[CAST]] : vector<3xi32> to vector<3x1xi32>
456// CHECK-NEXT:    [[CST:%.+]]   = arith.constant dense<0> : vector<3x2xi32>
457// CHECK-NEXT:    [[RES:%.+]]   = vector.insert_strided_slice [[SHAPE]], [[CST]] {offsets = [0, 0], strides = [1, 1]} : vector<3x1xi32> into vector<3x2xi32>
458// CHECK-NEXT:    return [[RES]] : vector<3x2xi32>
459func.func @index_castui_index_to_int_vector(%a : vector<3xindex>) -> vector<3xi64> {
460    %r = arith.index_castui %a : vector<3xindex> to vector<3xi64>
461    return %r : vector<3xi64>
462}
463
464// CHECK-LABEL: func @trunci_scalar1
465// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> i32
466// CHECK-NEXT:    [[EXT:%.+]] = vector.extract [[ARG]][0] : i32 from vector<2xi32>
467// CHECK-NEXT:    return [[EXT]] : i32
468func.func @trunci_scalar1(%a : i64) -> i32 {
469    %b = arith.trunci %a : i64 to i32
470    return %b : i32
471}
472
473// CHECK-LABEL: func @trunci_scalar2
474// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> i16
475// CHECK-NEXT:    [[EXTR:%.+]] = vector.extract [[ARG]][0] : i32 from vector<2xi32>
476// CHECK-NEXT:    [[TRNC:%.+]] = arith.trunci [[EXTR]] : i32 to i16
477// CHECK-NEXT:    return [[TRNC]] : i16
478func.func @trunci_scalar2(%a : i64) -> i16 {
479    %b = arith.trunci %a : i64 to i16
480    return %b : i16
481}
482
483// CHECK-LABEL: func @trunci_vector
484// CHECK-SAME:    ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xi16>
485// CHECK-NEXT:    [[EXTR:%.+]]  = vector.extract_strided_slice [[ARG]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
486// CHECK-NEXT:    [[SHAPE:%.+]] = vector.shape_cast [[EXTR]] : vector<3x1xi32> to vector<3xi32>
487// CHECK-NEXT:    [[TRNC:%.+]]  = arith.trunci [[SHAPE]] : vector<3xi32> to vector<3xi16>
488// CHECK-NEXT:    return [[TRNC]] : vector<3xi16>
489func.func @trunci_vector(%a : vector<3xi64>) -> vector<3xi16> {
490    %b = arith.trunci %a : vector<3xi64> to vector<3xi16>
491    return %b : vector<3xi16>
492}
493
494// CHECK-LABEL: func @maxui_scalar
495// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
496// CHECK-NEXT:    vector.extract [[ARG0]][0] : i32 from vector<2xi32>
497// CHECK-NEXT:    vector.extract [[ARG0]][1] : i32 from vector<2xi32>
498// CHECK-NEXT:    vector.extract [[ARG1]][0] : i32 from vector<2xi32>
499// CHECK-NEXT:    vector.extract [[ARG1]][1] : i32 from vector<2xi32>
500// CHECK:         arith.cmpi ugt
501// CHECK:         arith.cmpi ugt
502// CHECK:         arith.cmpi eq
503// CHECK:         arith.select
504// CHECK:         arith.select
505// CHECK:         [[INS0:%.+]]   = vector.insert {{%.+}}, {{%.+}} [0] : i32 into vector<2xi32>
506// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert {{%.+}}, [[INS0]] [1] : i32 into vector<2xi32>
507// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
508func.func @maxui_scalar(%a : i64, %b : i64) -> i64 {
509    %x = arith.maxui %a, %b : i64
510    return %x : i64
511}
512
513// CHECK-LABEL: func @maxui_vector
514// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
515// CHECK:         arith.cmpi ugt
516// CHECK:         arith.cmpi ugt
517// CHECK:         arith.cmpi eq
518// CHECK:         arith.select
519// CHECK:         arith.select
520// CHECK:         return {{.+}} : vector<3x2xi32>
521func.func @maxui_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
522    %x = arith.maxui %a, %b : vector<3xi64>
523    return %x : vector<3xi64>
524}
525
526// CHECK-LABEL: func @maxsi_scalar
527// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
528// CHECK-NEXT:    vector.extract [[ARG0]][0] : i32 from vector<2xi32>
529// CHECK-NEXT:    vector.extract [[ARG0]][1] : i32 from vector<2xi32>
530// CHECK-NEXT:    vector.extract [[ARG1]][0] : i32 from vector<2xi32>
531// CHECK-NEXT:    vector.extract [[ARG1]][1] : i32 from vector<2xi32>
532// CHECK:         arith.cmpi ugt
533// CHECK:         arith.cmpi sgt
534// CHECK:         arith.cmpi eq
535// CHECK:         arith.select
536// CHECK:         arith.select
537// CHECK:         [[INS0:%.+]]   = vector.insert {{%.+}}, {{%.+}} [0] : i32 into vector<2xi32>
538// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert {{%.+}}, [[INS0]] [1] : i32 into vector<2xi32>
539// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
540func.func @maxsi_scalar(%a : i64, %b : i64) -> i64 {
541    %x = arith.maxsi %a, %b : i64
542    return %x : i64
543}
544
545// CHECK-LABEL: func @maxsi_vector
546// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
547// CHECK:         arith.cmpi ugt
548// CHECK:         arith.cmpi sgt
549// CHECK:         arith.cmpi eq
550// CHECK:         arith.select
551// CHECK:         arith.select
552// CHECK:         return {{.+}} : vector<3x2xi32>
553func.func @maxsi_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
554    %x = arith.maxsi %a, %b : vector<3xi64>
555    return %x : vector<3xi64>
556}
557
558// CHECK-LABEL: func @minui_scalar
559// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
560// CHECK-NEXT:    vector.extract [[ARG0]][0] : i32 from vector<2xi32>
561// CHECK-NEXT:    vector.extract [[ARG0]][1] : i32 from vector<2xi32>
562// CHECK-NEXT:    vector.extract [[ARG1]][0] : i32 from vector<2xi32>
563// CHECK-NEXT:    vector.extract [[ARG1]][1] : i32 from vector<2xi32>
564// CHECK:         arith.cmpi ult
565// CHECK:         arith.cmpi ult
566// CHECK:         arith.cmpi eq
567// CHECK:         arith.select
568// CHECK:         arith.select
569// CHECK:         [[INS0:%.+]]   = vector.insert {{%.+}}, {{%.+}} [0] : i32 into vector<2xi32>
570// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert {{%.+}}, [[INS0]] [1] : i32 into vector<2xi32>
571// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
572func.func @minui_scalar(%a : i64, %b : i64) -> i64 {
573    %x = arith.minui %a, %b : i64
574    return %x : i64
575}
576
577// CHECK-LABEL: func @minui_vector
578// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
579// CHECK:         arith.cmpi ult
580// CHECK:         arith.cmpi ult
581// CHECK:         arith.cmpi eq
582// CHECK:         arith.select
583// CHECK:         arith.select
584// CHECK:         return {{.+}} : vector<3x2xi32>
585func.func @minui_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
586    %x = arith.minui %a, %b : vector<3xi64>
587    return %x : vector<3xi64>
588}
589
590// CHECK-LABEL: func @minsi_scalar
591// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
592// CHECK-NEXT:    vector.extract [[ARG0]][0] : i32 from vector<2xi32>
593// CHECK-NEXT:    vector.extract [[ARG0]][1] : i32 from vector<2xi32>
594// CHECK-NEXT:    vector.extract [[ARG1]][0] : i32 from vector<2xi32>
595// CHECK-NEXT:    vector.extract [[ARG1]][1] : i32 from vector<2xi32>
596// CHECK:         arith.cmpi ult
597// CHECK:         arith.cmpi slt
598// CHECK:         arith.cmpi eq
599// CHECK:         arith.select
600// CHECK:         arith.select
601// CHECK:         [[INS0:%.+]]   = vector.insert {{%.+}}, {{%.+}} [0] : i32 into vector<2xi32>
602// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert {{%.+}}, [[INS0]] [1] : i32 into vector<2xi32>
603// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
604func.func @minsi_scalar(%a : i64, %b : i64) -> i64 {
605    %x = arith.minsi %a, %b : i64
606    return %x : i64
607}
608
609// CHECK-LABEL: func @minsi_vector
610// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
611// CHECK:         arith.cmpi ult
612// CHECK:         arith.cmpi slt
613// CHECK:         arith.cmpi eq
614// CHECK:         arith.select
615// CHECK:         arith.select
616// CHECK:         return {{.+}} : vector<3x2xi32>
617func.func @minsi_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
618    %x = arith.minsi %a, %b : vector<3xi64>
619    return %x : vector<3xi64>
620}
621
622// CHECK-LABEL: func.func @select_scalar
623// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>, [[ARG2:%.+]]: i1)
624// CHECK-SAME:    -> vector<2xi32>
625// CHECK-NEXT:    [[TLOW:%.+]] = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
626// CHECK-NEXT:    [[THIGH:%.+]] = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
627// CHECK-NEXT:    [[FLOW:%.+]] = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
628// CHECK-NEXT:    [[FHIGH:%.+]] = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
629// CHECK-NEXT:    [[SLOW:%.+]] = arith.select [[ARG2]], [[TLOW]], [[FLOW]] : i32
630// CHECK-NEXT:    [[SHIGH:%.+]] = arith.select [[ARG2]], [[THIGH]], [[FHIGH]] : i32
631// CHECK-NEXT:    [[VZ:%.+]]   = arith.constant dense<0> : vector<2xi32>
632// CHECK-NEXT:    [[INS0:%.+]] = vector.insert [[SLOW]], [[VZ]] [0] : i32 into vector<2xi32>
633// CHECK-NEXT:    [[INS1:%.+]] = vector.insert [[SHIGH]], [[INS0]] [1] : i32 into vector<2xi32>
634// CHECK:         return [[INS1]] : vector<2xi32>
635func.func @select_scalar(%a : i64, %b : i64, %c : i1) -> i64 {
636    %r = arith.select %c, %a, %b : i64
637    return %r : i64
638}
639
640// CHECK-LABEL: func.func @select_vector_whole
641// CHECK-SAME:    ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>, [[ARG2:%.+]]: i1)
642// CHECK-SAME:    -> vector<3x2xi32>
643// CHECK:         arith.select {{%.+}}, {{%.+}}, {{%.+}} : vector<3x1xi32>
644// CHECK-NEXT:    arith.select {{%.+}}, {{%.+}}, {{%.+}} : vector<3x1xi32>
645// CHECK:         return {{%.+}} : vector<3x2xi32>
646func.func @select_vector_whole(%a : vector<3xi64>, %b : vector<3xi64>, %c : i1) -> vector<3xi64> {
647    %r = arith.select %c, %a, %b : vector<3xi64>
648    return %r : vector<3xi64>
649}
650
651// CHECK-LABEL: func.func @select_vector_elementwise
652// CHECK-SAME:    ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>, [[ARG2:%.+]]: vector<3xi1>)
653// CHECK-SAME:    -> vector<3x2xi32>
654// CHECK:         arith.select {{%.+}}, {{%.+}}, {{%.+}} : vector<3x1xi1>, vector<3x1xi32>
655// CHECK-NEXT:    arith.select {{%.+}}, {{%.+}}, {{%.+}} : vector<3x1xi1>, vector<3x1xi32>
656// CHECK:         return {{%.+}} : vector<3x2xi32>
657func.func @select_vector_elementwise(%a : vector<3xi64>, %b : vector<3xi64>, %c : vector<3xi1>) -> vector<3xi64> {
658    %r = arith.select %c, %a, %b : vector<3xi1>, vector<3xi64>
659    return %r : vector<3xi64>
660}
661
662// CHECK-LABEL: func.func @muli_scalar
663// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
664// CHECK-NEXT:    [[LOW0:%.+]]  = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
665// CHECK-NEXT:    [[HIGH0:%.+]] = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
666// CHECK-NEXT:    [[LOW1:%.+]]  = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
667// CHECK-NEXT:    [[HIGH1:%.+]] = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
668//
669// CHECK-DAG:     [[RESLOW:%.+]], [[HI0:%.+]] = arith.mului_extended [[LOW0]], [[LOW1]] : i32
670// CHECK-DAG:     [[HI1:%.+]]                 = arith.muli [[LOW0]], [[HIGH1]] : i32
671// CHECK-DAG:     [[HI2:%.+]]                 = arith.muli [[HIGH0]], [[LOW1]] : i32
672// CHECK-NEXT:    [[RESHI1:%.+]]              = arith.addi [[HI0]], [[HI1]] : i32
673// CHECK-NEXT:    [[RESHI2:%.+]]              = arith.addi [[RESHI1]], [[HI2]] : i32
674//
675// CHECK-NEXT:    [[VZ:%.+]]   = arith.constant dense<0> : vector<2xi32>
676// CHECK-NEXT:    [[INS0:%.+]] = vector.insert [[RESLOW]], [[VZ]] [0] : i32 into vector<2xi32>
677// CHECK-NEXT:    [[INS1:%.+]] = vector.insert [[RESHI2]], [[INS0]] [1] : i32 into vector<2xi32>
678// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
679func.func @muli_scalar(%a : i64, %b : i64) -> i64 {
680    %m = arith.muli %a, %b : i64
681    return %m : i64
682}
683
684// CHECK-LABEL: func.func @muli_vector
685// CHECK-SAME:    ({{%.+}}: vector<3x2xi32>, {{%.+}}: vector<3x2xi32>) -> vector<3x2xi32>
686// CHECK-DAG:     arith.mului_extended
687// CHECK-DAG:     arith.muli
688// CHECK-DAG:     arith.muli
689// CHECK-NEXT:    arith.addi
690// CHECK-NEXT:    arith.addi
691// CHECK:       return {{%.+}} : vector<3x2xi32>
692func.func @muli_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
693    %m = arith.muli %a, %b : vector<3xi64>
694    return %m : vector<3xi64>
695}
696
697// CHECK-LABEL: func.func @shli_scalar
698// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
699// CHECK-NEXT:    [[LOW0:%.+]]     = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
700// CHECK-NEXT:    [[HIGH0:%.+]]    = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
701// CHECK-NEXT:    [[LOW1:%.+]]     = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
702// CHECK-NEXT:    [[CST0:%.+]]     = arith.constant 0 : i32
703// CHECK-NEXT:    [[CST32:%.+]]    = arith.constant 32 : i32
704// CHECK-NEXT:    [[OOB:%.+]]      = arith.cmpi uge, [[LOW1]], [[CST32]] : i32
705// CHECK-NEXT:    [[SHLOW0:%.+]]   = arith.shli [[LOW0]], [[LOW1]] : i32
706// CHECK-NEXT:    [[RES0:%.+]]     = arith.select [[OOB]], [[CST0]], [[SHLOW0]] : i32
707// CHECK-NEXT:    [[SHAMT:%.+]]    = arith.select [[OOB]], [[CST32]], [[LOW1]] : i32
708// CHECK-NEXT:    [[RSHAMT:%.+]]   = arith.subi [[CST32]], [[SHAMT]] : i32
709// CHECK-NEXT:    [[SHRHIGH0:%.+]] = arith.shrui [[LOW0]], [[RSHAMT]] : i32
710// CHECK-NEXT:    [[LSHAMT:%.+]]   = arith.subi [[LOW1]], [[CST32]] : i32
711// CHECK-NEXT:    [[SHLHIGH0:%.+]] = arith.shli [[LOW0]], [[LSHAMT]] : i32
712// CHECK-NEXT:    [[SHLHIGH1:%.+]] = arith.shli [[HIGH0]], [[LOW1]] : i32
713// CHECK-NEXT:    [[RES1HIGH:%.+]] = arith.select [[OOB]], [[CST0]], [[SHLHIGH1]] : i32
714// CHECK-NEXT:    [[RES1LOW:%.+]]  = arith.select [[OOB]], [[SHLHIGH0]], [[SHRHIGH0]] : i32
715// CHECK-NEXT:    [[RES1:%.+]]     = arith.ori [[RES1LOW]], [[RES1HIGH]] : i32
716// CHECK-NEXT:    [[VZ:%.+]]       = arith.constant dense<0> : vector<2xi32>
717// CHECK-NEXT:    [[INS0:%.+]]     = vector.insert [[RES0]], [[VZ]] [0] : i32 into vector<2xi32>
718// CHECK-NEXT:    [[INS1:%.+]]     = vector.insert [[RES1]], [[INS0]] [1] : i32 into vector<2xi32>
719// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
720func.func @shli_scalar(%a : i64, %b : i64) -> i64 {
721    %c = arith.shli %a, %b : i64
722    return %c : i64
723}
724
725// CHECK-LABEL: func.func @shli_vector
726// CHECK-SAME:    ({{%.+}}: vector<3x2xi32>, {{%.+}}: vector<3x2xi32>) -> vector<3x2xi32>
727// CHECK:         {{%.+}} = arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
728// CHECK:         {{%.+}} = arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
729// CHECK:         {{%.+}} = arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
730// CHECK:         {{%.+}} = arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
731// CHECK:       return {{%.+}} : vector<3x2xi32>
732func.func @shli_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
733    %m = arith.shli %a, %b : vector<3xi64>
734    return %m : vector<3xi64>
735}
736
737// CHECK-LABEL: func.func @shrui_scalar
738// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
739// CHECK-NEXT:    [[LOW0:%.+]]     = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
740// CHECK-NEXT:    [[HIGH0:%.+]]    = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
741// CHECK-NEXT:    [[LOW1:%.+]]     = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
742// CHECK-NEXT:    [[CST0:%.+]]     = arith.constant 0 : i32
743// CHECK-NEXT:    [[CST32:%.+]]    = arith.constant 32 : i32
744// CHECK-DAG:     [[OOB:%.+]]      = arith.cmpi uge, [[LOW1]], [[CST32]] : i32
745// CHECK-DAG:     [[SHLOW0:%.+]]   = arith.shrui [[LOW0]], [[LOW1]] : i32
746// CHECK-NEXT:    [[RES0LOW:%.+]]  = arith.select [[OOB]], [[CST0]], [[SHLOW0]] : i32
747// CHECK-NEXT:    [[SHRHIGH0:%.+]] = arith.shrui [[HIGH0]], [[LOW1]] : i32
748// CHECK-NEXT:    [[RESLOW1:%.+]]  = arith.select [[OOB]], [[CST0]], [[SHRHIGH0]] : i32
749// CHECK-NEXT:    [[SHAMT:%.+]]    = arith.select [[OOB]], [[CST32]], [[LOW1]] : i32
750// CHECK-NEXT:    [[LSHAMT:%.+]]   = arith.subi [[CST32]], [[SHAMT]] : i32
751// CHECK-NEXT:    [[SHLHIGH0:%.+]] = arith.shli [[HIGH0]], [[LSHAMT]] : i32
752// CHECK-NEXT:    [[RSHAMT:%.+]]   = arith.subi [[LOW1]], [[CST32]] : i32
753// CHECK-NEXT:    [[SHRHIGH0:%.+]] = arith.shrui [[HIGH0]], [[RSHAMT]] : i32
754// CHECK-NEXT:    [[RES0HIGH:%.+]] = arith.select [[OOB]], [[SHRHIGH0]], [[SHLHIGH0]] : i32
755// CHECK-NEXT:    [[RES0:%.+]]     = arith.ori [[RES0LOW]], [[RES0HIGH]] : i32
756// CHECK-NEXT:    [[VZ:%.+]]       = arith.constant dense<0> : vector<2xi32>
757// CHECK-NEXT:    [[INS0:%.+]]     = vector.insert [[RES0]], [[VZ]] [0] : i32 into vector<2xi32>
758// CHECK-NEXT:    [[INS1:%.+]]     = vector.insert [[RESLOW1]], [[INS0]] [1] : i32 into vector<2xi32>
759// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
760func.func @shrui_scalar(%a : i64, %b : i64) -> i64 {
761    %c = arith.shrui %a, %b : i64
762    return %c : i64
763}
764
765// CHECK-LABEL: func.func @shrui_scalar_cst_2
766// CHECK-SAME:    ({{%.+}}: vector<2xi32>) -> vector<2xi32>
767// CHECK:       return {{%.+}} : vector<2xi32>
768func.func @shrui_scalar_cst_2(%a : i64) -> i64 {
769    %b = arith.constant 2 : i64
770    %c = arith.shrui %a, %b : i64
771    return %c : i64
772}
773
774// CHECK-LABEL: func.func @shrui_scalar_cst_36
775// CHECK-SAME:    ({{%.+}}: vector<2xi32>) -> vector<2xi32>
776// CHECK:       return {{%.+}} : vector<2xi32>
777func.func @shrui_scalar_cst_36(%a : i64) -> i64 {
778    %b = arith.constant 36 : i64
779    %c = arith.shrui %a, %b : i64
780    return %c : i64
781}
782
783// CHECK-LABEL: func.func @shrui_vector
784// CHECK-SAME:    ({{%.+}}: vector<3x2xi32>, {{%.+}}: vector<3x2xi32>) -> vector<3x2xi32>
785// CHECK:         {{%.+}} = arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
786// CHECK:         {{%.+}} = arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
787// CHECK:         {{%.+}} = arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
788// CHECK:         {{%.+}} = arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
789// CHECK:       return {{%.+}} : vector<3x2xi32>
790func.func @shrui_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
791    %m = arith.shrui %a, %b : vector<3xi64>
792    return %m : vector<3xi64>
793}
794
795// CHECK-LABEL: func.func @shrsi_scalar
796// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
797// CHECK-NEXT:    [[HIGH0:%.+]]    = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
798// CHECK-NEXT:    [[LOW1:%.+]]     = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
799// CHECK-NEXT:    [[CST0:%.+]]     = arith.constant 0 : i32
800// CHECK-NEXT:    [[NEG:%.+]]      = arith.cmpi slt, [[HIGH0]], [[CST0]] : i32
801// CHECK-NEXT:    [[NEGEXT:%.+]]   = arith.extsi [[NEG]] : i1 to i32
802// CHECK:         [[CST64:%.+]]    = arith.constant 64 : i32
803// CHECK-NEXT:    [[SIGNBITS:%.+]] = arith.subi [[CST64]], [[LOW1]] : i32
804// CHECK:         arith.shli
805// CHECK:         arith.shrui
806// CHECK:         arith.shli
807// CHECK:         arith.shli
808// CHECK:         arith.shrui
809// CHECK:         arith.shrui
810// CHECK:         arith.shli
811// CHECK:         arith.shrui
812// CHECK:         return {{%.+}} : vector<2xi32>
813func.func @shrsi_scalar(%a : i64, %b : i64) -> i64 {
814    %c = arith.shrsi %a, %b : i64
815    return %c : i64
816}
817
818// CHECK-LABEL: func.func @shrsi_vector
819// CHECK-SAME:    ({{%.+}}: vector<3x2xi32>, {{%.+}}: vector<3x2xi32>) -> vector<3x2xi32>
820// CHECK:         arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
821// CHECK:         arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
822// CHECK:         arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
823// CHECK:         arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
824// CHECK:         arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
825// CHECK:         arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
826// CHECK:         arith.shli {{%.+}}, {{%.+}} : vector<3x1xi32>
827// CHECK:         arith.shrui {{%.+}}, {{%.+}} : vector<3x1xi32>
828// CHECK:         return {{%.+}} : vector<3x2xi32>
829func.func @shrsi_vector(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
830    %m = arith.shrsi %a, %b : vector<3xi64>
831    return %m : vector<3xi64>
832}
833
834// CHECK-LABEL: func @andi_scalar_a_b
835// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
836// CHECK-NEXT:    [[LOW0:%.+]]   = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
837// CHECK-NEXT:    [[HIGH0:%.+]]  = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
838// CHECK-NEXT:    [[LOW1:%.+]]   = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
839// CHECK-NEXT:    [[HIGH1:%.+]]  = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
840// CHECK-NEXT:    [[RES0:%.+]]   = arith.andi [[LOW0]], [[LOW1]] : i32
841// CHECK-NEXT:    [[RES1:%.+]]   = arith.andi [[HIGH0]], [[HIGH1]] : i32
842// CHECK:         [[INS0:%.+]]   = vector.insert [[RES0]], {{%.+}} [0] : i32 into vector<2xi32>
843// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert [[RES1]], [[INS0]] [1] : i32 into vector<2xi32>
844// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
845func.func @andi_scalar_a_b(%a : i64, %b : i64) -> i64 {
846    %x = arith.andi %a, %b : i64
847    return %x : i64
848}
849
850// CHECK-LABEL: func @andi_vector_a_b
851// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
852// CHECK:         {{%.+}} = arith.andi {{%.+}}, {{%.+}} : vector<3x1xi32>
853// CHECK-NEXT:    {{%.+}} = arith.andi {{%.+}}, {{%.+}} : vector<3x1xi32>
854// CHECK:         return {{.+}} : vector<3x2xi32>
855func.func @andi_vector_a_b(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
856    %x = arith.andi %a, %b : vector<3xi64>
857    return %x : vector<3xi64>
858}
859
860// CHECK-LABEL: func @ori_scalar_a_b
861// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
862// CHECK-NEXT:    [[LOW0:%.+]]   = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
863// CHECK-NEXT:    [[HIGH0:%.+]]  = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
864// CHECK-NEXT:    [[LOW1:%.+]]   = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
865// CHECK-NEXT:    [[HIGH1:%.+]]  = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
866// CHECK-NEXT:    [[RES0:%.+]]   = arith.ori [[LOW0]], [[LOW1]] : i32
867// CHECK-NEXT:    [[RES1:%.+]]   = arith.ori [[HIGH0]], [[HIGH1]] : i32
868// CHECK:         [[INS0:%.+]]   = vector.insert [[RES0]], {{%.+}} [0] : i32 into vector<2xi32>
869// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert [[RES1]], [[INS0]] [1] : i32 into vector<2xi32>
870// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
871func.func @ori_scalar_a_b(%a : i64, %b : i64) -> i64 {
872    %x = arith.ori %a, %b : i64
873    return %x : i64
874}
875
876// CHECK-LABEL: func @ori_vector_a_b
877// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
878// CHECK:         {{%.+}} = arith.ori {{%.+}}, {{%.+}} : vector<3x1xi32>
879// CHECK-NEXT:    {{%.+}} = arith.ori {{%.+}}, {{%.+}} : vector<3x1xi32>
880// CHECK:         return {{.+}} : vector<3x2xi32>
881func.func @ori_vector_a_b(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
882    %x = arith.ori %a, %b : vector<3xi64>
883    return %x : vector<3xi64>
884}
885
886// CHECK-LABEL: func @xori_scalar_a_b
887// CHECK-SAME:    ([[ARG0:%.+]]: vector<2xi32>, [[ARG1:%.+]]: vector<2xi32>) -> vector<2xi32>
888// CHECK-NEXT:    [[LOW0:%.+]]   = vector.extract [[ARG0]][0] : i32 from vector<2xi32>
889// CHECK-NEXT:    [[HIGH0:%.+]]  = vector.extract [[ARG0]][1] : i32 from vector<2xi32>
890// CHECK-NEXT:    [[LOW1:%.+]]   = vector.extract [[ARG1]][0] : i32 from vector<2xi32>
891// CHECK-NEXT:    [[HIGH1:%.+]]  = vector.extract [[ARG1]][1] : i32 from vector<2xi32>
892// CHECK-NEXT:    [[RES0:%.+]]   = arith.xori [[LOW0]], [[LOW1]] : i32
893// CHECK-NEXT:    [[RES1:%.+]]   = arith.xori [[HIGH0]], [[HIGH1]] : i32
894// CHECK:         [[INS0:%.+]]   = vector.insert [[RES0]], {{%.+}} [0] : i32 into vector<2xi32>
895// CHECK-NEXT:    [[INS1:%.+]]   = vector.insert [[RES1]], [[INS0]] [1] : i32 into vector<2xi32>
896// CHECK-NEXT:    return [[INS1]] : vector<2xi32>
897func.func @xori_scalar_a_b(%a : i64, %b : i64) -> i64 {
898    %x = arith.xori %a, %b : i64
899    return %x : i64
900}
901
902// CHECK-LABEL: func @xori_vector_a_b
903// CHECK-SAME:   ([[ARG0:%.+]]: vector<3x2xi32>, [[ARG1:%.+]]: vector<3x2xi32>) -> vector<3x2xi32>
904// CHECK:         {{%.+}} = arith.xori {{%.+}}, {{%.+}} : vector<3x1xi32>
905// CHECK-NEXT:    {{%.+}} = arith.xori {{%.+}}, {{%.+}} : vector<3x1xi32>
906// CHECK:         return {{.+}} : vector<3x2xi32>
907func.func @xori_vector_a_b(%a : vector<3xi64>, %b : vector<3xi64>) -> vector<3xi64> {
908    %x = arith.xori %a, %b : vector<3xi64>
909    return %x : vector<3xi64>
910}
911
912// CHECK-LABEL: func @uitofp_i64_f64
913// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> f64
914// CHECK-NEXT:    [[LOW:%.+]]    = vector.extract [[ARG]][0] : i32 from vector<2xi32>
915// CHECK-NEXT:    [[HI:%.+]]     = vector.extract [[ARG]][1] : i32 from vector<2xi32>
916// CHECK-NEXT:    [[CST0:%.+]]   = arith.constant 0 : i32
917// CHECK-NEXT:    [[HIEQ0:%.+]]  = arith.cmpi eq, [[HI]], [[CST0]] : i32
918// CHECK-NEXT:    [[LOWFP:%.+]]  = arith.uitofp [[LOW]] : i32 to f64
919// CHECK-NEXT:    [[HIFP:%.+]]   = arith.uitofp [[HI]] : i32 to f64
920// CHECK-NEXT:    [[POW:%.+]]    = arith.constant 0x41F0000000000000 : f64
921// CHECK-NEXT:    [[RESHI:%.+]]  = arith.mulf [[HIFP]], [[POW]] : f64
922// CHECK-NEXT:    [[RES:%.+]]    = arith.addf [[LOWFP]], [[RESHI]] : f64
923// CHECK-NEXT:    [[SEL:%.+]]    = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : f64
924// CHECK-NEXT:    return [[SEL]] : f64
925func.func @uitofp_i64_f64(%a : i64) -> f64 {
926    %r = arith.uitofp %a : i64 to f64
927    return %r : f64
928}
929
930// CHECK-LABEL: func @uitofp_i64_f64_vector
931// CHECK-SAME:    ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xf64>
932// CHECK-NEXT:    [[EXTLOW:%.+]] = vector.extract_strided_slice [[ARG]] {offsets = [0, 0], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
933// CHECK-NEXT:    [[EXTHI:%.+]]  = vector.extract_strided_slice [[ARG]] {offsets = [0, 1], sizes = [3, 1], strides = [1, 1]} : vector<3x2xi32> to vector<3x1xi32>
934// CHECK-NEXT:    [[LOW:%.+]]    = vector.shape_cast [[EXTLOW]] : vector<3x1xi32> to vector<3xi32>
935// CHECK-NEXT:    [[HI:%.+]]     = vector.shape_cast [[EXTHI]] : vector<3x1xi32> to vector<3xi32>
936// CHECK-NEXT:    [[CST0:%.+]]   = arith.constant dense<0> : vector<3xi32>
937// CHECK-NEXT:    [[HIEQ0:%.+]]  = arith.cmpi eq, [[HI]], [[CST0]] : vector<3xi32>
938// CHECK-NEXT:    [[LOWFP:%.+]]  = arith.uitofp [[LOW]] : vector<3xi32> to vector<3xf64>
939// CHECK-NEXT:    [[HIFP:%.+]]   = arith.uitofp [[HI]] : vector<3xi32> to vector<3xf64>
940// CHECK-NEXT:    [[POW:%.+]]    = arith.constant dense<0x41F0000000000000> : vector<3xf64>
941// CHECK-NEXT:    [[RESHI:%.+]]  = arith.mulf [[HIFP]], [[POW]] : vector<3xf64>
942// CHECK-NEXT:    [[RES:%.+]]    = arith.addf [[LOWFP]], [[RESHI]] : vector<3xf64>
943// CHECK-NEXT:    [[SEL:%.+]]    = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : vector<3xi1>, vector<3xf64>
944// CHECK-NEXT:    return [[SEL]] : vector<3xf64>
945func.func @uitofp_i64_f64_vector(%a : vector<3xi64>) -> vector<3xf64> {
946    %r = arith.uitofp %a : vector<3xi64> to vector<3xf64>
947    return %r : vector<3xf64>
948}
949
950// CHECK-LABEL: func @uitofp_i64_f16
951// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> f16
952// CHECK-NEXT:    [[LOW:%.+]]   = vector.extract [[ARG]][0] : i32 from vector<2xi32>
953// CHECK-NEXT:    [[HI:%.+]]    = vector.extract [[ARG]][1] : i32 from vector<2xi32>
954// CHECK-NEXT:    [[CST0:%.+]]   = arith.constant 0 : i32
955// CHECK-NEXT:    [[HIEQ0:%.+]]  = arith.cmpi eq, [[HI]], [[CST0]] : i32
956// CHECK-NEXT:    [[LOWFP:%.+]]  = arith.uitofp [[LOW]] : i32 to f16
957// CHECK-NEXT:    [[HIFP:%.+]]   = arith.uitofp [[HI]] : i32 to f16
958// CHECK-NEXT:    [[POW:%.+]]    = arith.constant 0x7C00 : f16
959// CHECK-NEXT:    [[RESHI:%.+]]  = arith.mulf [[HIFP]], [[POW]] : f16
960// CHECK-NEXT:    [[RES:%.+]]    = arith.addf [[LOWFP]], [[RESHI]] : f16
961// CHECK-NEXT:    [[SEL:%.+]]    = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : f16
962// CHECK-NEXT:    return [[SEL]] : f16
963func.func @uitofp_i64_f16(%a : i64) -> f16 {
964    %r = arith.uitofp %a : i64 to f16
965    return %r : f16
966}
967
968// CHECK-LABEL: func @sitofp_i64_f64
969// CHECK-SAME:    ([[ARG:%.+]]: vector<2xi32>) -> f64
970// CHECK:         [[VONES:%.+]]  = arith.constant dense<-1> : vector<2xi32>
971// CHECK:         [[ONES1:%.+]]  = vector.extract [[VONES]][0] : i32 from vector<2xi32>
972// CHECK-NEXT:    [[ONES2:%.+]]  = vector.extract [[VONES]][1] : i32 from vector<2xi32>
973// CHECK:                          arith.xori {{%.+}}, [[ONES1]] : i32
974// CHECK-NEXT:                     arith.xori {{%.+}}, [[ONES2]] : i32
975// CHECK:         [[CST0:%.+]]   = arith.constant 0 : i32
976// CHECK:         [[HIEQ0:%.+]]  = arith.cmpi eq, [[HI:%.+]], [[CST0]] : i32
977// CHECK-NEXT:    [[LOWFP:%.+]]  = arith.uitofp [[LOW:%.+]] : i32 to f64
978// CHECK-NEXT:    [[HIFP:%.+]]   = arith.uitofp [[HI]] : i32 to f64
979// CHECK-NEXT:    [[POW:%.+]]    = arith.constant 0x41F0000000000000 : f64
980// CHECK-NEXT:    [[RESHI:%.+]]  = arith.mulf [[HIFP]], [[POW]] : f64
981// CHECK-NEXT:    [[RES:%.+]]    = arith.addf [[LOWFP]], [[RESHI]] : f64
982// CHECK-NEXT:    [[SEL:%.+]]    = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : f64
983// CHECK-NEXT:    [[NEG:%.+]]    = arith.negf [[SEL]] : f64
984// CHECK-NEXT:    [[FINAL:%.+]]  = arith.select %{{.+}}, [[NEG]], [[SEL]] : f64
985// CHECK-NEXT:    return [[FINAL]] : f64
986func.func @sitofp_i64_f64(%a : i64) -> f64 {
987    %r = arith.sitofp %a : i64 to f64
988    return %r : f64
989}
990
991// CHECK-LABEL: func @sitofp_i64_f64_vector
992// CHECK-SAME:    ([[ARG:%.+]]: vector<3x2xi32>) -> vector<3xf64>
993// CHECK:         [[VONES:%.+]]  = arith.constant dense<-1> : vector<3x2xi32>
994// CHECK:                          arith.xori
995// CHECK-NEXT:                     arith.xori
996// CHECK:         [[HIEQ0:%.+]]  = arith.cmpi eq, [[HI:%.+]], [[CST0:%.+]] : vector<3xi32>
997// CHECK-NEXT:    [[LOWFP:%.+]]  = arith.uitofp [[LOW:%.+]] : vector<3xi32> to vector<3xf64>
998// CHECK-NEXT:    [[HIFP:%.+]]   = arith.uitofp [[HI:%.+]] : vector<3xi32> to vector<3xf64>
999// CHECK-NEXT:    [[POW:%.+]]    = arith.constant dense<0x41F0000000000000> : vector<3xf64>
1000// CHECK-NEXT:    [[RESHI:%.+]]  = arith.mulf [[HIFP]], [[POW]] : vector<3xf64>
1001// CHECK-NEXT:    [[RES:%.+]]    = arith.addf [[LOWFP]], [[RESHI]] : vector<3xf64>
1002// CHECK-NEXT:    [[SEL:%.+]]    = arith.select [[HIEQ0]], [[LOWFP]], [[RES]] : vector<3xi1>, vector<3xf64>
1003// CHECK-NEXT:    [[NEG:%.+]]    = arith.negf [[SEL]] : vector<3xf64>
1004// CHECK-NEXT:    [[FINAL:%.+]]  = arith.select %{{.+}}, [[NEG]], [[SEL]] : vector<3xi1>, vector<3xf64>
1005// CHECK-NEXT:    return [[FINAL]] : vector<3xf64>
1006func.func @sitofp_i64_f64_vector(%a : vector<3xi64>) -> vector<3xf64> {
1007    %r = arith.sitofp %a : vector<3xi64> to vector<3xf64>
1008    return %r : vector<3xf64>
1009}
1010