xref: /llvm-project/mlir/test/Dialect/Arith/canonicalize.mlir (revision ac87d6b03642eca3901a7776d73be368299402e9)
1// RUN: mlir-opt %s -canonicalize="test-convergence" --split-input-file | FileCheck %s
2
3// CHECK-LABEL: @select_same_val
4//       CHECK:   return %arg1
5func.func @select_same_val(%arg0: i1, %arg1: i64) -> i64 {
6  %0 = arith.select %arg0, %arg1, %arg1 : i64
7  return %0 : i64
8}
9
10// CHECK-LABEL: @select_cmp_eq_select
11//       CHECK:   return %arg1
12func.func @select_cmp_eq_select(%arg0: i64, %arg1: i64) -> i64 {
13  %0 = arith.cmpi eq, %arg0, %arg1 : i64
14  %1 = arith.select %0, %arg0, %arg1 : i64
15  return %1 : i64
16}
17
18// CHECK-LABEL: @select_cmp_ne_select
19//       CHECK:   return %arg0
20func.func @select_cmp_ne_select(%arg0: i64, %arg1: i64) -> i64 {
21  %0 = arith.cmpi ne, %arg0, %arg1 : i64
22  %1 = arith.select %0, %arg0, %arg1 : i64
23  return %1 : i64
24}
25
26// CHECK-LABEL: @select_extui
27//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
28//       CHECK:   return %[[res]]
29func.func @select_extui(%arg0: i1) -> i64 {
30  %c0_i64 = arith.constant 0 : i64
31  %c1_i64 = arith.constant 1 : i64
32  %res = arith.select %arg0, %c1_i64, %c0_i64 : i64
33  return %res : i64
34}
35
36// CHECK-LABEL: @select_extui2
37// CHECK-DAG:  %true = arith.constant true
38// CHECK-DAG:  %[[xor:.+]] = arith.xori %arg0, %true : i1
39// CHECK-DAG:  %[[res:.+]] = arith.extui %[[xor]] : i1 to i64
40//       CHECK:   return %[[res]]
41func.func @select_extui2(%arg0: i1) -> i64 {
42  %c0_i64 = arith.constant 0 : i64
43  %c1_i64 = arith.constant 1 : i64
44  %res = arith.select %arg0, %c0_i64, %c1_i64 : i64
45  return %res : i64
46}
47
48// CHECK-LABEL: @select_extui_i1
49//  CHECK-NEXT:   return %arg0
50func.func @select_extui_i1(%arg0: i1) -> i1 {
51  %c0_i1 = arith.constant false
52  %c1_i1 = arith.constant true
53  %res = arith.select %arg0, %c1_i1, %c0_i1 : i1
54  return %res : i1
55}
56
57// CHECK-LABEL: @select_no_fold_ui1
58//       CHECK:  %[[CONST_0:.+]] = "test.constant"() <{value = 0 : i32}> : () -> ui1
59//       CHECK:  %[[CONST_1:.+]] = "test.constant"() <{value = 1 : i32}> : () -> ui1
60//  CHECK-NEXT:  %[[RES:.+]] = arith.select %arg0, %[[CONST_1]], %[[CONST_0]] : ui1
61//  CHECK-NEXT:   return %[[RES]]
62func.func @select_no_fold_ui1(%arg0: i1) -> ui1 {
63  %c0_i1 = "test.constant"() {value = 0 : i32} : () -> ui1
64  %c1_i1 = "test.constant"() {value = 1 : i32} : () -> ui1
65  %res = arith.select %arg0, %c1_i1, %c0_i1 : ui1
66  return %res : ui1
67}
68
69// CHECK-LABEL: @select_cst_false_scalar
70//  CHECK-SAME:   (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)
71//  CHECK-NEXT:   return %[[ARG1]]
72func.func @select_cst_false_scalar(%arg0: i32, %arg1: i32) -> i32 {
73  %false = arith.constant false
74  %res = arith.select %false, %arg0, %arg1 : i32
75  return %res : i32
76}
77
78// CHECK-LABEL: @select_cst_true_scalar
79//  CHECK-SAME:   (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)
80//  CHECK-NEXT:   return %[[ARG0]]
81func.func @select_cst_true_scalar(%arg0: i32, %arg1: i32) -> i32 {
82  %true = arith.constant true
83  %res = arith.select %true, %arg0, %arg1 : i32
84  return %res : i32
85}
86
87// CHECK-LABEL: @select_cst_true_splat
88//       CHECK:   %[[A:.+]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>
89//  CHECK-NEXT:   return %[[A]]
90func.func @select_cst_true_splat() -> vector<3xi32> {
91  %cond = arith.constant dense<true> : vector<3xi1>
92  %a = arith.constant dense<[1, 2, 3]> : vector<3xi32>
93  %b = arith.constant dense<[4, 5, 6]> : vector<3xi32>
94  %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xi32>
95  return %res : vector<3xi32>
96}
97
98// CHECK-LABEL: @select_cst_vector_i32
99//       CHECK:   %[[RES:.+]] = arith.constant dense<[1, 5, 3]> : vector<3xi32>
100//  CHECK-NEXT:   return %[[RES]]
101func.func @select_cst_vector_i32() -> vector<3xi32> {
102  %cond = arith.constant dense<[true, false, true]> : vector<3xi1>
103  %a = arith.constant dense<[1, 2, 3]> : vector<3xi32>
104  %b = arith.constant dense<[4, 5, 6]> : vector<3xi32>
105  %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xi32>
106  return %res : vector<3xi32>
107}
108
109// CHECK-LABEL: @select_cst_vector_f32
110//       CHECK:   %[[RES:.+]] = arith.constant dense<[4.000000e+00, 2.000000e+00, 6.000000e+00]> : vector<3xf32>
111//  CHECK-NEXT:   return %[[RES]]
112func.func @select_cst_vector_f32() -> vector<3xf32> {
113  %cond = arith.constant dense<[false, true, false]> : vector<3xi1>
114  %a = arith.constant dense<[1.0, 2.0, 3.0]> : vector<3xf32>
115  %b = arith.constant dense<[4.0, 5.0, 6.0]> : vector<3xf32>
116  %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xf32>
117  return %res : vector<3xf32>
118}
119
120// CHECK-LABEL: @selToNot
121//       CHECK:       %[[trueval:.+]] = arith.constant true
122//       CHECK:       %[[res:.+]] = arith.xori %arg0, %[[trueval]] : i1
123//       CHECK:   return %[[res]]
124func.func @selToNot(%arg0: i1) -> i1 {
125  %true = arith.constant true
126  %false = arith.constant false
127  %res = arith.select %arg0, %false, %true : i1
128  return %res : i1
129}
130
131// CHECK-LABEL: @redundantSelectTrue
132//       CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg1, %arg3
133//       CHECK-NEXT: return %[[res]]
134func.func @redundantSelectTrue(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 {
135  %0 = arith.select %arg0, %arg1, %arg2 : i32
136  %res = arith.select %arg0, %0, %arg3 : i32
137  return %res : i32
138}
139
140// CHECK-LABEL: @redundantSelectFalse
141//       CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg3, %arg2
142//       CHECK-NEXT: return %[[res]]
143func.func @redundantSelectFalse(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 {
144  %0 = arith.select %arg0, %arg1, %arg2 : i32
145  %res = arith.select %arg0, %arg3, %0 : i32
146  return %res : i32
147}
148
149// CHECK-LABEL: @selNotCond
150//       CHECK-NEXT: %[[res1:.+]] = arith.select %arg0, %arg2, %arg1
151//       CHECK-NEXT: %[[res2:.+]] = arith.select %arg0, %arg4, %arg3
152//       CHECK-NEXT: return %[[res1]], %[[res2]]
153func.func @selNotCond(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32, %arg4 : i32) -> (i32, i32) {
154  %one = arith.constant 1 : i1
155  %cond1 = arith.xori %arg0, %one : i1
156  %cond2 = arith.xori %one, %arg0 : i1
157
158  %res1 = arith.select %cond1, %arg1, %arg2 : i32
159  %res2 = arith.select %cond2, %arg3, %arg4 : i32
160  return %res1, %res2 : i32, i32
161}
162
163// CHECK-LABEL: @cmpiI1eq
164//  CHECK-SAME: (%[[ARG:.*]]: i1)
165//       CHECK: return %[[ARG]]
166func.func @cmpiI1eq(%arg0: i1) -> i1 {
167  %one = arith.constant 1 : i1
168  %res = arith.cmpi eq, %arg0, %one : i1
169  return %res : i1
170}
171
172// CHECK-LABEL: @cmpiI1eqVec
173//  CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)
174//       CHECK: return %[[ARG]]
175func.func @cmpiI1eqVec(%arg0: vector<4xi1>) -> vector<4xi1> {
176  %one = arith.constant dense<1> : vector<4xi1>
177  %res = arith.cmpi eq, %arg0, %one : vector<4xi1>
178  return %res : vector<4xi1>
179}
180
181// CHECK-LABEL: @cmpiI1ne
182//  CHECK-SAME: (%[[ARG:.*]]: i1)
183//       CHECK: return %[[ARG]]
184func.func @cmpiI1ne(%arg0: i1) -> i1 {
185  %zero = arith.constant 0 : i1
186  %res = arith.cmpi ne, %arg0, %zero : i1
187  return %res : i1
188}
189
190// CHECK-LABEL: @cmpiI1neVec
191//  CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)
192//       CHECK: return %[[ARG]]
193func.func @cmpiI1neVec(%arg0: vector<4xi1>) -> vector<4xi1> {
194  %zero = arith.constant dense<0> : vector<4xi1>
195  %res = arith.cmpi ne, %arg0, %zero : vector<4xi1>
196  return %res : vector<4xi1>
197}
198
199// CHECK-LABEL: @cmpiI1eqLhs
200//  CHECK-SAME: (%[[ARG:.*]]: i1)
201//       CHECK: return %[[ARG]]
202func.func @cmpiI1eqLhs(%arg0: i1) -> i1 {
203  %one = arith.constant 1 : i1
204  %res = arith.cmpi eq, %one, %arg0  : i1
205  return %res : i1
206}
207
208// CHECK-LABEL: @cmpiI1eqVecLhs
209//  CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)
210//       CHECK: return %[[ARG]]
211func.func @cmpiI1eqVecLhs(%arg0: vector<4xi1>) -> vector<4xi1> {
212  %one = arith.constant dense<1> : vector<4xi1>
213  %res = arith.cmpi eq, %one, %arg0 : vector<4xi1>
214  return %res : vector<4xi1>
215}
216
217// CHECK-LABEL: @cmpiI1neLhs
218//  CHECK-SAME: (%[[ARG:.*]]: i1)
219//       CHECK: return %[[ARG]]
220func.func @cmpiI1neLhs(%arg0: i1) -> i1 {
221  %zero = arith.constant 0 : i1
222  %res = arith.cmpi ne, %zero, %arg0 : i1
223  return %res : i1
224}
225
226// CHECK-LABEL: @cmpiI1neVecLhs
227//  CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)
228//       CHECK: return %[[ARG]]
229func.func @cmpiI1neVecLhs(%arg0: vector<4xi1>) -> vector<4xi1> {
230  %zero = arith.constant dense<0> : vector<4xi1>
231  %res = arith.cmpi ne, %zero, %arg0 : vector<4xi1>
232  return %res : vector<4xi1>
233}
234
235// Test case: Folding of comparisons with equal operands.
236// CHECK-LABEL: @cmpi_equal_operands
237//   CHECK-DAG:   %[[T:.*]] = arith.constant true
238//   CHECK-DAG:   %[[F:.*]] = arith.constant false
239//       CHECK:   return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],
240//  CHECK-SAME:          %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]
241func.func @cmpi_equal_operands(%arg0: i64)
242    -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
243  %0 = arith.cmpi eq, %arg0, %arg0 : i64
244  %1 = arith.cmpi sle, %arg0, %arg0 : i64
245  %2 = arith.cmpi sge, %arg0, %arg0 : i64
246  %3 = arith.cmpi ule, %arg0, %arg0 : i64
247  %4 = arith.cmpi uge, %arg0, %arg0 : i64
248  %5 = arith.cmpi ne, %arg0, %arg0 : i64
249  %6 = arith.cmpi slt, %arg0, %arg0 : i64
250  %7 = arith.cmpi sgt, %arg0, %arg0 : i64
251  %8 = arith.cmpi ult, %arg0, %arg0 : i64
252  %9 = arith.cmpi ugt, %arg0, %arg0 : i64
253  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9
254      : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
255}
256
257// Test case: Folding of comparisons with equal vector operands.
258// CHECK-LABEL: @cmpi_equal_vector_operands
259//   CHECK-DAG:   %[[T:.*]] = arith.constant dense<true>
260//   CHECK-DAG:   %[[F:.*]] = arith.constant dense<false>
261//       CHECK:   return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],
262//  CHECK-SAME:          %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]
263func.func @cmpi_equal_vector_operands(%arg0: vector<1x8xi64>)
264    -> (vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
265        vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
266	vector<1x8xi1>, vector<1x8xi1>) {
267  %0 = arith.cmpi eq, %arg0, %arg0 : vector<1x8xi64>
268  %1 = arith.cmpi sle, %arg0, %arg0 : vector<1x8xi64>
269  %2 = arith.cmpi sge, %arg0, %arg0 : vector<1x8xi64>
270  %3 = arith.cmpi ule, %arg0, %arg0 : vector<1x8xi64>
271  %4 = arith.cmpi uge, %arg0, %arg0 : vector<1x8xi64>
272  %5 = arith.cmpi ne, %arg0, %arg0 : vector<1x8xi64>
273  %6 = arith.cmpi slt, %arg0, %arg0 : vector<1x8xi64>
274  %7 = arith.cmpi sgt, %arg0, %arg0 : vector<1x8xi64>
275  %8 = arith.cmpi ult, %arg0, %arg0 : vector<1x8xi64>
276  %9 = arith.cmpi ugt, %arg0, %arg0 : vector<1x8xi64>
277  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9
278      : vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
279        vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
280	vector<1x8xi1>, vector<1x8xi1>
281}
282
283// -----
284
285// Test case: Move constant to the right side.
286// CHECK-LABEL: @cmpi_const_right(
287//  CHECK-SAME: %[[ARG:.*]]:
288//       CHECK:   %[[C:.*]] = arith.constant 1 : i64
289//       CHECK:   %[[R0:.*]] = arith.cmpi eq, %[[ARG]], %[[C]] : i64
290//       CHECK:   %[[R1:.*]] = arith.cmpi sge, %[[ARG]], %[[C]] : i64
291//       CHECK:   %[[R2:.*]] = arith.cmpi sle, %[[ARG]], %[[C]] : i64
292//       CHECK:   %[[R3:.*]] = arith.cmpi uge, %[[ARG]], %[[C]] : i64
293//       CHECK:   %[[R4:.*]] = arith.cmpi ule, %[[ARG]], %[[C]] : i64
294//       CHECK:   %[[R5:.*]] = arith.cmpi ne, %[[ARG]], %[[C]] : i64
295//       CHECK:   %[[R6:.*]] = arith.cmpi sgt, %[[ARG]], %[[C]] : i64
296//       CHECK:   %[[R7:.*]] = arith.cmpi slt, %[[ARG]], %[[C]] : i64
297//       CHECK:   %[[R8:.*]] = arith.cmpi ugt, %[[ARG]], %[[C]] : i64
298//       CHECK:   %[[R9:.*]] = arith.cmpi ult, %[[ARG]], %[[C]] : i64
299//       CHECK:   return %[[R0]], %[[R1]], %[[R2]], %[[R3]], %[[R4]],
300//  CHECK-SAME:          %[[R5]], %[[R6]], %[[R7]], %[[R8]], %[[R9]]
301func.func @cmpi_const_right(%arg0: i64)
302    -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
303  %c1 = arith.constant 1 : i64
304  %0 = arith.cmpi eq, %c1, %arg0 : i64
305  %1 = arith.cmpi sle, %c1, %arg0 : i64
306  %2 = arith.cmpi sge, %c1, %arg0 : i64
307  %3 = arith.cmpi ule, %c1, %arg0 : i64
308  %4 = arith.cmpi uge, %c1, %arg0 : i64
309  %5 = arith.cmpi ne, %c1, %arg0 : i64
310  %6 = arith.cmpi slt, %c1, %arg0 : i64
311  %7 = arith.cmpi sgt, %c1, %arg0 : i64
312  %8 = arith.cmpi ult, %c1, %arg0 : i64
313  %9 = arith.cmpi ugt, %c1, %arg0 : i64
314  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9
315      : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
316}
317
318// -----
319
320// CHECK-LABEL: @cmpOfExtSI(
321//  CHECK-NEXT:   return %arg0
322func.func @cmpOfExtSI(%arg0: i1) -> i1 {
323  %ext = arith.extsi %arg0 : i1 to i64
324  %c0 = arith.constant 0 : i64
325  %res = arith.cmpi ne, %ext, %c0 : i64
326  return %res : i1
327}
328
329// CHECK-LABEL: @cmpOfExtUI(
330//  CHECK-NEXT:   return %arg0
331func.func @cmpOfExtUI(%arg0: i1) -> i1 {
332  %ext = arith.extui %arg0 : i1 to i64
333  %c0 = arith.constant 0 : i64
334  %res = arith.cmpi ne, %ext, %c0 : i64
335  return %res : i1
336}
337
338// -----
339
340// CHECK-LABEL: @cmpOfExtSIVector(
341//  CHECK-NEXT:   return %arg0
342func.func @cmpOfExtSIVector(%arg0: vector<4xi1>) -> vector<4xi1> {
343  %ext = arith.extsi %arg0 : vector<4xi1> to vector<4xi64>
344  %c0 = arith.constant dense<0> : vector<4xi64>
345  %res = arith.cmpi ne, %ext, %c0 : vector<4xi64>
346  return %res : vector<4xi1>
347}
348
349// CHECK-LABEL: @cmpOfExtUIVector(
350//  CHECK-NEXT:   return %arg0
351func.func @cmpOfExtUIVector(%arg0: vector<4xi1>) -> vector<4xi1> {
352  %ext = arith.extui %arg0 : vector<4xi1> to vector<4xi64>
353  %c0 = arith.constant dense<0> : vector<4xi64>
354  %res = arith.cmpi ne, %ext, %c0 : vector<4xi64>
355  return %res : vector<4xi1>
356}
357
358// -----
359
360// CHECK-LABEL: @extSIOfExtUI
361//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
362//       CHECK:   return %[[res]]
363func.func @extSIOfExtUI(%arg0: i1) -> i64 {
364  %ext1 = arith.extui %arg0 : i1 to i8
365  %ext2 = arith.extsi %ext1 : i8 to i64
366  return %ext2 : i64
367}
368
369// CHECK-LABEL: @extUIOfExtUI
370//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
371//       CHECK:   return %[[res]]
372func.func @extUIOfExtUI(%arg0: i1) -> i64 {
373  %ext1 = arith.extui %arg0 : i1 to i8
374  %ext2 = arith.extui %ext1 : i8 to i64
375  return %ext2 : i64
376}
377
378// CHECK-LABEL: @extSIOfExtSI
379//       CHECK:   %[[res:.+]] = arith.extsi %arg0 : i1 to i64
380//       CHECK:   return %[[res]]
381func.func @extSIOfExtSI(%arg0: i1) -> i64 {
382  %ext1 = arith.extsi %arg0 : i1 to i8
383  %ext2 = arith.extsi %ext1 : i8 to i64
384  return %ext2 : i64
385}
386
387// -----
388
389// CHECK-LABEL: @cmpIExtSINE
390//       CHECK:  %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
391//       CHECK:   return %[[comb]]
392func.func @cmpIExtSINE(%arg0: i8, %arg1: i8) -> i1 {
393  %ext0 = arith.extsi %arg0 : i8 to i64
394  %ext1 = arith.extsi %arg1 : i8 to i64
395  %res = arith.cmpi ne, %ext0, %ext1 : i64
396  return %res : i1
397}
398
399// CHECK-LABEL: @cmpIExtSIEQ
400//       CHECK:  %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
401//       CHECK:   return %[[comb]]
402func.func @cmpIExtSIEQ(%arg0: i8, %arg1: i8) -> i1 {
403  %ext0 = arith.extsi %arg0 : i8 to i64
404  %ext1 = arith.extsi %arg1 : i8 to i64
405  %res = arith.cmpi eq, %ext0, %ext1 : i64
406  return %res : i1
407}
408
409// CHECK-LABEL: @cmpIExtUINE
410//       CHECK:  %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
411//       CHECK:   return %[[comb]]
412func.func @cmpIExtUINE(%arg0: i8, %arg1: i8) -> i1 {
413  %ext0 = arith.extui %arg0 : i8 to i64
414  %ext1 = arith.extui %arg1 : i8 to i64
415  %res = arith.cmpi ne, %ext0, %ext1 : i64
416  return %res : i1
417}
418
419// CHECK-LABEL: @cmpIExtUIEQ
420//       CHECK:  %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
421//       CHECK:   return %[[comb]]
422func.func @cmpIExtUIEQ(%arg0: i8, %arg1: i8) -> i1 {
423  %ext0 = arith.extui %arg0 : i8 to i64
424  %ext1 = arith.extui %arg1 : i8 to i64
425  %res = arith.cmpi eq, %ext0, %ext1 : i64
426  return %res : i1
427}
428
429// CHECK-LABEL: @cmpIFoldEQ
430//       CHECK:  %[[res:.+]] = arith.constant dense<[true, true, false]> : vector<3xi1>
431//       CHECK:   return %[[res]]
432func.func @cmpIFoldEQ() -> vector<3xi1> {
433  %lhs = arith.constant dense<[1, 2, 3]> : vector<3xi32>
434  %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>
435  %res = arith.cmpi eq, %lhs, %rhs : vector<3xi32>
436  return %res : vector<3xi1>
437}
438
439// CHECK-LABEL: @cmpIFoldNE
440//       CHECK:  %[[res:.+]] = arith.constant dense<[false, false, true]> : vector<3xi1>
441//       CHECK:   return %[[res]]
442func.func @cmpIFoldNE() -> vector<3xi1> {
443  %lhs = arith.constant dense<[1, 2, 3]> : vector<3xi32>
444  %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>
445  %res = arith.cmpi ne, %lhs, %rhs : vector<3xi32>
446  return %res : vector<3xi1>
447}
448
449// CHECK-LABEL: @cmpIFoldSGE
450//       CHECK:  %[[res:.+]] = arith.constant dense<[true, true, false]> : vector<3xi1>
451//       CHECK:   return %[[res]]
452func.func @cmpIFoldSGE() -> vector<3xi1> {
453  %lhs = arith.constant dense<2> : vector<3xi32>
454  %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>
455  %res = arith.cmpi sge, %lhs, %rhs : vector<3xi32>
456  return %res : vector<3xi1>
457}
458
459// CHECK-LABEL: @cmpIFoldULT
460//       CHECK:  %[[res:.+]] = arith.constant dense<false> : vector<3xi1>
461//       CHECK:   return %[[res]]
462func.func @cmpIFoldULT() -> vector<3xi1> {
463  %lhs = arith.constant dense<2> : vector<3xi32>
464  %rhs = arith.constant dense<1> : vector<3xi32>
465  %res = arith.cmpi ult, %lhs, %rhs : vector<3xi32>
466  return %res : vector<3xi1>
467}
468
469// -----
470
471// CHECK-LABEL: @andOfExtSI
472//       CHECK:  %[[comb:.+]] = arith.andi %arg0, %arg1 : i8
473//       CHECK:  %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64
474//       CHECK:   return %[[ext]]
475func.func @andOfExtSI(%arg0: i8, %arg1: i8) -> i64 {
476  %ext0 = arith.extsi %arg0 : i8 to i64
477  %ext1 = arith.extsi %arg1 : i8 to i64
478  %res = arith.andi %ext0, %ext1 : i64
479  return %res : i64
480}
481
482// CHECK-LABEL: @andOfExtUI
483//       CHECK:  %[[comb:.+]] = arith.andi %arg0, %arg1 : i8
484//       CHECK:  %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64
485//       CHECK:   return %[[ext]]
486func.func @andOfExtUI(%arg0: i8, %arg1: i8) -> i64 {
487  %ext0 = arith.extui %arg0 : i8 to i64
488  %ext1 = arith.extui %arg1 : i8 to i64
489  %res = arith.andi %ext0, %ext1 : i64
490  return %res : i64
491}
492
493// CHECK-LABEL: @orOfExtSI
494//       CHECK:  %[[comb:.+]] = arith.ori %arg0, %arg1 : i8
495//       CHECK:  %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64
496//       CHECK:   return %[[ext]]
497func.func @orOfExtSI(%arg0: i8, %arg1: i8) -> i64 {
498  %ext0 = arith.extsi %arg0 : i8 to i64
499  %ext1 = arith.extsi %arg1 : i8 to i64
500  %res = arith.ori %ext0, %ext1 : i64
501  return %res : i64
502}
503
504// CHECK-LABEL: @orOfExtUI
505//       CHECK:  %[[comb:.+]] = arith.ori %arg0, %arg1 : i8
506//       CHECK:  %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64
507//       CHECK:   return %[[ext]]
508func.func @orOfExtUI(%arg0: i8, %arg1: i8) -> i64 {
509  %ext0 = arith.extui %arg0 : i8 to i64
510  %ext1 = arith.extui %arg1 : i8 to i64
511  %res = arith.ori %ext0, %ext1 : i64
512  return %res : i64
513}
514
515// -----
516
517// CHECK-LABEL: @indexCastOfSignExtend
518//       CHECK:   %[[res:.+]] = arith.index_cast %arg0 : i8 to index
519//       CHECK:   return %[[res]]
520func.func @indexCastOfSignExtend(%arg0: i8) -> index {
521  %ext = arith.extsi %arg0 : i8 to i16
522  %idx = arith.index_cast %ext : i16 to index
523  return %idx : index
524}
525
526// CHECK-LABEL: @indexCastUIOfUnsignedExtend
527//       CHECK:   %[[res:.+]] = arith.index_castui %arg0 : i8 to index
528//       CHECK:   return %[[res]]
529func.func @indexCastUIOfUnsignedExtend(%arg0: i8) -> index {
530  %ext = arith.extui %arg0 : i8 to i16
531  %idx = arith.index_castui %ext : i16 to index
532  return %idx : index
533}
534
535// CHECK-LABEL: @indexCastFold
536//       CHECK:   %[[res:.*]] = arith.constant -2 : index
537//       CHECK:   return %[[res]]
538func.func @indexCastFold() -> index {
539  %c-2 = arith.constant -2 : i8
540  %idx = arith.index_cast %c-2 : i8 to index
541  return %idx : index
542}
543
544// CHECK-LABEL: @indexCastFoldIndexToInt
545//       CHECK:   %[[res:.*]] = arith.constant 1 : i32
546//       CHECK:   return %[[res]]
547func.func @indexCastFoldIndexToInt() -> i32 {
548  %c1 = arith.constant 1 : index
549  %int = arith.index_cast %c1 : index to i32
550  return %int : i32
551}
552
553// CHECK-LABEL: @indexCastFoldSplatVector
554//       CHECK:   %[[res:.*]] = arith.constant dense<42> : vector<3xindex>
555//       CHECK:   return %[[res]] : vector<3xindex>
556func.func @indexCastFoldSplatVector() -> vector<3xindex> {
557  %cst = arith.constant dense<42> : vector<3xi32>
558  %int = arith.index_cast %cst : vector<3xi32> to vector<3xindex>
559  return %int : vector<3xindex>
560}
561
562// CHECK-LABEL: @indexCastFoldVector
563//       CHECK:   %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xindex>
564//       CHECK:   return %[[res]] : vector<3xindex>
565func.func @indexCastFoldVector() -> vector<3xindex> {
566  %cst = arith.constant dense<[1, 2, 3]> : vector<3xi32>
567  %int = arith.index_cast %cst : vector<3xi32> to vector<3xindex>
568  return %int : vector<3xindex>
569}
570
571// CHECK-LABEL: @indexCastFoldSplatVectorIndexToInt
572//       CHECK:   %[[res:.*]] = arith.constant dense<42> : vector<3xi32>
573//       CHECK:   return %[[res]] : vector<3xi32>
574func.func @indexCastFoldSplatVectorIndexToInt() -> vector<3xi32> {
575  %cst = arith.constant dense<42> : vector<3xindex>
576  %int = arith.index_cast %cst : vector<3xindex> to vector<3xi32>
577  return %int : vector<3xi32>
578}
579
580// CHECK-LABEL: @indexCastFoldVectorIndexToInt
581//       CHECK:   %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>
582//       CHECK:   return %[[res]] : vector<3xi32>
583func.func @indexCastFoldVectorIndexToInt() -> vector<3xi32> {
584  %cst = arith.constant dense<[1, 2, 3]> : vector<3xindex>
585  %int = arith.index_cast %cst : vector<3xindex> to vector<3xi32>
586  return %int : vector<3xi32>
587}
588
589// CHECK-LABEL: @indexCastUIFold
590//       CHECK:   %[[res:.*]] = arith.constant 254 : index
591//       CHECK:   return %[[res]]
592func.func @indexCastUIFold() -> index {
593  %c-2 = arith.constant -2 : i8
594  %idx = arith.index_castui %c-2 : i8 to index
595  return %idx : index
596}
597
598// CHECK-LABEL: @indexCastUIFoldSplatVector
599//       CHECK:   %[[res:.*]] = arith.constant dense<42> : vector<3xindex>
600//       CHECK:   return %[[res]] : vector<3xindex>
601func.func @indexCastUIFoldSplatVector() -> vector<3xindex> {
602  %cst = arith.constant dense<42> : vector<3xi32>
603  %int = arith.index_castui %cst : vector<3xi32> to vector<3xindex>
604  return %int : vector<3xindex>
605}
606
607// CHECK-LABEL: @indexCastUIFoldVector
608//       CHECK:   %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xindex>
609//       CHECK:   return %[[res]] : vector<3xindex>
610func.func @indexCastUIFoldVector() -> vector<3xindex> {
611  %cst = arith.constant dense<[1, 2, 3]> : vector<3xi32>
612  %int = arith.index_castui %cst : vector<3xi32> to vector<3xindex>
613  return %int : vector<3xindex>
614}
615
616// CHECK-LABEL: @indexCastUIFoldIndexToInt
617//       CHECK:   %[[res:.*]] = arith.constant 1 : i32
618//       CHECK:   return %[[res]]
619func.func @indexCastUIFoldIndexToInt() -> i32 {
620  %c1 = arith.constant 1 : index
621  %int = arith.index_castui %c1 : index to i32
622  return %int : i32
623}
624
625// CHECK-LABEL: @indexCastUIFoldSplatVectorIndexToInt
626//       CHECK:   %[[res:.*]] = arith.constant dense<42> : vector<3xi32>
627//       CHECK:   return %[[res]] : vector<3xi32>
628func.func @indexCastUIFoldSplatVectorIndexToInt() -> vector<3xi32> {
629  %cst = arith.constant dense<42> : vector<3xindex>
630  %int = arith.index_castui %cst : vector<3xindex> to vector<3xi32>
631  return %int : vector<3xi32>
632}
633
634// CHECK-LABEL: @indexCastUIFoldVectorIndexToInt
635//       CHECK:   %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>
636//       CHECK:   return %[[res]] : vector<3xi32>
637func.func @indexCastUIFoldVectorIndexToInt() -> vector<3xi32> {
638  %cst = arith.constant dense<[1, 2, 3]> : vector<3xindex>
639  %int = arith.index_castui %cst : vector<3xindex> to vector<3xi32>
640  return %int : vector<3xi32>
641}
642
643// CHECK-LABEL: @signExtendConstant
644//       CHECK:   %[[cres:.+]] = arith.constant -2 : i16
645//       CHECK:   return %[[cres]]
646func.func @signExtendConstant() -> i16 {
647  %c-2 = arith.constant -2 : i8
648  %ext = arith.extsi %c-2 : i8 to i16
649  return %ext : i16
650}
651
652// CHECK-LABEL: @signExtendConstantSplat
653//       CHECK:   %[[cres:.+]] = arith.constant dense<-2> : vector<4xi16>
654//       CHECK:   return %[[cres]]
655func.func @signExtendConstantSplat() -> vector<4xi16> {
656  %c-2 = arith.constant -2 : i8
657  %splat = vector.splat %c-2 : vector<4xi8>
658  %ext = arith.extsi %splat : vector<4xi8> to vector<4xi16>
659  return %ext : vector<4xi16>
660}
661
662// CHECK-LABEL: @signExtendConstantVector
663//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
664//       CHECK:   return %[[cres]]
665func.func @signExtendConstantVector() -> vector<4xi16> {
666  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
667  %ext = arith.extsi %vector : vector<4xi8> to vector<4xi16>
668  return %ext : vector<4xi16>
669}
670
671// CHECK-LABEL: @unsignedExtendConstant
672//       CHECK:   %[[cres:.+]] = arith.constant 2 : i16
673//       CHECK:   return %[[cres]]
674func.func @unsignedExtendConstant() -> i16 {
675  %c2 = arith.constant 2 : i8
676  %ext = arith.extui %c2 : i8 to i16
677  return %ext : i16
678}
679
680// CHECK-LABEL: @unsignedExtendConstantSplat
681//       CHECK:   %[[cres:.+]] = arith.constant dense<2> : vector<4xi16>
682//       CHECK:   return %[[cres]]
683func.func @unsignedExtendConstantSplat() -> vector<4xi16> {
684  %c2 = arith.constant 2 : i8
685  %splat = vector.splat %c2 : vector<4xi8>
686  %ext = arith.extui %splat : vector<4xi8> to vector<4xi16>
687  return %ext : vector<4xi16>
688}
689
690// CHECK-LABEL: @unsignedExtendConstantVector
691//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
692//       CHECK:   return %[[cres]]
693func.func @unsignedExtendConstantVector() -> vector<4xi16> {
694  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
695  %ext = arith.extui %vector : vector<4xi8> to vector<4xi16>
696  return %ext : vector<4xi16>
697}
698
699// CHECK-LABEL: @extFPConstant
700//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : f64
701//       CHECK:   return %[[cres]]
702func.func @extFPConstant() -> f64 {
703  %cst = arith.constant 1.000000e+00 : f32
704  %0 = arith.extf %cst : f32 to f64
705  return %0 : f64
706}
707
708// CHECK-LABEL: @extFPVectorConstant
709//       CHECK:   %[[cres:.+]] = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf128>
710//       CHECK:   return %[[cres]]
711func.func @extFPVectorConstant() -> vector<2xf128> {
712  %cst = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf80>
713  %0 = arith.extf %cst : vector<2xf80> to vector<2xf128>
714  return %0 : vector<2xf128>
715}
716
717// TODO: We should also add a test for not folding arith.extf on information loss.
718// This may happen when extending f8E5M2FNUZ to f16.
719
720// CHECK-LABEL: @truncConstant
721//       CHECK:   %[[cres:.+]] = arith.constant -2 : i16
722//       CHECK:   return %[[cres]]
723func.func @truncConstant(%arg0: i8) -> i16 {
724  %c-2 = arith.constant -2 : i32
725  %tr = arith.trunci %c-2 : i32 to i16
726  return %tr : i16
727}
728
729// CHECK-LABEL: @truncExtui
730//       CHECK-NOT:  trunci
731//       CHECK:   return  %arg0
732func.func @truncExtui(%arg0: i32) -> i32 {
733  %extui = arith.extui %arg0 : i32 to i64
734  %trunci = arith.trunci %extui : i64 to i32
735  return %trunci : i32
736}
737
738// CHECK-LABEL: @truncExtui2
739//       CHECK:  %[[ARG0:.+]]: i32
740//       CHECK:  %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16
741//       CHECK:   return  %[[CST:.*]]
742func.func @truncExtui2(%arg0: i32) -> i16 {
743  %extui = arith.extui %arg0 : i32 to i64
744  %trunci = arith.trunci %extui : i64 to i16
745  return %trunci : i16
746}
747
748// CHECK-LABEL: @truncExtui3
749//       CHECK:  %[[ARG0:.+]]: i8
750//       CHECK:  %[[CST:.*]] = arith.extui %[[ARG0:.+]] : i8 to i16
751//       CHECK:   return  %[[CST:.*]] : i16
752func.func @truncExtui3(%arg0: i8) -> i16 {
753  %extui = arith.extui %arg0 : i8 to i32
754  %trunci = arith.trunci %extui : i32 to i16
755  return %trunci : i16
756}
757
758// CHECK-LABEL: @truncExtuiVector
759//       CHECK:  %[[ARG0:.+]]: vector<2xi32>
760//       CHECK:  %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16>
761//       CHECK:   return  %[[CST:.*]]
762func.func @truncExtuiVector(%arg0: vector<2xi32>) -> vector<2xi16> {
763  %extsi = arith.extui %arg0 : vector<2xi32> to vector<2xi64>
764  %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16>
765  return %trunci : vector<2xi16>
766}
767
768// CHECK-LABEL: @truncExtsi
769//       CHECK-NOT:  trunci
770//       CHECK:   return  %arg0
771func.func @truncExtsi(%arg0: i32) -> i32 {
772  %extsi = arith.extsi %arg0 : i32 to i64
773  %trunci = arith.trunci %extsi : i64 to i32
774  return %trunci : i32
775}
776
777// CHECK-LABEL: @truncExtsi2
778//       CHECK:  %[[ARG0:.+]]: i32
779//       CHECK:  %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16
780//       CHECK:   return  %[[CST:.*]]
781func.func @truncExtsi2(%arg0: i32) -> i16 {
782  %extsi = arith.extsi %arg0 : i32 to i64
783  %trunci = arith.trunci %extsi : i64 to i16
784  return %trunci : i16
785}
786
787// CHECK-LABEL: @truncExtsi3
788//       CHECK:  %[[ARG0:.+]]: i8
789//       CHECK:  %[[CST:.*]] = arith.extsi %[[ARG0:.+]] : i8 to i16
790//       CHECK:   return  %[[CST:.*]] : i16
791func.func @truncExtsi3(%arg0: i8) -> i16 {
792  %extsi = arith.extsi %arg0 : i8 to i32
793  %trunci = arith.trunci %extsi : i32 to i16
794  return %trunci : i16
795}
796
797// CHECK-LABEL: @truncExtsiVector
798//       CHECK:  %[[ARG0:.+]]: vector<2xi32>
799//       CHECK:  %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16>
800//       CHECK:   return  %[[CST:.*]]
801func.func @truncExtsiVector(%arg0: vector<2xi32>) -> vector<2xi16> {
802  %extsi = arith.extsi %arg0 : vector<2xi32> to vector<2xi64>
803  %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16>
804  return %trunci : vector<2xi16>
805}
806
807// CHECK-LABEL: @truncConstantSplat
808//       CHECK:   %[[cres:.+]] = arith.constant dense<-2> : vector<4xi8>
809//       CHECK:   return %[[cres]]
810func.func @truncConstantSplat() -> vector<4xi8> {
811  %c-2 = arith.constant -2 : i16
812  %splat = vector.splat %c-2 : vector<4xi16>
813  %trunc = arith.trunci %splat : vector<4xi16> to vector<4xi8>
814  return %trunc : vector<4xi8>
815}
816
817// CHECK-LABEL: @truncConstantVector
818//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
819//       CHECK:   return %[[cres]]
820func.func @truncConstantVector() -> vector<4xi8> {
821  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
822  %trunc = arith.trunci %vector : vector<4xi16> to vector<4xi8>
823  return %trunc : vector<4xi8>
824}
825
826// CHECK-LABEL: @truncTrunc
827//       CHECK:   %[[cres:.+]] = arith.trunci %arg0 : i64 to i8
828//       CHECK:   return %[[cres]]
829func.func @truncTrunc(%arg0: i64) -> i8 {
830  %tr1 = arith.trunci %arg0 : i64 to i32
831  %tr2 = arith.trunci %tr1 : i32 to i8
832  return %tr2 : i8
833}
834
835// CHECK-LABEL: @truncFPConstant
836//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
837//       CHECK:   return %[[cres]]
838func.func @truncFPConstant() -> bf16 {
839  %cst = arith.constant 1.000000e+00 : f32
840  %0 = arith.truncf %cst : f32 to bf16
841  return %0 : bf16
842}
843
844// CHECK-LABEL: @truncFPToNearestEvenConstant
845//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
846//       CHECK:   return %[[cres]]
847func.func @truncFPToNearestEvenConstant() -> bf16 {
848  %cst = arith.constant 1.000000e+00 : f32
849  %0 = arith.truncf %cst to_nearest_even : f32 to bf16
850  return %0 : bf16
851}
852
853// CHECK-LABEL: @truncFPDownwardConstant
854//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
855//       CHECK:   return %[[cres]]
856func.func @truncFPDownwardConstant() -> bf16 {
857  %cst = arith.constant 1.000000e+00 : f32
858  %0 = arith.truncf %cst downward : f32 to bf16
859  return %0 : bf16
860}
861
862// CHECK-LABEL: @truncFPUpwardConstant
863//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
864//       CHECK:   return %[[cres]]
865func.func @truncFPUpwardConstant() -> bf16 {
866  %cst = arith.constant 1.000000e+00 : f32
867  %0 = arith.truncf %cst upward : f32 to bf16
868  return %0 : bf16
869}
870
871// CHECK-LABEL: @truncFPTowardZeroConstant
872//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
873//       CHECK:   return %[[cres]]
874func.func @truncFPTowardZeroConstant() -> bf16 {
875  %cst = arith.constant 1.000000e+00 : f32
876  %0 = arith.truncf %cst toward_zero : f32 to bf16
877  return %0 : bf16
878}
879
880// CHECK-LABEL: @truncFPToNearestAwayConstant
881//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
882//       CHECK:   return %[[cres]]
883func.func @truncFPToNearestAwayConstant() -> bf16 {
884  %cst = arith.constant 1.000000e+00 : f32
885  %0 = arith.truncf %cst to_nearest_away : f32 to bf16
886  return %0 : bf16
887}
888
889// CHECK-LABEL: @truncFPVectorConstant
890//       CHECK:   %[[cres:.+]] = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xbf16>
891//       CHECK:   return %[[cres]]
892func.func @truncFPVectorConstant() -> vector<2xbf16> {
893  %cst = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf32>
894  %0 = arith.truncf %cst : vector<2xf32> to vector<2xbf16>
895  return %0 : vector<2xbf16>
896}
897
898// Test that cases with rounding are NOT propagated
899// CHECK-LABEL: @truncFPConstantRounding
900//       CHECK:   arith.constant 1.444000e+25 : f32
901//       CHECK:   truncf
902func.func @truncFPConstantRounding() -> bf16 {
903  %cst = arith.constant 1.444000e+25 : f32
904  %0 = arith.truncf %cst : f32 to bf16
905  return %0 : bf16
906}
907
908// CHECK-LABEL: @tripleAddAdd
909//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
910//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
911//       CHECK:   return %[[add]]
912func.func @tripleAddAdd(%arg0: index) -> index {
913  %c17 = arith.constant 17 : index
914  %c42 = arith.constant 42 : index
915  %add1 = arith.addi %c17, %arg0 : index
916  %add2 = arith.addi %c42, %add1 : index
917  return %add2 : index
918}
919
920// CHECK-LABEL: @tripleAddAddOvf1
921//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
922//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index
923//       CHECK:   return %[[add]]
924func.func @tripleAddAddOvf1(%arg0: index) -> index {
925  %c17 = arith.constant 17 : index
926  %c42 = arith.constant 42 : index
927  %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index
928  %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index
929  return %add2 : index
930}
931
932// CHECK-LABEL: @tripleAddAddOvf2
933//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
934//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
935//       CHECK:   return %[[add]]
936func.func @tripleAddAddOvf2(%arg0: index) -> index {
937  %c17 = arith.constant 17 : index
938  %c42 = arith.constant 42 : index
939  %add1 = arith.addi %c17, %arg0 overflow<nsw> : index
940  %add2 = arith.addi %c42, %add1 overflow<nuw> : index
941  return %add2 : index
942}
943
944
945// CHECK-LABEL: @foldSubXX_tensor
946//       CHECK:   %[[c0:.+]] = arith.constant dense<0> : tensor<10xi32>
947//       CHECK:   %[[sub:.+]] = arith.subi
948//       CHECK:   return %[[c0]], %[[sub]]
949func.func @foldSubXX_tensor(%static : tensor<10xi32>, %dyn : tensor<?x?xi32>) -> (tensor<10xi32>, tensor<?x?xi32>) {
950  %static_sub = arith.subi %static, %static : tensor<10xi32>
951  %dyn_sub = arith.subi %dyn, %dyn : tensor<?x?xi32>
952  return %static_sub, %dyn_sub : tensor<10xi32>, tensor<?x?xi32>
953}
954
955// CHECK-LABEL: @foldSubXX_vector
956//       CHECK-DAG:  %[[c0:.+]] = arith.constant dense<0> : vector<8xi32>
957//       CHECK-DAG:  %[[c0_scalable:.+]] = arith.constant dense<0> : vector<[4]xi32>
958//       CHECK:   return %[[c0]], %[[c0_scalable]]
959func.func @foldSubXX_vector(%static : vector<8xi32>, %dyn : vector<[4]xi32>) -> (vector<8xi32>, vector<[4]xi32>) {
960  %static_sub = arith.subi %static, %static : vector<8xi32>
961  %dyn_sub = arith.subi %dyn, %dyn : vector<[4]xi32>
962  return %static_sub, %dyn_sub : vector<8xi32>, vector<[4]xi32>
963}
964
965// CHECK-LABEL: @tripleAddSub0
966//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
967//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
968//       CHECK:   return %[[add]]
969func.func @tripleAddSub0(%arg0: index) -> index {
970  %c17 = arith.constant 17 : index
971  %c42 = arith.constant 42 : index
972  %add1 = arith.subi %c17, %arg0 : index
973  %add2 = arith.addi %c42, %add1 : index
974  return %add2 : index
975}
976
977// CHECK-LABEL: @tripleAddSub0Ovf
978//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
979//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index
980//       CHECK:   return %[[add]]
981func.func @tripleAddSub0Ovf(%arg0: index) -> index {
982  %c17 = arith.constant 17 : index
983  %c42 = arith.constant 42 : index
984  %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index
985  %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index
986  return %add2 : index
987}
988
989// CHECK-LABEL: @tripleAddSub1
990//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
991//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
992//       CHECK:   return %[[add]]
993func.func @tripleAddSub1(%arg0: index) -> index {
994  %c17 = arith.constant 17 : index
995  %c42 = arith.constant 42 : index
996  %add1 = arith.subi %arg0, %c17 : index
997  %add2 = arith.addi %c42, %add1 : index
998  return %add2 : index
999}
1000
1001// CHECK-LABEL: @tripleAddSub1Ovf
1002//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
1003//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index
1004//       CHECK:   return %[[add]]
1005func.func @tripleAddSub1Ovf(%arg0: index) -> index {
1006  %c17 = arith.constant 17 : index
1007  %c42 = arith.constant 42 : index
1008  %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index
1009  %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index
1010  return %add2 : index
1011}
1012
1013// CHECK-LABEL: @tripleSubAdd0
1014//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
1015//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
1016//       CHECK:   return %[[add]]
1017func.func @tripleSubAdd0(%arg0: index) -> index {
1018  %c17 = arith.constant 17 : index
1019  %c42 = arith.constant 42 : index
1020  %add1 = arith.addi %c17, %arg0 : index
1021  %add2 = arith.subi %c42, %add1 : index
1022  return %add2 : index
1023}
1024
1025// CHECK-LABEL: @tripleSubAdd0Ovf
1026//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
1027//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index
1028//       CHECK:   return %[[add]]
1029func.func @tripleSubAdd0Ovf(%arg0: index) -> index {
1030  %c17 = arith.constant 17 : index
1031  %c42 = arith.constant 42 : index
1032  %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index
1033  %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index
1034  return %add2 : index
1035}
1036
1037// CHECK-LABEL: @tripleSubAdd1
1038//       CHECK:   %[[cres:.+]] = arith.constant -25 : index
1039//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
1040//       CHECK:   return %[[add]]
1041func.func @tripleSubAdd1(%arg0: index) -> index {
1042  %c17 = arith.constant 17 : index
1043  %c42 = arith.constant 42 : index
1044  %add1 = arith.addi %c17, %arg0 : index
1045  %add2 = arith.subi %add1, %c42 : index
1046  return %add2 : index
1047}
1048
1049// CHECK-LABEL: @subSub0
1050//       CHECK:   %[[c0:.+]] = arith.constant 0 : index
1051//       CHECK:   %[[add:.+]] = arith.subi %[[c0]], %arg1 : index
1052//       CHECK:   return %[[add]]
1053func.func @subSub0(%arg0: index, %arg1: index) -> index {
1054  %sub1 = arith.subi %arg0, %arg1 : index
1055  %sub2 = arith.subi %sub1, %arg0 : index
1056  return %sub2 : index
1057}
1058
1059// CHECK-LABEL: @subSub0Ovf
1060//       CHECK:   %[[c0:.+]] = arith.constant 0 : index
1061//       CHECK:   %[[add:.+]] = arith.subi %[[c0]], %arg1 overflow<nsw, nuw> : index
1062//       CHECK:   return %[[add]]
1063func.func @subSub0Ovf(%arg0: index, %arg1: index) -> index {
1064  %sub1 = arith.subi %arg0, %arg1 overflow<nsw, nuw> : index
1065  %sub2 = arith.subi %sub1, %arg0 overflow<nsw, nuw> : index
1066  return %sub2 : index
1067}
1068
1069// CHECK-LABEL: @tripleSubSub0
1070//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
1071//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
1072//       CHECK:   return %[[add]]
1073func.func @tripleSubSub0(%arg0: index) -> index {
1074  %c17 = arith.constant 17 : index
1075  %c42 = arith.constant 42 : index
1076  %add1 = arith.subi %c17, %arg0 : index
1077  %add2 = arith.subi %c42, %add1 : index
1078  return %add2 : index
1079}
1080
1081// CHECK-LABEL: @tripleSubSub0Ovf
1082//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
1083//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index
1084//       CHECK:   return %[[add]]
1085func.func @tripleSubSub0Ovf(%arg0: index) -> index {
1086  %c17 = arith.constant 17 : index
1087  %c42 = arith.constant 42 : index
1088  %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index
1089  %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index
1090  return %add2 : index
1091}
1092
1093
1094// CHECK-LABEL: @tripleSubSub1
1095//       CHECK:   %[[cres:.+]] = arith.constant -25 : index
1096//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
1097//       CHECK:   return %[[add]]
1098func.func @tripleSubSub1(%arg0: index) -> index {
1099  %c17 = arith.constant 17 : index
1100  %c42 = arith.constant 42 : index
1101  %add1 = arith.subi %c17, %arg0 : index
1102  %add2 = arith.subi %add1, %c42 : index
1103  return %add2 : index
1104}
1105
1106// CHECK-LABEL: @tripleSubSub1Ovf
1107//       CHECK:   %[[cres:.+]] = arith.constant -25 : index
1108//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index
1109//       CHECK:   return %[[add]]
1110func.func @tripleSubSub1Ovf(%arg0: index) -> index {
1111  %c17 = arith.constant 17 : index
1112  %c42 = arith.constant 42 : index
1113  %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index
1114  %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index
1115  return %add2 : index
1116}
1117
1118// CHECK-LABEL: @tripleSubSub2
1119//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
1120//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
1121//       CHECK:   return %[[add]]
1122func.func @tripleSubSub2(%arg0: index) -> index {
1123  %c17 = arith.constant 17 : index
1124  %c42 = arith.constant 42 : index
1125  %add1 = arith.subi %arg0, %c17 : index
1126  %add2 = arith.subi %c42, %add1 : index
1127  return %add2 : index
1128}
1129
1130// CHECK-LABEL: @tripleSubSub2Ovf
1131//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
1132//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index
1133//       CHECK:   return %[[add]]
1134func.func @tripleSubSub2Ovf(%arg0: index) -> index {
1135  %c17 = arith.constant 17 : index
1136  %c42 = arith.constant 42 : index
1137  %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index
1138  %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index
1139  return %add2 : index
1140}
1141
1142// CHECK-LABEL: @tripleSubSub3
1143//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
1144//       CHECK:   %[[add:.+]] = arith.subi %arg0, %[[cres]] : index
1145//       CHECK:   return %[[add]]
1146func.func @tripleSubSub3(%arg0: index) -> index {
1147  %c17 = arith.constant 17 : index
1148  %c42 = arith.constant 42 : index
1149  %add1 = arith.subi %arg0, %c17 : index
1150  %add2 = arith.subi %add1, %c42 : index
1151  return %add2 : index
1152}
1153
1154// CHECK-LABEL: @tripleSubSub3Ovf
1155//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
1156//       CHECK:   %[[add:.+]] = arith.subi %arg0, %[[cres]] overflow<nsw, nuw> : index
1157//       CHECK:   return %[[add]]
1158func.func @tripleSubSub3Ovf(%arg0: index) -> index {
1159  %c17 = arith.constant 17 : index
1160  %c42 = arith.constant 42 : index
1161  %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index
1162  %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index
1163  return %add2 : index
1164}
1165
1166// CHECK-LABEL: @subAdd1
1167//  CHECK-NEXT:   return %arg0
1168func.func @subAdd1(%arg0: index, %arg1 : index) -> index {
1169  %add = arith.addi %arg0, %arg1 : index
1170  %sub = arith.subi %add, %arg1 : index
1171  return %sub : index
1172}
1173
1174// CHECK-LABEL: @subAdd2
1175//  CHECK-NEXT:   return %arg1
1176func.func @subAdd2(%arg0: index, %arg1 : index) -> index {
1177  %add = arith.addi %arg0, %arg1 : index
1178  %sub = arith.subi %add, %arg0 : index
1179  return %sub : index
1180}
1181
1182// CHECK-LABEL: @doubleAddSub1
1183//  CHECK-NEXT:   return %arg0
1184func.func @doubleAddSub1(%arg0: index, %arg1 : index) -> index {
1185  %sub = arith.subi %arg0, %arg1 : index
1186  %add = arith.addi %sub, %arg1 : index
1187  return %add : index
1188}
1189
1190// CHECK-LABEL: @doubleAddSub2
1191//  CHECK-NEXT:   return %arg0
1192func.func @doubleAddSub2(%arg0: index, %arg1 : index) -> index {
1193  %sub = arith.subi %arg0, %arg1 : index
1194  %add = arith.addi %arg1, %sub : index
1195  return %add : index
1196}
1197
1198// CHECK-LABEL: @tripleMulIMulIIndex
1199//       CHECK:   %[[cres:.+]] = arith.constant 15 : index
1200//       CHECK:   %[[muli:.+]] = arith.muli %arg0, %[[cres]] : index
1201//       CHECK:   return %[[muli]]
1202func.func @tripleMulIMulIIndex(%arg0: index) -> index {
1203  %c3 = arith.constant 3 : index
1204  %c5 = arith.constant 5 : index
1205  %mul1 = arith.muli %arg0, %c3 : index
1206  %mul2 = arith.muli %mul1, %c5 : index
1207  return %mul2 : index
1208}
1209
1210// CHECK-LABEL: @tripleMulIMulII32
1211//       CHECK:   %[[cres:.+]] = arith.constant -21 : i32
1212//       CHECK:   %[[muli:.+]] = arith.muli %arg0, %[[cres]] : i32
1213//       CHECK:   return %[[muli]]
1214func.func @tripleMulIMulII32(%arg0: i32) -> i32 {
1215  %c_n3 = arith.constant -3 : i32
1216  %c7 = arith.constant 7 : i32
1217  %mul1 = arith.muli %arg0, %c_n3 : i32
1218  %mul2 = arith.muli %mul1, %c7 : i32
1219  return %mul2 : i32
1220}
1221
1222// CHECK-LABEL: @tripleMulLargeInt
1223//       CHECK:   %[[cres:.+]] = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020482 : i256
1224//       CHECK:   %[[addi:.+]] = arith.addi %arg0, %[[cres]] : i256
1225//       CHECK:   return %[[addi]]
1226func.func @tripleMulLargeInt(%arg0: i256) -> i256 {
1227  %0 = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020481 : i256
1228  %1 = arith.constant 1 : i256
1229  %2 = arith.addi %arg0, %0 : i256
1230  %3 = arith.addi %2, %1 : i256
1231  return %3 : i256
1232}
1233
1234// CHECK-LABEL: @addiMuliToSubiRhsI32
1235//  CHECK-SAME:   (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)
1236//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i32
1237//       CHECK:   return %[[SUB]]
1238func.func @addiMuliToSubiRhsI32(%arg0: i32, %arg1: i32) -> i32 {
1239  %c-1 = arith.constant -1 : i32
1240  %neg = arith.muli %arg1, %c-1 : i32
1241  %add = arith.addi %arg0, %neg : i32
1242  return %add : i32
1243}
1244
1245// CHECK-LABEL: @addiMuliToSubiRhsIndex
1246//  CHECK-SAME:   (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index)
1247//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index
1248//       CHECK:   return %[[SUB]]
1249func.func @addiMuliToSubiRhsIndex(%arg0: index, %arg1: index) -> index {
1250  %c-1 = arith.constant -1 : index
1251  %neg = arith.muli %arg1, %c-1 : index
1252  %add = arith.addi %arg0, %neg : index
1253  return %add : index
1254}
1255
1256// CHECK-LABEL: @addiMuliToSubiRhsVector
1257//  CHECK-SAME:   (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>)
1258//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64>
1259//       CHECK:   return %[[SUB]]
1260func.func @addiMuliToSubiRhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> {
1261  %c-1 = arith.constant dense<-1> : vector<3xi64>
1262  %neg = arith.muli %arg1, %c-1 : vector<3xi64>
1263  %add = arith.addi %arg0, %neg : vector<3xi64>
1264  return %add : vector<3xi64>
1265}
1266
1267// CHECK-LABEL: @addiMuliToSubiLhsI32
1268//  CHECK-SAME:   (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)
1269//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i32
1270//       CHECK:   return %[[SUB]]
1271func.func @addiMuliToSubiLhsI32(%arg0: i32, %arg1: i32) -> i32 {
1272  %c-1 = arith.constant -1 : i32
1273  %neg = arith.muli %arg1, %c-1 : i32
1274  %add = arith.addi %neg, %arg0 : i32
1275  return %add : i32
1276}
1277
1278// CHECK-LABEL: @addiMuliToSubiLhsIndex
1279//  CHECK-SAME:   (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index)
1280//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index
1281//       CHECK:   return %[[SUB]]
1282func.func @addiMuliToSubiLhsIndex(%arg0: index, %arg1: index) -> index {
1283  %c-1 = arith.constant -1 : index
1284  %neg = arith.muli %arg1, %c-1 : index
1285  %add = arith.addi %neg, %arg0 : index
1286  return %add : index
1287}
1288
1289// CHECK-LABEL: @addiMuliToSubiLhsVector
1290//  CHECK-SAME:   (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>)
1291//       CHECK:   %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64>
1292//       CHECK:   return %[[SUB]]
1293func.func @addiMuliToSubiLhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> {
1294  %c-1 = arith.constant dense<-1> : vector<3xi64>
1295  %neg = arith.muli %arg1, %c-1 : vector<3xi64>
1296  %add = arith.addi %neg, %arg0 : vector<3xi64>
1297  return %add : vector<3xi64>
1298}
1299
1300// CHECK-LABEL: @adduiExtendedZeroRhs
1301//  CHECK-NEXT:   %[[false:.+]] = arith.constant false
1302//  CHECK-NEXT:   return %arg0, %[[false]]
1303func.func @adduiExtendedZeroRhs(%arg0: i32) -> (i32, i1) {
1304  %zero = arith.constant 0 : i32
1305  %sum, %overflow = arith.addui_extended %arg0, %zero: i32, i1
1306  return %sum, %overflow : i32, i1
1307}
1308
1309// CHECK-LABEL: @adduiExtendedZeroRhsSplat
1310//  CHECK-NEXT:   %[[false:.+]] = arith.constant dense<false> : vector<4xi1>
1311//  CHECK-NEXT:   return %arg0, %[[false]]
1312func.func @adduiExtendedZeroRhsSplat(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi1>) {
1313  %zero = arith.constant dense<0> : vector<4xi32>
1314  %sum, %overflow = arith.addui_extended %arg0, %zero: vector<4xi32>, vector<4xi1>
1315  return %sum, %overflow : vector<4xi32>, vector<4xi1>
1316}
1317
1318// CHECK-LABEL: @adduiExtendedZeroLhs
1319//  CHECK-NEXT:   %[[false:.+]] = arith.constant false
1320//  CHECK-NEXT:   return %arg0, %[[false]]
1321func.func @adduiExtendedZeroLhs(%arg0: i32) -> (i32, i1) {
1322  %zero = arith.constant 0 : i32
1323  %sum, %overflow = arith.addui_extended %zero, %arg0: i32, i1
1324  return %sum, %overflow : i32, i1
1325}
1326
1327// CHECK-LABEL: @adduiExtendedUnusedOverflowScalar
1328//  CHECK-SAME:   (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32) -> i32
1329//  CHECK-NEXT:   %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : i32
1330//  CHECK-NEXT:   return %[[RES]] : i32
1331func.func @adduiExtendedUnusedOverflowScalar(%arg0: i32, %arg1: i32) -> i32 {
1332  %sum, %overflow = arith.addui_extended %arg0, %arg1: i32, i1
1333  return %sum : i32
1334}
1335
1336// CHECK-LABEL: @adduiExtendedUnusedOverflowVector
1337//  CHECK-SAME:   (%[[LHS:.+]]: vector<3xi32>, %[[RHS:.+]]: vector<3xi32>) -> vector<3xi32>
1338//  CHECK-NEXT:   %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : vector<3xi32>
1339//  CHECK-NEXT:   return %[[RES]] : vector<3xi32>
1340func.func @adduiExtendedUnusedOverflowVector(%arg0: vector<3xi32>, %arg1: vector<3xi32>) -> vector<3xi32> {
1341  %sum, %overflow = arith.addui_extended %arg0, %arg1: vector<3xi32>, vector<3xi1>
1342  return %sum : vector<3xi32>
1343}
1344
1345// CHECK-LABEL: @adduiExtendedConstants
1346//  CHECK-DAG:    %[[false:.+]] = arith.constant false
1347//  CHECK-DAG:    %[[c50:.+]] = arith.constant 50 : i32
1348//  CHECK-NEXT:   return %[[c50]], %[[false]]
1349func.func @adduiExtendedConstants() -> (i32, i1) {
1350  %c13 = arith.constant 13 : i32
1351  %c37 = arith.constant 37 : i32
1352  %sum, %overflow = arith.addui_extended %c13, %c37: i32, i1
1353  return %sum, %overflow : i32, i1
1354}
1355
1356// CHECK-LABEL: @adduiExtendedConstantsOverflow1
1357//  CHECK-DAG:    %[[true:.+]] = arith.constant true
1358//  CHECK-DAG:    %[[c0:.+]] = arith.constant 0 : i32
1359//  CHECK-NEXT:   return %[[c0]], %[[true]]
1360func.func @adduiExtendedConstantsOverflow1() -> (i32, i1) {
1361  %max = arith.constant 4294967295 : i32
1362  %c1 = arith.constant 1 : i32
1363  %sum, %overflow = arith.addui_extended %max, %c1: i32, i1
1364  return %sum, %overflow : i32, i1
1365}
1366
1367// CHECK-LABEL: @adduiExtendedConstantsOverflow2
1368//  CHECK-DAG:    %[[true:.+]] = arith.constant true
1369//  CHECK-DAG:    %[[c_2:.+]] = arith.constant -2 : i32
1370// CHECK-NEXT:    return %[[c_2]], %[[true]]
1371func.func @adduiExtendedConstantsOverflow2() -> (i32, i1) {
1372  %max = arith.constant 4294967295 : i32
1373  %sum, %overflow = arith.addui_extended %max, %max: i32, i1
1374  return %sum, %overflow : i32, i1
1375}
1376
1377// CHECK-LABEL: @adduiExtendedConstantsOverflowVector
1378//  CHECK-DAG:    %[[sum:.+]] = arith.constant dense<[1, 6, 2, 14]> : vector<4xi32>
1379//  CHECK-DAG:    %[[overflow:.+]] = arith.constant dense<[false, false, true, false]> : vector<4xi1>
1380// CHECK-NEXT:    return %[[sum]], %[[overflow]]
1381func.func @adduiExtendedConstantsOverflowVector() -> (vector<4xi32>, vector<4xi1>) {
1382  %v1 = arith.constant dense<[1, 3, 3, 7]> : vector<4xi32>
1383  %v2 = arith.constant dense<[0, 3, 4294967295, 7]> : vector<4xi32>
1384  %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1>
1385  return %sum, %overflow : vector<4xi32>, vector<4xi1>
1386}
1387
1388// CHECK-LABEL: @adduiExtendedConstantsSplatVector
1389//   CHECK-DAG:   %[[sum:.+]] = arith.constant dense<3> : vector<4xi32>
1390//   CHECK-DAG:   %[[overflow:.+]] = arith.constant dense<false> : vector<4xi1>
1391//  CHECK-NEXT:   return %[[sum]], %[[overflow]]
1392func.func @adduiExtendedConstantsSplatVector() -> (vector<4xi32>, vector<4xi1>) {
1393  %v1 = arith.constant dense<1> : vector<4xi32>
1394  %v2 = arith.constant dense<2> : vector<4xi32>
1395  %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1>
1396  return %sum, %overflow : vector<4xi32>, vector<4xi1>
1397}
1398
1399// CHECK-LABEL: @mulsiExtendedZeroRhs
1400//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1401//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1402func.func @mulsiExtendedZeroRhs(%arg0: i32) -> (i32, i32) {
1403  %zero = arith.constant 0 : i32
1404  %low, %high = arith.mulsi_extended %arg0, %zero: i32
1405  return %low, %high : i32, i32
1406}
1407
1408// CHECK-LABEL: @mulsiExtendedZeroRhsSplat
1409//  CHECK-NEXT:   %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>
1410//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1411func.func @mulsiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {
1412  %zero = arith.constant dense<0> : vector<3xi32>
1413  %low, %high = arith.mulsi_extended %arg0, %zero: vector<3xi32>
1414  return %low, %high : vector<3xi32>, vector<3xi32>
1415}
1416
1417// CHECK-LABEL: @mulsiExtendedZeroLhs
1418//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1419//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1420func.func @mulsiExtendedZeroLhs(%arg0: i32) -> (i32, i32) {
1421  %zero = arith.constant 0 : i32
1422  %low, %high = arith.mulsi_extended %zero, %arg0: i32
1423  return %low, %high : i32, i32
1424}
1425
1426// CHECK-LABEL: @mulsiExtendedOneRhs
1427//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> (i32, i32)
1428//  CHECK-NEXT:   %[[C0:.+]]  = arith.constant 0 : i32
1429//  CHECK-NEXT:   %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : i32
1430//  CHECK-NEXT:   %[[EXT:.+]] = arith.extsi %[[CMP]] : i1 to i32
1431//  CHECK-NEXT:   return %[[ARG]], %[[EXT]] : i32, i32
1432func.func @mulsiExtendedOneRhs(%arg0: i32) -> (i32, i32) {
1433  %one = arith.constant 1 : i32
1434  %low, %high = arith.mulsi_extended %arg0, %one: i32
1435  return %low, %high : i32, i32
1436}
1437
1438// CHECK-LABEL: @mulsiExtendedOneRhsSplat
1439//  CHECK-SAME:   (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>)
1440//  CHECK-NEXT:   %[[C0:.+]]  = arith.constant dense<0> : vector<3xi32>
1441//  CHECK-NEXT:   %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : vector<3xi32>
1442//  CHECK-NEXT:   %[[EXT:.+]] = arith.extsi %[[CMP]] : vector<3xi1> to vector<3xi32>
1443//  CHECK-NEXT:   return %[[ARG]], %[[EXT]] : vector<3xi32>, vector<3xi32>
1444func.func @mulsiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {
1445  %one = arith.constant dense<1> : vector<3xi32>
1446  %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi32>
1447  return %low, %high : vector<3xi32>, vector<3xi32>
1448}
1449
1450// CHECK-LABEL: @mulsiExtendedOneRhsI1
1451//  CHECK-SAME:   (%[[ARG:.+]]: i1) -> (i1, i1)
1452//  CHECK-NEXT:   %[[T:.+]]  = arith.constant true
1453//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[T]] : i1
1454//  CHECK-NEXT:   return %[[LOW]], %[[HIGH]] : i1, i1
1455func.func @mulsiExtendedOneRhsI1(%arg0: i1) -> (i1, i1) {
1456  %one = arith.constant true
1457  %low, %high = arith.mulsi_extended %arg0, %one: i1
1458  return %low, %high : i1, i1
1459}
1460
1461// CHECK-LABEL: @mulsiExtendedOneRhsSplatI1
1462//  CHECK-SAME:   (%[[ARG:.+]]: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>)
1463//  CHECK-NEXT:   %[[TS:.+]]  = arith.constant dense<true> : vector<3xi1>
1464//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[TS]] : vector<3xi1>
1465//  CHECK-NEXT:   return %[[LOW]], %[[HIGH]] : vector<3xi1>, vector<3xi1>
1466func.func @mulsiExtendedOneRhsSplatI1(%arg0: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) {
1467  %one = arith.constant dense<true> : vector<3xi1>
1468  %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi1>
1469  return %low, %high : vector<3xi1>, vector<3xi1>
1470}
1471
1472// CHECK-LABEL: @mulsiExtendedUnusedHigh
1473//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> i32
1474//  CHECK-NEXT:   %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i32
1475//  CHECK-NEXT:   return %[[RES]]
1476func.func @mulsiExtendedUnusedHigh(%arg0: i32) -> i32 {
1477  %low, %high = arith.mulsi_extended %arg0, %arg0: i32
1478  return %low : i32
1479}
1480
1481// CHECK-LABEL: @mulsiExtendedScalarConstants
1482//  CHECK-DAG:    %[[c27:.+]] = arith.constant 27 : i8
1483//  CHECK-DAG:    %[[c_n3:.+]] = arith.constant -3 : i8
1484//  CHECK-NEXT:   return %[[c27]], %[[c_n3]]
1485func.func @mulsiExtendedScalarConstants() -> (i8, i8) {
1486  %c57 = arith.constant 57 : i8
1487  %c_n13 = arith.constant -13 : i8
1488  %low, %high = arith.mulsi_extended %c57, %c_n13: i8
1489  return %low, %high : i8, i8
1490}
1491
1492// CHECK-LABEL: @mulsiExtendedVectorConstants
1493//  CHECK-DAG:    %[[cstLo:.+]] = arith.constant dense<[65, 79, 34]> : vector<3xi8>
1494//  CHECK-DAG:    %[[cstHi:.+]] = arith.constant dense<[0, 14, 0]> : vector<3xi8>
1495//  CHECK-NEXT:   return %[[cstLo]], %[[cstHi]]
1496func.func @mulsiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) {
1497  %cstA = arith.constant dense<[5, 37, -17]> : vector<3xi8>
1498  %cstB = arith.constant dense<[13, 99, -2]> : vector<3xi8>
1499  %low, %high = arith.mulsi_extended %cstA, %cstB: vector<3xi8>
1500  return %low, %high : vector<3xi8>, vector<3xi8>
1501}
1502
1503// CHECK-LABEL: @muluiExtendedZeroRhs
1504//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1505//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1506func.func @muluiExtendedZeroRhs(%arg0: i32) -> (i32, i32) {
1507  %zero = arith.constant 0 : i32
1508  %low, %high = arith.mului_extended %arg0, %zero: i32
1509  return %low, %high : i32, i32
1510}
1511
1512// CHECK-LABEL: @muluiExtendedZeroRhsSplat
1513//  CHECK-NEXT:   %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>
1514//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1515func.func @muluiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {
1516  %zero = arith.constant dense<0> : vector<3xi32>
1517  %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32>
1518  return %low, %high : vector<3xi32>, vector<3xi32>
1519}
1520
1521// CHECK-LABEL: @muluiExtendedZeroLhs
1522//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1523//  CHECK-NEXT:   return %[[zero]], %[[zero]]
1524func.func @muluiExtendedZeroLhs(%arg0: i32) -> (i32, i32) {
1525  %zero = arith.constant 0 : i32
1526  %low, %high = arith.mului_extended %zero, %arg0: i32
1527  return %low, %high : i32, i32
1528}
1529
1530// CHECK-LABEL: @muluiExtendedOneRhs
1531//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> (i32, i32)
1532//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1533//  CHECK-NEXT:   return %[[ARG]], %[[zero]]
1534func.func @muluiExtendedOneRhs(%arg0: i32) -> (i32, i32) {
1535  %zero = arith.constant 1 : i32
1536  %low, %high = arith.mului_extended %arg0, %zero: i32
1537  return %low, %high : i32, i32
1538}
1539
1540// CHECK-LABEL: @muluiExtendedOneRhsSplat
1541//  CHECK-SAME:   (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>)
1542//  CHECK-NEXT:   %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>
1543//  CHECK-NEXT:   return %[[ARG]], %[[zero]]
1544func.func @muluiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {
1545  %zero = arith.constant dense<1> : vector<3xi32>
1546  %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32>
1547  return %low, %high : vector<3xi32>, vector<3xi32>
1548}
1549
1550// CHECK-LABEL: @muluiExtendedOneLhs
1551//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> (i32, i32)
1552//  CHECK-NEXT:   %[[zero:.+]] = arith.constant 0 : i32
1553//  CHECK-NEXT:   return %[[ARG]], %[[zero]]
1554func.func @muluiExtendedOneLhs(%arg0: i32) -> (i32, i32) {
1555  %zero = arith.constant 1 : i32
1556  %low, %high = arith.mului_extended %zero, %arg0: i32
1557  return %low, %high : i32, i32
1558}
1559
1560// CHECK-LABEL: @muluiExtendedUnusedHigh
1561//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> i32
1562//  CHECK-NEXT:   %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i32
1563//  CHECK-NEXT:   return %[[RES]]
1564func.func @muluiExtendedUnusedHigh(%arg0: i32) -> i32 {
1565  %low, %high = arith.mului_extended %arg0, %arg0: i32
1566  return %low : i32
1567}
1568
1569// This shouldn't be folded.
1570// CHECK-LABEL: @muluiExtendedUnusedLow
1571//  CHECK-SAME:   (%[[ARG:.+]]: i32) -> i32
1572//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[ARG]], %[[ARG]] : i32
1573//  CHECK-NEXT:   return %[[HIGH]]
1574func.func @muluiExtendedUnusedLow(%arg0: i32) -> i32 {
1575  %low, %high = arith.mului_extended %arg0, %arg0: i32
1576  return %high : i32
1577}
1578
1579// CHECK-LABEL: @muluiExtendedScalarConstants
1580//  CHECK-DAG:    %[[c157:.+]] = arith.constant -99 : i8
1581//  CHECK-DAG:    %[[c29:.+]] = arith.constant 29 : i8
1582//  CHECK-NEXT:   return %[[c157]], %[[c29]]
1583func.func @muluiExtendedScalarConstants() -> (i8, i8) {
1584  %c57 = arith.constant 57 : i8
1585  %c133 = arith.constant 133 : i8
1586  %low, %high = arith.mului_extended %c57, %c133: i8 // = 7581
1587  return %low, %high : i8, i8
1588}
1589
1590// CHECK-LABEL: @muluiExtendedVectorConstants
1591//  CHECK-DAG:    %[[cstLo:.+]] = arith.constant dense<[65, 79, 1]> : vector<3xi8>
1592//  CHECK-DAG:    %[[cstHi:.+]] = arith.constant dense<[0, 14, -2]> : vector<3xi8>
1593//  CHECK-NEXT:   return %[[cstLo]], %[[cstHi]]
1594func.func @muluiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) {
1595  %cstA = arith.constant dense<[5, 37, 255]> : vector<3xi8>
1596  %cstB = arith.constant dense<[13, 99, 255]> : vector<3xi8>
1597  %low, %high = arith.mului_extended %cstA, %cstB: vector<3xi8>
1598  return %low, %high : vector<3xi8>, vector<3xi8>
1599}
1600
1601// CHECK-LABEL: @notCmpEQ
1602//       CHECK:   %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
1603//       CHECK:   return %[[cres]]
1604func.func @notCmpEQ(%arg0: i8, %arg1: i8) -> i1 {
1605  %true = arith.constant true
1606  %cmp = arith.cmpi "eq", %arg0, %arg1 : i8
1607  %ncmp = arith.xori %cmp, %true : i1
1608  return %ncmp : i1
1609}
1610
1611// CHECK-LABEL: @notCmpEQ2
1612//       CHECK:   %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
1613//       CHECK:   return %[[cres]]
1614func.func @notCmpEQ2(%arg0: i8, %arg1: i8) -> i1 {
1615  %true = arith.constant true
1616  %cmp = arith.cmpi "eq", %arg0, %arg1 : i8
1617  %ncmp = arith.xori %true, %cmp : i1
1618  return %ncmp : i1
1619}
1620
1621// CHECK-LABEL: @notCmpNE
1622//       CHECK:   %[[cres:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
1623//       CHECK:   return %[[cres]]
1624func.func @notCmpNE(%arg0: i8, %arg1: i8) -> i1 {
1625  %true = arith.constant true
1626  %cmp = arith.cmpi "ne", %arg0, %arg1 : i8
1627  %ncmp = arith.xori %cmp, %true : i1
1628  return %ncmp : i1
1629}
1630
1631// CHECK-LABEL: @notCmpSLT
1632//       CHECK:   %[[cres:.+]] = arith.cmpi sge, %arg0, %arg1 : i8
1633//       CHECK:   return %[[cres]]
1634func.func @notCmpSLT(%arg0: i8, %arg1: i8) -> i1 {
1635  %true = arith.constant true
1636  %cmp = arith.cmpi "slt", %arg0, %arg1 : i8
1637  %ncmp = arith.xori %cmp, %true : i1
1638  return %ncmp : i1
1639}
1640
1641// CHECK-LABEL: @notCmpSLE
1642//       CHECK:   %[[cres:.+]] = arith.cmpi sgt, %arg0, %arg1 : i8
1643//       CHECK:   return %[[cres]]
1644func.func @notCmpSLE(%arg0: i8, %arg1: i8) -> i1 {
1645  %true = arith.constant true
1646  %cmp = arith.cmpi "sle", %arg0, %arg1 : i8
1647  %ncmp = arith.xori %cmp, %true : i1
1648  return %ncmp : i1
1649}
1650
1651// CHECK-LABEL: @notCmpSGT
1652//       CHECK:   %[[cres:.+]] = arith.cmpi sle, %arg0, %arg1 : i8
1653//       CHECK:   return %[[cres]]
1654func.func @notCmpSGT(%arg0: i8, %arg1: i8) -> i1 {
1655  %true = arith.constant true
1656  %cmp = arith.cmpi "sgt", %arg0, %arg1 : i8
1657  %ncmp = arith.xori %cmp, %true : i1
1658  return %ncmp : i1
1659}
1660
1661// CHECK-LABEL: @notCmpSGE
1662//       CHECK:   %[[cres:.+]] = arith.cmpi slt, %arg0, %arg1 : i8
1663//       CHECK:   return %[[cres]]
1664func.func @notCmpSGE(%arg0: i8, %arg1: i8) -> i1 {
1665  %true = arith.constant true
1666  %cmp = arith.cmpi "sge", %arg0, %arg1 : i8
1667  %ncmp = arith.xori %cmp, %true : i1
1668  return %ncmp : i1
1669}
1670
1671// CHECK-LABEL: @notCmpULT
1672//       CHECK:   %[[cres:.+]] = arith.cmpi uge, %arg0, %arg1 : i8
1673//       CHECK:   return %[[cres]]
1674func.func @notCmpULT(%arg0: i8, %arg1: i8) -> i1 {
1675  %true = arith.constant true
1676  %cmp = arith.cmpi "ult", %arg0, %arg1 : i8
1677  %ncmp = arith.xori %cmp, %true : i1
1678  return %ncmp : i1
1679}
1680
1681// CHECK-LABEL: @notCmpULE
1682//       CHECK:   %[[cres:.+]] = arith.cmpi ugt, %arg0, %arg1 : i8
1683//       CHECK:   return %[[cres]]
1684func.func @notCmpULE(%arg0: i8, %arg1: i8) -> i1 {
1685  %true = arith.constant true
1686  %cmp = arith.cmpi "ule", %arg0, %arg1 : i8
1687  %ncmp = arith.xori %cmp, %true : i1
1688  return %ncmp : i1
1689}
1690
1691// CHECK-LABEL: @notCmpUGT
1692//       CHECK:   %[[cres:.+]] = arith.cmpi ule, %arg0, %arg1 : i8
1693//       CHECK:   return %[[cres]]
1694func.func @notCmpUGT(%arg0: i8, %arg1: i8) -> i1 {
1695  %true = arith.constant true
1696  %cmp = arith.cmpi "ugt", %arg0, %arg1 : i8
1697  %ncmp = arith.xori %cmp, %true : i1
1698  return %ncmp : i1
1699}
1700
1701// CHECK-LABEL: @notCmpUGE
1702//       CHECK:   %[[cres:.+]] = arith.cmpi ult, %arg0, %arg1 : i8
1703//       CHECK:   return %[[cres]]
1704func.func @notCmpUGE(%arg0: i8, %arg1: i8) -> i1 {
1705  %true = arith.constant true
1706  %cmp = arith.cmpi "uge", %arg0, %arg1 : i8
1707  %ncmp = arith.xori %cmp, %true : i1
1708  return %ncmp : i1
1709}
1710
1711// -----
1712
1713// CHECK-LABEL: @xorxor(
1714//       CHECK-NOT: xori
1715//       CHECK:   return %arg0
1716func.func @xorxor(%cmp : i1) -> i1 {
1717  %true = arith.constant true
1718  %ncmp = arith.xori %cmp, %true : i1
1719  %nncmp = arith.xori %ncmp, %true : i1
1720  return %nncmp : i1
1721}
1722
1723// CHECK-LABEL: @xorOfExtSI
1724//       CHECK:  %[[comb:.+]] = arith.xori %arg0, %arg1 : i8
1725//       CHECK:  %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64
1726//       CHECK:   return %[[ext]]
1727func.func @xorOfExtSI(%arg0: i8, %arg1: i8) -> i64 {
1728  %ext0 = arith.extsi %arg0 : i8 to i64
1729  %ext1 = arith.extsi %arg1 : i8 to i64
1730  %res = arith.xori %ext0, %ext1 : i64
1731  return %res : i64
1732}
1733
1734// CHECK-LABEL: @xorOfExtUI
1735//       CHECK:  %[[comb:.+]] = arith.xori %arg0, %arg1 : i8
1736//       CHECK:  %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64
1737//       CHECK:   return %[[ext]]
1738func.func @xorOfExtUI(%arg0: i8, %arg1: i8) -> i64 {
1739  %ext0 = arith.extui %arg0 : i8 to i64
1740  %ext1 = arith.extui %arg1 : i8 to i64
1741  %res = arith.xori %ext0, %ext1 : i64
1742  return %res : i64
1743}
1744
1745// -----
1746
1747// CHECK-LABEL: @bitcastSameType(
1748// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
1749func.func @bitcastSameType(%arg : f32) -> f32 {
1750  // CHECK: return %[[ARG]]
1751  %res = arith.bitcast %arg : f32 to f32
1752  return %res : f32
1753}
1754
1755// -----
1756
1757// CHECK-LABEL: @bitcastConstantFPtoI(
1758func.func @bitcastConstantFPtoI() -> i32 {
1759  // CHECK: %[[C0:.+]] = arith.constant 0 : i32
1760  // CHECK: return %[[C0]]
1761  %c0 = arith.constant 0.0 : f32
1762  %res = arith.bitcast %c0 : f32 to i32
1763  return %res : i32
1764}
1765
1766// -----
1767
1768// CHECK-LABEL: @bitcastConstantItoFP(
1769func.func @bitcastConstantItoFP() -> f32 {
1770  // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f32
1771  // CHECK: return %[[C0]]
1772  %c0 = arith.constant 0 : i32
1773  %res = arith.bitcast %c0 : i32 to f32
1774  return %res : f32
1775}
1776
1777// -----
1778
1779// CHECK-LABEL: @bitcastConstantFPtoFP(
1780func.func @bitcastConstantFPtoFP() -> f16 {
1781  // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f16
1782  // CHECK: return %[[C0]]
1783  %c0 = arith.constant 0.0 : bf16
1784  %res = arith.bitcast %c0 : bf16 to f16
1785  return %res : f16
1786}
1787
1788// -----
1789
1790// CHECK-LABEL: @bitcastConstantVecFPtoI(
1791func.func @bitcastConstantVecFPtoI() -> vector<3xf32> {
1792  // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xf32>
1793  // CHECK: return %[[C0]]
1794  %c0 = arith.constant dense<0> : vector<3xi32>
1795  %res = arith.bitcast %c0 : vector<3xi32> to vector<3xf32>
1796  return %res : vector<3xf32>
1797}
1798
1799// -----
1800
1801// CHECK-LABEL: @bitcastConstantVecItoFP(
1802func.func @bitcastConstantVecItoFP() -> vector<3xi32> {
1803  // CHECK: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32>
1804  // CHECK: return %[[C0]]
1805  %c0 = arith.constant dense<0.0> : vector<3xf32>
1806  %res = arith.bitcast %c0 : vector<3xf32> to vector<3xi32>
1807  return %res : vector<3xi32>
1808}
1809
1810// -----
1811
1812// CHECK-LABEL: @bitcastConstantVecFPtoFP(
1813func.func @bitcastConstantVecFPtoFP() -> vector<3xbf16> {
1814  // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xbf16>
1815  // CHECK: return %[[C0]]
1816  %c0 = arith.constant dense<0.0> : vector<3xf16>
1817  %res = arith.bitcast %c0 : vector<3xf16> to vector<3xbf16>
1818  return %res : vector<3xbf16>
1819}
1820
1821// -----
1822
1823// CHECK-LABEL: @bitcastBackAndForth(
1824// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
1825func.func @bitcastBackAndForth(%arg : i32) -> i32 {
1826  // CHECK: return %[[ARG]]
1827  %f = arith.bitcast %arg : i32 to f32
1828  %res = arith.bitcast %f : f32 to i32
1829  return %res : i32
1830}
1831
1832// -----
1833
1834// CHECK-LABEL: @bitcastOfBitcast(
1835// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
1836func.func @bitcastOfBitcast(%arg : i16) -> i16 {
1837  // CHECK: return %[[ARG]]
1838  %f = arith.bitcast %arg : i16 to f16
1839  %bf = arith.bitcast %f : f16 to bf16
1840  %res = arith.bitcast %bf : bf16 to i16
1841  return %res : i16
1842}
1843
1844// -----
1845
1846// CHECK-LABEL: test_maxsi
1847// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1848// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 127
1849// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]
1850// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
1851func.func @test_maxsi(%arg0 : i8) -> (i8, i8, i8, i8) {
1852  %maxIntCst = arith.constant 127 : i8
1853  %minIntCst = arith.constant -128 : i8
1854  %c0 = arith.constant 42 : i8
1855  %0 = arith.maxsi %arg0, %arg0 : i8
1856  %1 = arith.maxsi %arg0, %maxIntCst : i8
1857  %2 = arith.maxsi %arg0, %minIntCst : i8
1858  %3 = arith.maxsi %arg0, %c0 : i8
1859  return %0, %1, %2, %3: i8, i8, i8, i8
1860}
1861
1862// CHECK-LABEL: test_maxsi2
1863// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1864// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 127
1865// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]
1866// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
1867func.func @test_maxsi2(%arg0 : i8) -> (i8, i8, i8, i8) {
1868  %maxIntCst = arith.constant 127 : i8
1869  %minIntCst = arith.constant -128 : i8
1870  %c0 = arith.constant 42 : i8
1871  %0 = arith.maxsi %arg0, %arg0 : i8
1872  %1 = arith.maxsi %maxIntCst, %arg0: i8
1873  %2 = arith.maxsi %minIntCst, %arg0: i8
1874  %3 = arith.maxsi %c0, %arg0 : i8
1875  return %0, %1, %2, %3: i8, i8, i8, i8
1876}
1877
1878// -----
1879
1880// CHECK-LABEL: test_maxui
1881// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1882// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -1
1883// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]
1884// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
1885func.func @test_maxui(%arg0 : i8) -> (i8, i8, i8, i8) {
1886  %maxIntCst = arith.constant 255 : i8
1887  %minIntCst = arith.constant 0 : i8
1888  %c0 = arith.constant 42 : i8
1889  %0 = arith.maxui %arg0, %arg0 : i8
1890  %1 = arith.maxui %arg0, %maxIntCst : i8
1891  %2 = arith.maxui %arg0, %minIntCst : i8
1892  %3 = arith.maxui %arg0, %c0 : i8
1893  return %0, %1, %2, %3: i8, i8, i8, i8
1894}
1895
1896// CHECK-LABEL: test_maxui
1897// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1898// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -1
1899// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]
1900// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
1901func.func @test_maxui2(%arg0 : i8) -> (i8, i8, i8, i8) {
1902  %maxIntCst = arith.constant 255 : i8
1903  %minIntCst = arith.constant 0 : i8
1904  %c0 = arith.constant 42 : i8
1905  %0 = arith.maxui %arg0, %arg0 : i8
1906  %1 = arith.maxui %maxIntCst, %arg0 : i8
1907  %2 = arith.maxui %minIntCst, %arg0 : i8
1908  %3 = arith.maxui %c0, %arg0 : i8
1909  return %0, %1, %2, %3: i8, i8, i8, i8
1910}
1911
1912// -----
1913
1914// CHECK-LABEL: test_minsi
1915// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1916// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -128
1917// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]
1918// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
1919func.func @test_minsi(%arg0 : i8) -> (i8, i8, i8, i8) {
1920  %maxIntCst = arith.constant 127 : i8
1921  %minIntCst = arith.constant -128 : i8
1922  %c0 = arith.constant 42 : i8
1923  %0 = arith.minsi %arg0, %arg0 : i8
1924  %1 = arith.minsi %arg0, %maxIntCst : i8
1925  %2 = arith.minsi %arg0, %minIntCst : i8
1926  %3 = arith.minsi %arg0, %c0 : i8
1927  return %0, %1, %2, %3: i8, i8, i8, i8
1928}
1929
1930// CHECK-LABEL: test_minsi
1931// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1932// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -128
1933// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]
1934// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
1935func.func @test_minsi2(%arg0 : i8) -> (i8, i8, i8, i8) {
1936  %maxIntCst = arith.constant 127 : i8
1937  %minIntCst = arith.constant -128 : i8
1938  %c0 = arith.constant 42 : i8
1939  %0 = arith.minsi %arg0, %arg0 : i8
1940  %1 = arith.minsi %maxIntCst, %arg0 : i8
1941  %2 = arith.minsi %minIntCst, %arg0 : i8
1942  %3 = arith.minsi %c0, %arg0 : i8
1943  return %0, %1, %2, %3: i8, i8, i8, i8
1944}
1945
1946// -----
1947
1948// CHECK-LABEL: test_minui
1949// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1950// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 0
1951// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]
1952// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
1953func.func @test_minui(%arg0 : i8) -> (i8, i8, i8, i8) {
1954  %maxIntCst = arith.constant 255 : i8
1955  %minIntCst = arith.constant 0 : i8
1956  %c0 = arith.constant 42 : i8
1957  %0 = arith.minui %arg0, %arg0 : i8
1958  %1 = arith.minui %arg0, %maxIntCst : i8
1959  %2 = arith.minui %arg0, %minIntCst : i8
1960  %3 = arith.minui %arg0, %c0 : i8
1961  return %0, %1, %2, %3: i8, i8, i8, i8
1962}
1963
1964// CHECK-LABEL: test_minui
1965// CHECK-DAG: %[[C0:.+]] = arith.constant 42
1966// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 0
1967// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]
1968// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
1969func.func @test_minui2(%arg0 : i8) -> (i8, i8, i8, i8) {
1970  %maxIntCst = arith.constant 255 : i8
1971  %minIntCst = arith.constant 0 : i8
1972  %c0 = arith.constant 42 : i8
1973  %0 = arith.minui %arg0, %arg0 : i8
1974  %1 = arith.minui %maxIntCst, %arg0 : i8
1975  %2 = arith.minui %minIntCst, %arg0 : i8
1976  %3 = arith.minui %c0, %arg0 : i8
1977  return %0, %1, %2, %3: i8, i8, i8, i8
1978}
1979
1980// -----
1981
1982// CHECK-LABEL: @test_minimumf(
1983func.func @test_minimumf(%arg0 : f32) -> (f32, f32, f32) {
1984  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
1985  // CHECK-NEXT:  %[[X:.+]] = arith.minimumf %arg0, %[[C0]]
1986  // CHECK-NEXT:  return %[[X]], %arg0, %arg0
1987  %c0 = arith.constant 0.0 : f32
1988  %inf = arith.constant 0x7F800000 : f32
1989  %0 = arith.minimumf %c0, %arg0 : f32
1990  %1 = arith.minimumf %arg0, %arg0 : f32
1991  %2 = arith.minimumf %inf, %arg0 : f32
1992  return %0, %1, %2 : f32, f32, f32
1993}
1994
1995// -----
1996
1997// CHECK-LABEL: @test_maximumf(
1998func.func @test_maximumf(%arg0 : f32) -> (f32, f32, f32) {
1999  // CHECK-DAG:   %[[C0:.+]] = arith.constant
2000  // CHECK-NEXT:  %[[X:.+]] = arith.maximumf %arg0, %[[C0]]
2001  // CHECK-NEXT:   return %[[X]], %arg0, %arg0
2002  %c0 = arith.constant 0.0 : f32
2003  %-inf = arith.constant 0xFF800000 : f32
2004  %0 = arith.maximumf %c0, %arg0 : f32
2005  %1 = arith.maximumf %arg0, %arg0 : f32
2006  %2 = arith.maximumf %-inf, %arg0 : f32
2007  return %0, %1, %2 : f32, f32, f32
2008}
2009
2010// -----
2011
2012// CHECK-LABEL: @test_minnumf(
2013func.func @test_minnumf(%arg0 : f32) -> (f32, f32, f32, f32) {
2014  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
2015  // CHECK-DAG:   %[[INF:.+]] = arith.constant
2016  // CHECK-NEXT:  %[[X:.+]] = arith.minnumf %arg0, %[[C0]]
2017  // CHECK-NEXT:  %[[Y:.+]] = arith.minnumf %arg0, %[[INF]]
2018  // CHECK-NEXT:   return %[[X]], %arg0, %[[Y]], %arg0
2019  %c0 = arith.constant 0.0 : f32
2020  %inf = arith.constant 0x7F800000 : f32
2021  %nan = arith.constant 0x7FC00000 : f32
2022  %0 = arith.minnumf %c0, %arg0 : f32
2023  %1 = arith.minnumf %arg0, %arg0 : f32
2024  %2 = arith.minnumf %inf, %arg0 : f32
2025  %3 = arith.minnumf %nan, %arg0 : f32
2026  return %0, %1, %2, %3 : f32, f32, f32, f32
2027}
2028
2029// -----
2030
2031// CHECK-LABEL: @test_maxnumf(
2032func.func @test_maxnumf(%arg0 : f32) -> (f32, f32, f32, f32) {
2033  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
2034  // CHECK-DAG:   %[[NINF:.+]] = arith.constant
2035  // CHECK-NEXT:  %[[X:.+]] = arith.maxnumf %arg0, %[[C0]]
2036  // CHECK-NEXT:  %[[Y:.+]] = arith.maxnumf %arg0, %[[NINF]]
2037  // CHECK-NEXT:   return %[[X]], %arg0, %[[Y]], %arg0
2038  %c0 = arith.constant 0.0 : f32
2039  %-inf = arith.constant 0xFF800000 : f32
2040  %nan = arith.constant 0x7FC00000 : f32
2041  %0 = arith.maxnumf %c0, %arg0 : f32
2042  %1 = arith.maxnumf %arg0, %arg0 : f32
2043  %2 = arith.maxnumf %-inf, %arg0 : f32
2044  %3 = arith.maxnumf %nan, %arg0 : f32
2045  return %0, %1, %2, %3 : f32, f32, f32, f32
2046}
2047
2048// -----
2049
2050// CHECK-LABEL: @test_addf(
2051func.func @test_addf(%arg0 : f32) -> (f32, f32, f32, f32) {
2052  // CHECK-DAG:   %[[C2:.+]] = arith.constant 2.0
2053  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
2054  // CHECK-NEXT:  %[[X:.+]] = arith.addf %arg0, %[[C0]]
2055  // CHECK-NEXT:   return %[[X]], %arg0, %arg0, %[[C2]]
2056  %c0 = arith.constant 0.0 : f32
2057  %c-0 = arith.constant -0.0 : f32
2058  %c1 = arith.constant 1.0 : f32
2059  %0 = arith.addf %c0, %arg0 : f32
2060  %1 = arith.addf %arg0, %c-0 : f32
2061  %2 = arith.addf %c-0, %arg0 : f32
2062  %3 = arith.addf %c1, %c1 : f32
2063  return %0, %1, %2, %3 : f32, f32, f32, f32
2064}
2065
2066// -----
2067
2068// CHECK-LABEL: @test_subf(
2069func.func @test_subf(%arg0 : f16) -> (f16, f16, f16) {
2070  // CHECK-DAG:   %[[C1:.+]] = arith.constant -1.0
2071  // CHECK-DAG:   %[[C0:.+]] = arith.constant -0.0
2072  // CHECK-NEXT:  %[[X:.+]] = arith.subf %arg0, %[[C0]]
2073  // CHECK-NEXT:   return %arg0, %[[X]], %[[C1]]
2074  %c0 = arith.constant 0.0 : f16
2075  %c-0 = arith.constant -0.0 : f16
2076  %c1 = arith.constant 1.0 : f16
2077  %0 = arith.subf %arg0, %c0 : f16
2078  %1 = arith.subf %arg0, %c-0 : f16
2079  %2 = arith.subf %c0, %c1 : f16
2080  return %0, %1, %2 : f16, f16, f16
2081}
2082
2083// -----
2084
2085// CHECK-LABEL: @test_mulf(
2086func.func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) {
2087  // CHECK-DAG:   %[[C2:.+]] = arith.constant 2.0
2088  // CHECK-DAG:   %[[C4:.+]] = arith.constant 4.0
2089  // CHECK-NEXT:  %[[X:.+]] = arith.mulf %arg0, %[[C2]]
2090  // CHECK-NEXT:  return %[[X]], %arg0, %arg0, %[[C4]]
2091  %c1 = arith.constant 1.0 : f32
2092  %c2 = arith.constant 2.0 : f32
2093  %0 = arith.mulf %c2, %arg0 : f32
2094  %1 = arith.mulf %arg0, %c1 : f32
2095  %2 = arith.mulf %c1, %arg0 : f32
2096  %3 = arith.mulf %c2, %c2 : f32
2097  return %0, %1, %2, %3 : f32, f32, f32, f32
2098}
2099
2100// CHECK-LABEL: @test_mulf1(
2101func.func @test_mulf1(%arg0 : f32, %arg1 : f32) -> (f32) {
2102  // CHECK-NEXT:  %[[X:.+]] = arith.mulf %arg0, %arg1 : f32
2103  // CHECK-NEXT:  return %[[X]]
2104  %0 = arith.negf %arg0 : f32
2105  %1 = arith.negf %arg1 : f32
2106  %2 = arith.mulf %0, %1 : f32
2107  return %2 : f32
2108}
2109
2110// -----
2111
2112// CHECK-LABEL: @test_divf(
2113func.func @test_divf(%arg0 : f64) -> (f64, f64) {
2114  // CHECK-NEXT:  %[[C5:.+]] = arith.constant 5.000000e-01
2115  // CHECK-NEXT:   return %arg0, %[[C5]]
2116  %c1 = arith.constant 1.0 : f64
2117  %c2 = arith.constant 2.0 : f64
2118  %0 = arith.divf %arg0, %c1 : f64
2119  %1 = arith.divf %c1, %c2 : f64
2120  return %0, %1 : f64, f64
2121}
2122
2123// CHECK-LABEL: @test_divf1(
2124func.func @test_divf1(%arg0 : f32, %arg1 : f32) -> (f32) {
2125  // CHECK-NEXT:  %[[X:.+]] = arith.divf %arg0, %arg1 : f32
2126  // CHECK-NEXT:  return %[[X]]
2127  %0 = arith.negf %arg0 : f32
2128  %1 = arith.negf %arg1 : f32
2129  %2 = arith.divf %0, %1 : f32
2130  return %2 : f32
2131}
2132
2133// -----
2134
2135func.func @fold_divui_of_muli_0(%arg0 : index, %arg1 : index) -> index {
2136  %0 = arith.muli %arg0, %arg1 overflow<nuw> : index
2137  %1 = arith.divui %0, %arg0 : index
2138  return %1 : index
2139}
2140// CHECK-LABEL: func @fold_divui_of_muli_0(
2141//  CHECK-SAME:     %[[ARG0:.+]]: index,
2142//  CHECK-SAME:     %[[ARG1:.+]]: index)
2143//       CHECK:   return %[[ARG1]]
2144
2145func.func @fold_divui_of_muli_1(%arg0 : index, %arg1 : index) -> index {
2146  %0 = arith.muli %arg0, %arg1 overflow<nuw> : index
2147  %1 = arith.divui %0, %arg1 : index
2148  return %1 : index
2149}
2150// CHECK-LABEL: func @fold_divui_of_muli_1(
2151//  CHECK-SAME:     %[[ARG0:.+]]: index,
2152//  CHECK-SAME:     %[[ARG1:.+]]: index)
2153//       CHECK:   return %[[ARG0]]
2154
2155func.func @fold_divsi_of_muli_0(%arg0 : index, %arg1 : index) -> index {
2156  %0 = arith.muli %arg0, %arg1 overflow<nsw> : index
2157  %1 = arith.divsi %0, %arg0 : index
2158  return %1 : index
2159}
2160// CHECK-LABEL: func @fold_divsi_of_muli_0(
2161//  CHECK-SAME:     %[[ARG0:.+]]: index,
2162//  CHECK-SAME:     %[[ARG1:.+]]: index)
2163//       CHECK:   return %[[ARG1]]
2164
2165func.func @fold_divsi_of_muli_1(%arg0 : index, %arg1 : index) -> index {
2166  %0 = arith.muli %arg0, %arg1 overflow<nsw> : index
2167  %1 = arith.divsi %0, %arg1 : index
2168  return %1 : index
2169}
2170// CHECK-LABEL: func @fold_divsi_of_muli_1(
2171//  CHECK-SAME:     %[[ARG0:.+]]: index,
2172//  CHECK-SAME:     %[[ARG1:.+]]: index)
2173//       CHECK:   return %[[ARG0]]
2174
2175// Do not fold divui(mul(a, v), v) -> a with nuw attribute.
2176func.func @no_fold_divui_of_muli(%arg0 : index, %arg1 : index) -> index {
2177  %0 = arith.muli %arg0, %arg1 : index
2178  %1 = arith.divui %0, %arg0 : index
2179  return %1 : index
2180}
2181// CHECK-LABEL: func @no_fold_divui_of_muli
2182//       CHECK:   %[[T0:.+]] = arith.muli
2183//       CHECK:   %[[T1:.+]] = arith.divui %[[T0]],
2184//       CHECK:   return %[[T1]]
2185
2186// Do not fold divsi(mul(a, v), v) -> a with nuw attribute.
2187func.func @no_fold_divsi_of_muli(%arg0 : index, %arg1 : index) -> index {
2188  %0 = arith.muli %arg0, %arg1 : index
2189  %1 = arith.divsi %0, %arg0 : index
2190  return %1 : index
2191}
2192// CHECK-LABEL: func @no_fold_divsi_of_muli
2193//       CHECK:   %[[T0:.+]] = arith.muli
2194//       CHECK:   %[[T1:.+]] = arith.divsi %[[T0]],
2195//       CHECK:   return %[[T1]]
2196
2197// -----
2198
2199// CHECK-LABEL: @test_cmpf(
2200func.func @test_cmpf(%arg0 : f32) -> (i1, i1, i1, i1) {
2201//   CHECK-DAG:   %[[T:.*]] = arith.constant true
2202//   CHECK-DAG:   %[[F:.*]] = arith.constant false
2203//       CHECK:   return %[[F]], %[[F]], %[[T]], %[[T]]
2204  %nan = arith.constant 0x7fffffff : f32
2205  %0 = arith.cmpf olt, %nan, %arg0 : f32
2206  %1 = arith.cmpf olt, %arg0, %nan : f32
2207  %2 = arith.cmpf ugt, %nan, %arg0 : f32
2208  %3 = arith.cmpf ugt, %arg0, %nan : f32
2209  return %0, %1, %2, %3 : i1, i1, i1, i1
2210}
2211
2212// -----
2213
2214// CHECK-LABEL: @constant_FPtoUI(
2215func.func @constant_FPtoUI() -> i32 {
2216  // CHECK: %[[C0:.+]] = arith.constant 2 : i32
2217  // CHECK: return %[[C0]]
2218  %c0 = arith.constant 2.0 : f32
2219  %res = arith.fptoui %c0 : f32 to i32
2220  return %res : i32
2221}
2222
2223// CHECK-LABEL: @constant_FPtoUI_splat(
2224func.func @constant_FPtoUI_splat() -> vector<4xi32> {
2225  // CHECK: %[[C0:.+]] = arith.constant dense<2> : vector<4xi32>
2226  // CHECK: return %[[C0]]
2227  %c0 = arith.constant 2.0 : f32
2228  %splat = vector.splat %c0 : vector<4xf32>
2229  %res = arith.fptoui %splat : vector<4xf32> to vector<4xi32>
2230  return %res : vector<4xi32>
2231}
2232
2233// CHECK-LABEL: @constant_FPtoUI_vector(
2234func.func @constant_FPtoUI_vector() -> vector<4xi32> {
2235  // CHECK: %[[C0:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
2236  // CHECK: return %[[C0]]
2237  %vector = arith.constant dense<[1.0, 3.0, 5.0, 7.0]> : vector<4xf32>
2238  %res = arith.fptoui %vector : vector<4xf32> to vector<4xi32>
2239  return %res : vector<4xi32>
2240}
2241
2242// -----
2243// CHECK-LABEL: @invalid_constant_FPtoUI(
2244func.func @invalid_constant_FPtoUI() -> i32 {
2245  // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32
2246  // CHECK: %[[C1:.+]] = arith.fptoui %[[C0]] : f32 to i32
2247  // CHECK: return %[[C1]]
2248  %c0 = arith.constant -2.0 : f32
2249  %res = arith.fptoui %c0 : f32 to i32
2250  return %res : i32
2251}
2252
2253// -----
2254// CHECK-LABEL: @constant_FPtoSI(
2255func.func @constant_FPtoSI() -> i32 {
2256  // CHECK: %[[C0:.+]] = arith.constant -2 : i32
2257  // CHECK: return %[[C0]]
2258  %c0 = arith.constant -2.0 : f32
2259  %res = arith.fptosi %c0 : f32 to i32
2260  return %res : i32
2261}
2262
2263// CHECK-LABEL: @constant_FPtoSI_splat(
2264func.func @constant_FPtoSI_splat() -> vector<4xi32> {
2265  // CHECK: %[[C0:.+]] = arith.constant dense<-2> : vector<4xi32>
2266  // CHECK: return %[[C0]]
2267  %c0 = arith.constant -2.0 : f32
2268  %splat = vector.splat %c0 : vector<4xf32>
2269  %res = arith.fptosi %splat : vector<4xf32> to vector<4xi32>
2270  return %res : vector<4xi32>
2271}
2272
2273// CHECK-LABEL: @constant_FPtoSI_vector(
2274func.func @constant_FPtoSI_vector() -> vector<4xi32> {
2275  // CHECK: %[[C0:.+]] = arith.constant dense<[-1, -3, -5, -7]> : vector<4xi32>
2276  // CHECK: return %[[C0]]
2277  %vector = arith.constant dense<[-1.0, -3.0, -5.0, -7.0]> : vector<4xf32>
2278  %res = arith.fptosi %vector : vector<4xf32> to vector<4xi32>
2279  return %res : vector<4xi32>
2280}
2281
2282// -----
2283// CHECK-LABEL: @invalid_constant_FPtoSI(
2284func.func @invalid_constant_FPtoSI() -> i8 {
2285  // CHECK: %[[C0:.+]] = arith.constant 2.000000e+10 : f32
2286  // CHECK: %[[C1:.+]] = arith.fptosi %[[C0]] : f32 to i8
2287  // CHECK: return %[[C1]]
2288  %c0 = arith.constant 2.0e10 : f32
2289  %res = arith.fptosi %c0 : f32 to i8
2290  return %res : i8
2291}
2292
2293// CHECK-LABEL: @constant_SItoFP(
2294func.func @constant_SItoFP() -> f32 {
2295  // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32
2296  // CHECK: return %[[C0]]
2297  %c0 = arith.constant -2 : i32
2298  %res = arith.sitofp %c0 : i32 to f32
2299  return %res : f32
2300}
2301
2302// CHECK-LABEL: @constant_SItoFP_splat(
2303func.func @constant_SItoFP_splat() -> vector<4xf32> {
2304  // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>
2305  // CHECK: return %[[C0]]
2306  %c0 = arith.constant 2 : i32
2307  %splat = vector.splat %c0 : vector<4xi32>
2308  %res = arith.sitofp %splat : vector<4xi32> to vector<4xf32>
2309  return %res : vector<4xf32>
2310}
2311
2312// CHECK-LABEL: @constant_SItoFP_vector(
2313func.func @constant_SItoFP_vector() -> vector<4xf32> {
2314  // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>
2315  // CHECK: return %[[C0]]
2316  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
2317  %res = arith.sitofp %vector : vector<4xi32> to vector<4xf32>
2318  return %res : vector<4xf32>
2319}
2320
2321// -----
2322// CHECK-LABEL: @constant_UItoFP(
2323func.func @constant_UItoFP() -> f32 {
2324  // CHECK: %[[C0:.+]] = arith.constant 2.000000e+00 : f32
2325  // CHECK: return %[[C0]]
2326  %c0 = arith.constant 2 : i32
2327  %res = arith.uitofp %c0 : i32 to f32
2328  return %res : f32
2329}
2330
2331// CHECK-LABEL: @constant_UItoFP_splat(
2332func.func @constant_UItoFP_splat() -> vector<4xf32> {
2333  // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>
2334  // CHECK: return %[[C0]]
2335  %c0 = arith.constant 2 : i32
2336  %splat = vector.splat %c0 : vector<4xi32>
2337  %res = arith.uitofp %splat : vector<4xi32> to vector<4xf32>
2338  return %res : vector<4xf32>
2339}
2340
2341// CHECK-LABEL: @constant_UItoFP_vector(
2342func.func @constant_UItoFP_vector() -> vector<4xf32> {
2343  // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>
2344  // CHECK: return %[[C0]]
2345  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
2346  %res = arith.uitofp %vector : vector<4xi32> to vector<4xf32>
2347  return %res : vector<4xf32>
2348}
2349
2350// -----
2351
2352// Tests rewritten from https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/InstCombine/2008-11-08-FCmp.ll
2353// When inst combining an FCMP with the LHS coming from a arith.uitofp instruction, we
2354// can lower it to signed ICMP instructions.
2355
2356// CHECK-LABEL: @test1(
2357// CHECK-SAME: %[[arg0:.+]]:
2358func.func @test1(%arg0: i32) -> i1 {
2359  %cst = arith.constant 0.000000e+00 : f64
2360  %1 = arith.uitofp %arg0: i32 to f64
2361  %2 = arith.cmpf ole, %1, %cst : f64
2362  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
2363  // CHECK: arith.cmpi ule, %[[arg0]], %[[c0]] : i32
2364  return %2 : i1
2365}
2366
2367// CHECK-LABEL: @test2(
2368// CHECK-SAME: %[[arg0:.+]]:
2369func.func @test2(%arg0: i32) -> i1 {
2370  %cst = arith.constant 0.000000e+00 : f64
2371  %1 = arith.uitofp %arg0: i32 to f64
2372  %2 = arith.cmpf olt, %1, %cst : f64
2373  return %2 : i1
2374  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
2375  // CHECK: arith.cmpi ult, %[[arg0]], %[[c0]] : i32
2376}
2377
2378// CHECK-LABEL: @test3(
2379// CHECK-SAME: %[[arg0:.+]]:
2380func.func @test3(%arg0: i32) -> i1 {
2381  %cst = arith.constant 0.000000e+00 : f64
2382  %1 = arith.uitofp %arg0: i32 to f64
2383  %2 = arith.cmpf oge, %1, %cst : f64
2384  return %2 : i1
2385  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
2386  // CHECK: arith.cmpi uge, %[[arg0]], %[[c0]] : i32
2387}
2388
2389// CHECK-LABEL: @test4(
2390// CHECK-SAME: %[[arg0:.+]]:
2391func.func @test4(%arg0: i32) -> i1 {
2392  %cst = arith.constant 0.000000e+00 : f64
2393  %1 = arith.uitofp %arg0: i32 to f64
2394  %2 = arith.cmpf ogt, %1, %cst : f64
2395  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
2396  // CHECK: arith.cmpi ugt, %[[arg0]], %[[c0]] : i32
2397  return %2 : i1
2398}
2399
2400// CHECK-LABEL: @test5(
2401func.func @test5(%arg0: i32) -> i1 {
2402  %cst = arith.constant -4.400000e+00 : f64
2403  %1 = arith.uitofp %arg0: i32 to f64
2404  %2 = arith.cmpf ogt, %1, %cst : f64
2405  return %2 : i1
2406  // CHECK: %[[true:.+]] = arith.constant true
2407  // CHECK: return %[[true]] : i1
2408}
2409
2410// CHECK-LABEL: @test6(
2411func.func @test6(%arg0: i32) -> i1 {
2412  %cst = arith.constant -4.400000e+00 : f64
2413  %1 = arith.uitofp %arg0: i32 to f64
2414  %2 = arith.cmpf olt, %1, %cst : f64
2415  return %2 : i1
2416  // CHECK: %[[false:.+]] = arith.constant false
2417  // CHECK: return %[[false]] : i1
2418}
2419
2420// Check that optimizing unsigned >= comparisons correctly distinguishes
2421// positive and negative constants.
2422// CHECK-LABEL: @test7(
2423// CHECK-SAME: %[[arg0:.+]]:
2424func.func @test7(%arg0: i32) -> i1 {
2425  %cst = arith.constant 3.200000e+00 : f64
2426  %1 = arith.uitofp %arg0: i32 to f64
2427  %2 = arith.cmpf oge, %1, %cst : f64
2428  return %2 : i1
2429  // CHECK: %[[c3:.+]] = arith.constant 3 : i32
2430  // CHECK: arith.cmpi ugt, %[[arg0]], %[[c3]] : i32
2431}
2432
2433// -----
2434
2435// CHECK-LABEL: @foldShl(
2436// CHECK: %[[res:.+]] = arith.constant 4294967296 : i64
2437// CHECK: return %[[res]]
2438func.func @foldShl() -> i64 {
2439  %c1 = arith.constant 1 : i64
2440  %c32 = arith.constant 32 : i64
2441  %r = arith.shli %c1, %c32 : i64
2442  return %r : i64
2443}
2444
2445// CHECK-LABEL: @nofoldShl(
2446// CHECK: %[[res:.+]] = arith.shli
2447// CHECK: return %[[res]]
2448func.func @nofoldShl() -> i64 {
2449  %c1 = arith.constant 1 : i64
2450  %c132 = arith.constant 132 : i64
2451  %r = arith.shli %c1, %c132 : i64
2452  return %r : i64
2453}
2454
2455// CHECK-LABEL: @nofoldShl2(
2456// CHECK: %[[res:.+]] = arith.shli
2457// CHECK: return %[[res]]
2458func.func @nofoldShl2() -> i64 {
2459  %c1 = arith.constant 1 : i64
2460  %cm32 = arith.constant -32 : i64
2461  %r = arith.shli %c1, %cm32 : i64
2462  return %r : i64
2463}
2464
2465// CHECK-LABEL: @nofoldShl3(
2466// CHECK: %[[res:.+]] = arith.shli
2467// CHECK: return %[[res]]
2468func.func @nofoldShl3() -> i64 {
2469  %c1 = arith.constant 1 : i64
2470  %c64 = arith.constant 64 : i64
2471  // Note that this should return Poison in the future.
2472  %r = arith.shli %c1, %c64 : i64
2473  return %r : i64
2474}
2475
2476// CHECK-LABEL: @foldShru(
2477// CHECK: %[[res:.+]] = arith.constant 2 : i64
2478// CHECK: return %[[res]]
2479func.func @foldShru() -> i64 {
2480  %c1 = arith.constant 8 : i64
2481  %c32 = arith.constant 2 : i64
2482  %r = arith.shrui %c1, %c32 : i64
2483  return %r : i64
2484}
2485
2486// CHECK-LABEL: @foldShru2(
2487// CHECK: %[[res:.+]] = arith.constant 9223372036854775807 : i64
2488// CHECK: return %[[res]]
2489func.func @foldShru2() -> i64 {
2490  %c1 = arith.constant -2 : i64
2491  %c32 = arith.constant 1 : i64
2492  %r = arith.shrui %c1, %c32 : i64
2493  return %r : i64
2494}
2495
2496// CHECK-LABEL: @nofoldShru(
2497// CHECK: %[[res:.+]] = arith.shrui
2498// CHECK: return %[[res]]
2499func.func @nofoldShru() -> i64 {
2500  %c1 = arith.constant 8 : i64
2501  %c132 = arith.constant 132 : i64
2502  %r = arith.shrui %c1, %c132 : i64
2503  return %r : i64
2504}
2505
2506// CHECK-LABEL: @nofoldShru2(
2507// CHECK: %[[res:.+]] = arith.shrui
2508// CHECK: return %[[res]]
2509func.func @nofoldShru2() -> i64 {
2510  %c1 = arith.constant 8 : i64
2511  %cm32 = arith.constant -32 : i64
2512  %r = arith.shrui %c1, %cm32 : i64
2513  return %r : i64
2514}
2515
2516// CHECK-LABEL: @nofoldShru3(
2517// CHECK: %[[res:.+]] = arith.shrui
2518// CHECK: return %[[res]]
2519func.func @nofoldShru3() -> i64 {
2520  %c1 = arith.constant 8 : i64
2521  %c64 = arith.constant 64 : i64
2522  // Note that this should return Poison in the future.
2523  %r = arith.shrui %c1, %c64 : i64
2524  return %r : i64
2525}
2526
2527// CHECK-LABEL: @foldShrs(
2528// CHECK: %[[res:.+]] = arith.constant 2 : i64
2529// CHECK: return %[[res]]
2530func.func @foldShrs() -> i64 {
2531  %c1 = arith.constant 8 : i64
2532  %c32 = arith.constant 2 : i64
2533  %r = arith.shrsi %c1, %c32 : i64
2534  return %r : i64
2535}
2536
2537// CHECK-LABEL: @foldShrs2(
2538// CHECK: %[[res:.+]] = arith.constant -1 : i64
2539// CHECK: return %[[res]]
2540func.func @foldShrs2() -> i64 {
2541  %c1 = arith.constant -2 : i64
2542  %c32 = arith.constant 1 : i64
2543  %r = arith.shrsi %c1, %c32 : i64
2544  return %r : i64
2545}
2546
2547// CHECK-LABEL: @nofoldShrs(
2548// CHECK: %[[res:.+]] = arith.shrsi
2549// CHECK: return %[[res]]
2550func.func @nofoldShrs() -> i64 {
2551  %c1 = arith.constant 8 : i64
2552  %c132 = arith.constant 132 : i64
2553  %r = arith.shrsi %c1, %c132 : i64
2554  return %r : i64
2555}
2556
2557// CHECK-LABEL: @nofoldShrs2(
2558// CHECK: %[[res:.+]] = arith.shrsi
2559// CHECK: return %[[res]]
2560func.func @nofoldShrs2() -> i64 {
2561  %c1 = arith.constant 8 : i64
2562  %cm32 = arith.constant -32 : i64
2563  %r = arith.shrsi %c1, %cm32 : i64
2564  return %r : i64
2565}
2566
2567// CHECK-LABEL: @nofoldShrs3(
2568// CHECK: %[[res:.+]] = arith.shrsi
2569// CHECK: return %[[res]]
2570func.func @nofoldShrs3() -> i64 {
2571  %c1 = arith.constant 8 : i64
2572  %c64 = arith.constant 64 : i64
2573  // Note that this should return Poison in the future.
2574  %r = arith.shrsi %c1, %c64 : i64
2575  return %r : i64
2576}
2577
2578// -----
2579
2580// CHECK-LABEL: @test_negf(
2581// CHECK: %[[res:.+]] = arith.constant -2.0
2582// CHECK: return %[[res]]
2583func.func @test_negf() -> (f32) {
2584  %c = arith.constant 2.0 : f32
2585  %0 = arith.negf %c : f32
2586  return %0: f32
2587}
2588
2589// CHECK-LABEL: @test_negf1(
2590// CHECK-SAME: %[[arg0:.+]]:
2591// CHECK: return %[[arg0]]
2592func.func @test_negf1(%f : f32) -> (f32) {
2593  %0 = arith.negf %f : f32
2594  %1 = arith.negf %0 : f32
2595  return %1: f32
2596}
2597
2598// -----
2599
2600// CHECK-LABEL: @test_remui(
2601// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>
2602// CHECK: return %[[res]]
2603func.func @test_remui() -> (vector<4xi32>) {
2604  %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>
2605  %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
2606  %0 = arith.remui %v1, %v2 : vector<4xi32>
2607  return %0 : vector<4xi32>
2608}
2609
2610// // -----
2611
2612// CHECK-LABEL: @test_remui_1(
2613// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>
2614// CHECK: return %[[res]]
2615func.func @test_remui_1(%arg : vector<4xi32>) -> (vector<4xi32>) {
2616  %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>
2617  %0 = arith.remui %arg, %v : vector<4xi32>
2618  return %0 : vector<4xi32>
2619}
2620
2621// -----
2622
2623// CHECK-LABEL: @test_remsi(
2624// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>
2625// CHECK: return %[[res]]
2626func.func @test_remsi() -> (vector<4xi32>) {
2627  %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>
2628  %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
2629  %0 = arith.remsi %v1, %v2 : vector<4xi32>
2630  return %0 : vector<4xi32>
2631}
2632
2633// // -----
2634
2635// CHECK-LABEL: @test_remsi_1(
2636// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>
2637// CHECK: return %[[res]]
2638func.func @test_remsi_1(%arg : vector<4xi32>) -> (vector<4xi32>) {
2639  %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>
2640  %0 = arith.remsi %arg, %v : vector<4xi32>
2641  return %0 : vector<4xi32>
2642}
2643
2644// -----
2645
2646// CHECK-LABEL: @test_remf(
2647// CHECK: %[[res:.+]] = arith.constant 1.000000e+00 : f32
2648// CHECK: return %[[res]]
2649func.func @test_remf() -> (f32) {
2650  %v1 = arith.constant 3.0 : f32
2651  %v2 = arith.constant 2.0 : f32
2652  %0 = arith.remf %v1, %v2 : f32
2653  return %0 : f32
2654}
2655
2656// CHECK-LABEL: @test_remf2(
2657// CHECK: %[[respos:.+]] = arith.constant 1.000000e+00 : f32
2658// CHECK: %[[resneg:.+]] = arith.constant -1.000000e+00 : f32
2659// CHECK: return %[[respos]], %[[resneg]]
2660func.func @test_remf2() -> (f32, f32) {
2661  %v1 = arith.constant 3.0 : f32
2662  %v2 = arith.constant -2.0 : f32
2663  %v3 = arith.constant -3.0 : f32
2664  %0 = arith.remf %v1, %v2 : f32
2665  %1 = arith.remf %v3, %v2 : f32
2666  return %0, %1 : f32, f32
2667}
2668
2669// CHECK-LABEL: @test_remf_vec(
2670// CHECK: %[[res:.+]] = arith.constant dense<[1.000000e+00, 0.000000e+00, -1.000000e+00, 0.000000e+00]> : vector<4xf32>
2671// CHECK: return %[[res]]
2672func.func @test_remf_vec() -> (vector<4xf32>) {
2673  %v1 = arith.constant dense<[1.0, 2.0, -3.0, 4.0]> : vector<4xf32>
2674  %v2 = arith.constant dense<[2.0, 2.0, 2.0, 2.0]> : vector<4xf32>
2675  %0 = arith.remf %v1, %v2 : vector<4xf32>
2676  return %0 : vector<4xf32>
2677}
2678
2679// -----
2680
2681// CHECK-LABEL: @test_andi_not_fold_rhs(
2682// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]
2683// CHECK: %[[C:.*]] = arith.constant 0 : index
2684// CHECK: return %[[C]]
2685
2686func.func @test_andi_not_fold_rhs(%arg0 : index) -> index {
2687    %0 = arith.constant -1 : index
2688    %1 = arith.xori %arg0, %0 : index
2689    %2 = arith.andi %arg0, %1 : index
2690    return %2 : index
2691}
2692
2693
2694// CHECK-LABEL: @test_andi_not_fold_lhs(
2695// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]
2696// CHECK: %[[C:.*]] = arith.constant 0 : index
2697// CHECK: return %[[C]]
2698
2699func.func @test_andi_not_fold_lhs(%arg0 : index) -> index {
2700    %0 = arith.constant -1 : index
2701    %1 = arith.xori %arg0, %0 : index
2702    %2 = arith.andi %1, %arg0 : index
2703    return %2 : index
2704}
2705
2706// -----
2707
2708// CHECK-LABEL: @test_andi_not_fold_rhs_vec(
2709// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]
2710// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32>
2711// CHECK: return %[[C]]
2712
2713func.func @test_andi_not_fold_rhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> {
2714    %0 = arith.constant dense<[-1, -1]> : vector<2xi32>
2715    %1 = arith.xori %arg0, %0 : vector<2xi32>
2716    %2 = arith.andi %arg0, %1 : vector<2xi32>
2717    return %2 : vector<2xi32>
2718}
2719
2720
2721// CHECK-LABEL: @test_andi_not_fold_lhs_vec(
2722// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]
2723// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32>
2724// CHECK: return %[[C]]
2725
2726func.func @test_andi_not_fold_lhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> {
2727    %0 = arith.constant dense<[-1, -1]> : vector<2xi32>
2728    %1 = arith.xori %arg0, %0 : vector<2xi32>
2729    %2 = arith.andi %1, %arg0 : vector<2xi32>
2730    return %2 : vector<2xi32>
2731}
2732
2733// -----
2734/// xor(xor(x, a), a) -> x
2735
2736// CHECK-LABEL: @xorxor0(
2737//       CHECK-NOT: xori
2738//       CHECK:   return %arg0
2739func.func @xorxor0(%a : i32, %b : i32) -> i32 {
2740  %c = arith.xori %a, %b : i32
2741  %res = arith.xori %c, %b : i32
2742  return %res : i32
2743}
2744
2745// -----
2746/// xor(xor(a, x), a) -> x
2747
2748// CHECK-LABEL: @xorxor1(
2749//       CHECK-NOT: xori
2750//       CHECK:   return %arg0
2751func.func @xorxor1(%a : i32, %b : i32) -> i32 {
2752  %c = arith.xori %b, %a : i32
2753  %res = arith.xori %c, %b : i32
2754  return %res : i32
2755}
2756
2757// -----
2758/// xor(a, xor(x, a)) -> x
2759
2760// CHECK-LABEL: @xorxor2(
2761//       CHECK-NOT: xori
2762//       CHECK:   return %arg0
2763func.func @xorxor2(%a : i32, %b : i32) -> i32 {
2764  %c = arith.xori %a, %b : i32
2765  %res = arith.xori %b, %c : i32
2766  return %res : i32
2767}
2768
2769// -----
2770/// xor(a, xor(a, x)) -> x
2771
2772// CHECK-LABEL: @xorxor3(
2773//       CHECK-NOT: xori
2774//       CHECK:   return %arg0
2775func.func @xorxor3(%a : i32, %b : i32) -> i32 {
2776  %c = arith.xori %b, %a : i32
2777  %res = arith.xori %b, %c : i32
2778  return %res : i32
2779}
2780
2781// -----
2782
2783/// and(a, and(a, b)) -> and(a, b)
2784
2785// CHECK-LABEL: @andand0
2786//  CHECK-SAME:   (%[[A:.*]]: i32, %[[B:.*]]: i32)
2787//       CHECK:   %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
2788//       CHECK:   return %[[RES]]
2789func.func @andand0(%a : i32, %b : i32) -> i32 {
2790  %c = arith.andi %a, %b : i32
2791  %res = arith.andi %a, %c : i32
2792  return %res : i32
2793}
2794
2795// CHECK-LABEL: @andand1
2796//  CHECK-SAME:   (%[[A:.*]]: i32, %[[B:.*]]: i32)
2797//       CHECK:   %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
2798//       CHECK:   return %[[RES]]
2799func.func @andand1(%a : i32, %b : i32) -> i32 {
2800  %c = arith.andi %a, %b : i32
2801  %res = arith.andi %c, %a : i32
2802  return %res : i32
2803}
2804
2805// CHECK-LABEL: @andand2
2806//  CHECK-SAME:   (%[[A:.*]]: i32, %[[B:.*]]: i32)
2807//       CHECK:   %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
2808//       CHECK:   return %[[RES]]
2809func.func @andand2(%a : i32, %b : i32) -> i32 {
2810  %c = arith.andi %a, %b : i32
2811  %res = arith.andi %b, %c : i32
2812  return %res : i32
2813}
2814
2815// CHECK-LABEL: @andand3
2816//  CHECK-SAME:   (%[[A:.*]]: i32, %[[B:.*]]: i32)
2817//       CHECK:   %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
2818//       CHECK:   return %[[RES]]
2819func.func @andand3(%a : i32, %b : i32) -> i32 {
2820  %c = arith.andi %a, %b : i32
2821  %res = arith.andi %c, %b : i32
2822  return %res : i32
2823}
2824
2825// -----
2826
2827// CHECK-LABEL: @truncIShrSIToTrunciShrUI
2828//  CHECK-SAME:   (%[[A:.+]]: i64)
2829//  CHECK-NEXT:   %[[C32:.+]] = arith.constant 32 : i64
2830//  CHECK-NEXT:   %[[SHR:.+]] = arith.shrui %[[A]], %[[C32]] : i64
2831//  CHECK-NEXT:   %[[TRU:.+]] = arith.trunci %[[SHR]] : i64 to i32
2832//  CHECK-NEXT:   return %[[TRU]] : i32
2833func.func @truncIShrSIToTrunciShrUI(%a: i64) -> i32 {
2834  %c32 = arith.constant 32: i64
2835  %sh = arith.shrsi %a, %c32 : i64
2836  %hi = arith.trunci %sh: i64 to i32
2837  return %hi : i32
2838}
2839
2840// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt1
2841//       CHECK:   arith.shrsi
2842func.func @truncIShrSIToTrunciShrUIBadShiftAmt1(%a: i64) -> i32 {
2843  %c33 = arith.constant 33: i64
2844  %sh = arith.shrsi %a, %c33 : i64
2845  %hi = arith.trunci %sh: i64 to i32
2846  return %hi : i32
2847}
2848
2849// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt2
2850//  CHECK:        arith.shrsi
2851func.func @truncIShrSIToTrunciShrUIBadShiftAmt2(%a: i64) -> i32 {
2852  %c31 = arith.constant 31: i64
2853  %sh = arith.shrsi %a, %c31 : i64
2854  %hi = arith.trunci %sh: i64 to i32
2855  return %hi : i32
2856}
2857
2858// CHECK-LABEL: @wideMulToMulSIExtended
2859//  CHECK-SAME:   (%[[A:.+]]: i32, %[[B:.+]]: i32)
2860//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[A]], %[[B]] : i32
2861//  CHECK-NEXT:   return %[[HIGH]] : i32
2862func.func @wideMulToMulSIExtended(%a: i32, %b: i32) -> i32 {
2863  %x = arith.extsi %a: i32 to i64
2864  %y = arith.extsi %b: i32 to i64
2865  %m = arith.muli %x, %y: i64
2866  %c32 = arith.constant 32: i64
2867  %sh = arith.shrui %m, %c32 : i64
2868  %hi = arith.trunci %sh: i64 to i32
2869  return %hi : i32
2870}
2871
2872// CHECK-LABEL: @wideMulToMulSIExtendedVector
2873//  CHECK-SAME:   (%[[A:.+]]: vector<3xi32>, %[[B:.+]]: vector<3xi32>)
2874//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[A]], %[[B]] : vector<3xi32>
2875//  CHECK-NEXT:   return %[[HIGH]] : vector<3xi32>
2876func.func @wideMulToMulSIExtendedVector(%a: vector<3xi32>, %b: vector<3xi32>) -> vector<3xi32> {
2877  %x = arith.extsi %a: vector<3xi32> to vector<3xi64>
2878  %y = arith.extsi %b: vector<3xi32> to vector<3xi64>
2879  %m = arith.muli %x, %y: vector<3xi64>
2880  %c32 = arith.constant dense<32>: vector<3xi64>
2881  %sh = arith.shrui %m, %c32 : vector<3xi64>
2882  %hi = arith.trunci %sh: vector<3xi64> to vector<3xi32>
2883  return %hi : vector<3xi32>
2884}
2885
2886// CHECK-LABEL: @wideMulToMulUIExtended
2887//  CHECK-SAME:   (%[[A:.+]]: i32, %[[B:.+]]: i32)
2888//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[A]], %[[B]] : i32
2889//  CHECK-NEXT:   return %[[HIGH]] : i32
2890func.func @wideMulToMulUIExtended(%a: i32, %b: i32) -> i32 {
2891  %x = arith.extui %a: i32 to i64
2892  %y = arith.extui %b: i32 to i64
2893  %m = arith.muli %x, %y: i64
2894  %c32 = arith.constant 32: i64
2895  %sh = arith.shrui %m, %c32 : i64
2896  %hi = arith.trunci %sh: i64 to i32
2897  return %hi : i32
2898}
2899
2900// CHECK-LABEL: @wideMulToMulUIExtendedVector
2901//  CHECK-SAME:   (%[[A:.+]]: vector<3xi32>, %[[B:.+]]: vector<3xi32>)
2902//  CHECK-NEXT:   %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[A]], %[[B]] : vector<3xi32>
2903//  CHECK-NEXT:   return %[[HIGH]] : vector<3xi32>
2904func.func @wideMulToMulUIExtendedVector(%a: vector<3xi32>, %b: vector<3xi32>) -> vector<3xi32> {
2905  %x = arith.extui %a: vector<3xi32> to vector<3xi64>
2906  %y = arith.extui %b: vector<3xi32> to vector<3xi64>
2907  %m = arith.muli %x, %y: vector<3xi64>
2908  %c32 = arith.constant dense<32>: vector<3xi64>
2909  %sh = arith.shrui %m, %c32 : vector<3xi64>
2910  %hi = arith.trunci %sh: vector<3xi64> to vector<3xi32>
2911  return %hi : vector<3xi32>
2912}
2913
2914// CHECK-LABEL: @wideMulToMulIExtendedMixedExt
2915//       CHECK:   arith.muli
2916//       CHECK:   arith.shrui
2917//       CHECK:   arith.trunci
2918func.func @wideMulToMulIExtendedMixedExt(%a: i32, %b: i32) -> i32 {
2919  %x = arith.extsi %a: i32 to i64
2920  %y = arith.extui %b: i32 to i64
2921  %m = arith.muli %x, %y: i64
2922  %c32 = arith.constant 32: i64
2923  %sh = arith.shrui %m, %c32 : i64
2924  %hi = arith.trunci %sh: i64 to i32
2925  return %hi : i32
2926}
2927
2928// CHECK-LABEL: @wideMulToMulSIExtendedBadExt
2929//       CHECK:   arith.muli
2930//       CHECK:   arith.shrui
2931//       CHECK:   arith.trunci
2932func.func @wideMulToMulSIExtendedBadExt(%a: i16, %b: i16) -> i32 {
2933  %x = arith.extsi %a: i16 to i64
2934  %y = arith.extsi %b: i16 to i64
2935  %m = arith.muli %x, %y: i64
2936  %c32 = arith.constant 32: i64
2937  %sh = arith.shrui %m, %c32 : i64
2938  %hi = arith.trunci %sh: i64 to i32
2939  return %hi : i32
2940}
2941
2942// CHECK-LABEL: @wideMulToMulSIExtendedBadShift1
2943//       CHECK:   arith.muli
2944//       CHECK:   arith.shrui
2945//       CHECK:   arith.trunci
2946func.func @wideMulToMulSIExtendedBadShift1(%a: i32, %b: i32) -> i32 {
2947  %x = arith.extsi %a: i32 to i64
2948  %y = arith.extsi %b: i32 to i64
2949  %m = arith.muli %x, %y: i64
2950  %c33 = arith.constant 33: i64
2951  %sh = arith.shrui %m, %c33 : i64
2952  %hi = arith.trunci %sh: i64 to i32
2953  return %hi : i32
2954}
2955
2956// CHECK-LABEL: @wideMulToMulSIExtendedBadShift2
2957//       CHECK:   arith.muli
2958//       CHECK:   arith.shrui
2959//       CHECK:   arith.trunci
2960func.func @wideMulToMulSIExtendedBadShift2(%a: i32, %b: i32) -> i32 {
2961  %x = arith.extsi %a: i32 to i64
2962  %y = arith.extsi %b: i32 to i64
2963  %m = arith.muli %x, %y: i64
2964  %c31 = arith.constant 31: i64
2965  %sh = arith.shrui %m, %c31 : i64
2966  %hi = arith.trunci %sh: i64 to i32
2967  return %hi : i32
2968}
2969
2970// CHECK-LABEL: @foldShli0
2971// CHECK-SAME: (%[[ARG:.*]]: i64)
2972//       CHECK:   return %[[ARG]] : i64
2973func.func @foldShli0(%x : i64) -> i64 {
2974  %c0 = arith.constant 0 : i64
2975  %r = arith.shli %x, %c0 : i64
2976  return %r : i64
2977}
2978
2979// CHECK-LABEL: @foldShrui0
2980// CHECK-SAME: (%[[ARG:.*]]: i64)
2981//       CHECK:   return %[[ARG]] : i64
2982func.func @foldShrui0(%x : i64) -> i64 {
2983  %c0 = arith.constant 0 : i64
2984  %r = arith.shrui %x, %c0 : i64
2985  return %r : i64
2986}
2987
2988// CHECK-LABEL: @foldShrsi0
2989// CHECK-SAME: (%[[ARG:.*]]: i64)
2990//       CHECK:   return %[[ARG]] : i64
2991func.func @foldShrsi0(%x : i64) -> i64 {
2992  %c0 = arith.constant 0 : i64
2993  %r = arith.shrsi %x, %c0 : i64
2994  return %r : i64
2995}
2996
2997// CHECK-LABEL: @foldOrXor1
2998//  CHECK-SAME: (%[[ARG:.*]]: i1)
2999//       CHECK:   %[[ONE:.*]] = arith.constant true
3000//       CHECK:   return %[[ONE]]
3001func.func @foldOrXor1(%arg0: i1) -> i1 {
3002  %0 = arith.constant true
3003  %1 = arith.xori %arg0, %0 : i1
3004  %2 = arith.ori %arg0, %1 : i1
3005  return %2 : i1
3006}
3007
3008// CHECK-LABEL: @foldOrXor2
3009//  CHECK-SAME: (%[[ARG:.*]]: i1)
3010//       CHECK:   %[[ONE:.*]] = arith.constant true
3011//       CHECK:   return %[[ONE]]
3012func.func @foldOrXor2(%arg0: i1) -> i1 {
3013  %0 = arith.constant true
3014  %1 = arith.xori %0, %arg0 : i1
3015  %2 = arith.ori %arg0, %1 : i1
3016  return %2 : i1
3017}
3018
3019// CHECK-LABEL: @foldOrXor3
3020//  CHECK-SAME: (%[[ARG:.*]]: i1)
3021//       CHECK:   %[[ONE:.*]] = arith.constant true
3022//       CHECK:   return %[[ONE]]
3023func.func @foldOrXor3(%arg0: i1) -> i1 {
3024  %0 = arith.constant true
3025  %1 = arith.xori %arg0, %0 : i1
3026  %2 = arith.ori %1, %arg0 : i1
3027  return %2 : i1
3028}
3029
3030// CHECK-LABEL: @foldOrXor4
3031//  CHECK-SAME: (%[[ARG:.*]]: i1)
3032//       CHECK:   %[[ONE:.*]] = arith.constant true
3033//       CHECK:   return %[[ONE]]
3034func.func @foldOrXor4(%arg0: i1) -> i1 {
3035  %0 = arith.constant true
3036  %1 = arith.xori %0, %arg0 : i1
3037  %2 = arith.ori %1, %arg0 : i1
3038  return %2 : i1
3039}
3040
3041// CHECK-LABEL: @foldOrXor5
3042//  CHECK-SAME: (%[[ARG:.*]]: i32)
3043//       CHECK:   %[[ONE:.*]] = arith.constant -1
3044//       CHECK:   return %[[ONE]]
3045func.func @foldOrXor5(%arg0: i32) -> i32 {
3046  %0 = arith.constant -1 : i32
3047  %1 = arith.xori %arg0, %0 : i32
3048  %2 = arith.ori %arg0, %1 : i32
3049  return %2 : i32
3050}
3051
3052// CHECK-LABEL: @foldOrXor6
3053//  CHECK-SAME: (%[[ARG:.*]]: index)
3054//       CHECK:   %[[ONE:.*]] = arith.constant -1
3055//       CHECK:   return %[[ONE]]
3056func.func @foldOrXor6(%arg0: index) -> index {
3057  %0 = arith.constant -1 : index
3058  %1 = arith.xori %arg0, %0 : index
3059  %2 = arith.ori %arg0, %1 : index
3060  return %2 : index
3061}
3062
3063// CHECK-LABEL: @selectOfPoison
3064// CHECK-SAME: %[[ARG:[[:alnum:]]+]]: i32
3065// CHECK: %[[UB:.*]] = ub.poison : i32
3066// CHECK: return %[[ARG]], %[[ARG]], %[[UB]], %[[ARG]]
3067func.func @selectOfPoison(%cond : i1, %arg: i32) -> (i32, i32, i32, i32) {
3068  %poison = ub.poison : i32
3069  %select1 = arith.select %cond, %poison, %arg : i32
3070  %select2 = arith.select %cond, %arg, %poison : i32
3071
3072  // Check that constant folding is applied prior to poison handling.
3073  %true = arith.constant true
3074  %false = arith.constant false
3075  %select3 = arith.select %true, %poison, %arg : i32
3076  %select4 = arith.select %false, %poison, %arg : i32
3077  return %select1, %select2, %select3, %select4 : i32, i32, i32, i32
3078}
3079
3080// CHECK-LABEL: @addi_poison1
3081//       CHECK:   %[[P:.*]] = ub.poison : i32
3082//       CHECK:   return %[[P]]
3083func.func @addi_poison1(%arg: i32) -> i32 {
3084  %0 = ub.poison : i32
3085  %1 = arith.addi %0, %arg : i32
3086  return %1 : i32
3087}
3088
3089// CHECK-LABEL: @addi_poison2
3090//       CHECK:   %[[P:.*]] = ub.poison : i32
3091//       CHECK:   return %[[P]]
3092func.func @addi_poison2(%arg: i32) -> i32 {
3093  %0 = ub.poison : i32
3094  %1 = arith.addi %arg, %0 : i32
3095  return %1 : i32
3096}
3097
3098// CHECK-LABEL: @addf_poison1
3099//       CHECK:   %[[P:.*]] = ub.poison : f32
3100//       CHECK:   return %[[P]]
3101func.func @addf_poison1(%arg: f32) -> f32 {
3102  %0 = ub.poison : f32
3103  %1 = arith.addf %0, %arg : f32
3104  return %1 : f32
3105}
3106
3107// CHECK-LABEL: @addf_poison2
3108//       CHECK:   %[[P:.*]] = ub.poison : f32
3109//       CHECK:   return %[[P]]
3110func.func @addf_poison2(%arg: f32) -> f32 {
3111  %0 = ub.poison : f32
3112  %1 = arith.addf %arg, %0 : f32
3113  return %1 : f32
3114}
3115
3116
3117// CHECK-LABEL: @negf_poison
3118//       CHECK:   %[[P:.*]] = ub.poison : f32
3119//       CHECK:   return %[[P]]
3120func.func @negf_poison() -> f32 {
3121  %0 = ub.poison : f32
3122  %1 = arith.negf %0 : f32
3123  return %1 : f32
3124}
3125
3126// CHECK-LABEL: @extsi_poison
3127//       CHECK:   %[[P:.*]] = ub.poison : i64
3128//       CHECK:   return %[[P]]
3129func.func @extsi_poison() -> i64 {
3130  %0 = ub.poison : i32
3131  %1 = arith.extsi %0 : i32 to i64
3132  return %1 : i64
3133}
3134
3135// Just checks that this doesn't crash.
3136// CHECK-LABEL: @unsignedExtendConstantResource
3137func.func @unsignedExtendConstantResource() -> tensor<i16> {
3138  %c2 = arith.constant dense_resource<blob1> : tensor<i8>
3139  %ext = arith.extui %c2 : tensor<i8> to tensor<i16>
3140  return %ext : tensor<i16>
3141}
3142
3143// CHECK-LABEL: @extsi_i0
3144//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i16
3145//       CHECK:   return %[[ZERO]] : i16
3146func.func @extsi_i0() -> i16 {
3147  %c0 = arith.constant 0 : i0
3148  %extsi = arith.extsi %c0 : i0 to i16
3149  return %extsi : i16
3150}
3151
3152// CHECK-LABEL: @extui_i0
3153//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i16
3154//       CHECK:   return %[[ZERO]] : i16
3155func.func @extui_i0() -> i16 {
3156  %c0 = arith.constant 0 : i0
3157  %extui = arith.extui %c0 : i0 to i16
3158  return %extui : i16
3159}
3160
3161// CHECK-LABEL: @trunc_i0
3162//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3163//       CHECK:   return %[[ZERO]] : i0
3164func.func @trunc_i0() -> i0 {
3165  %cFF = arith.constant 0xFF : i8
3166  %trunc = arith.trunci %cFF : i8 to i0
3167  return %trunc : i0
3168}
3169
3170// CHECK-LABEL: @shli_i0
3171//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3172//       CHECK:   return %[[ZERO]] : i0
3173func.func @shli_i0() -> i0 {
3174  %c0 = arith.constant 0 : i0
3175  %shli = arith.shli %c0, %c0 : i0
3176  return %shli : i0
3177}
3178
3179// CHECK-LABEL: @shrsi_i0
3180//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3181//       CHECK:   return %[[ZERO]] : i0
3182func.func @shrsi_i0() -> i0 {
3183  %c0 = arith.constant 0 : i0
3184  %shrsi = arith.shrsi %c0, %c0 : i0
3185  return %shrsi : i0
3186}
3187
3188// CHECK-LABEL: @shrui_i0
3189//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3190//       CHECK:   return %[[ZERO]] : i0
3191func.func @shrui_i0() -> i0 {
3192  %c0 = arith.constant 0 : i0
3193  %shrui = arith.shrui %c0, %c0 : i0
3194  return %shrui : i0
3195}
3196
3197// CHECK-LABEL: @maxsi_i0
3198//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3199//       CHECK:   return %[[ZERO]] : i0
3200func.func @maxsi_i0() -> i0 {
3201  %c0 = arith.constant 0 : i0
3202  %maxsi = arith.maxsi %c0, %c0 : i0
3203  return %maxsi : i0
3204}
3205
3206// CHECK-LABEL: @minsi_i0
3207//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3208//       CHECK:   return %[[ZERO]] : i0
3209func.func @minsi_i0() -> i0 {
3210  %c0 = arith.constant 0 : i0
3211  %minsi = arith.minsi %c0, %c0 : i0
3212  return %minsi : i0
3213}
3214
3215// CHECK-LABEL: @mulsi_extended_i0
3216//       CHECK:   %[[ZERO:.*]] = arith.constant 0 : i0
3217//       CHECK:   return %[[ZERO]], %[[ZERO]] : i0
3218func.func @mulsi_extended_i0() -> (i0, i0) {
3219  %c0 = arith.constant 0 : i0
3220  %mulsi_extended:2 = arith.mulsi_extended %c0, %c0 : i0
3221  return %mulsi_extended#0, %mulsi_extended#1 : i0, i0
3222}
3223
3224// CHECK-LABEL: @sequences_fastmath_contract
3225// CHECK-SAME: ([[ARG0:%.+]]: bf16)
3226// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]
3227// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]
3228// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]
3229// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]
3230// CHECK: return [[TRUNCF]] : bf16
3231func.func @sequences_fastmath_contract(%arg0: bf16) -> bf16 {
3232  %0 = arith.extf %arg0 fastmath<contract> : bf16 to f32
3233  %1 = math.absf %0 : f32
3234  %2 = arith.truncf %1 fastmath<contract> : f32 to bf16
3235  %3 = arith.extf %2 fastmath<contract> : bf16 to f32
3236  %4 = math.sin %3 : f32
3237  %5 = arith.truncf %4 fastmath<contract> : f32 to bf16
3238  return %5 : bf16
3239}
3240
3241// CHECK-LABEL: @sequences_no_fastmath
3242// CHECK-SAME: ([[ARG0:%.+]]: bf16)
3243// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]
3244// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]
3245// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ABSF]]
3246// CHECK: [[EXTF1:%.+]] = arith.extf [[TRUNCF1]]
3247// CHECK: [[SIN:%.+]] = math.sin [[EXTF1]]
3248// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]
3249// CHECK: return [[TRUNCF]] : bf16
3250func.func @sequences_no_fastmath(%arg0: bf16) -> bf16 {
3251  %0 = arith.extf %arg0 : bf16 to f32
3252  %1 = math.absf %0 : f32
3253  %2 = arith.truncf %1 : f32 to bf16
3254  %3 = arith.extf %2 : bf16 to f32
3255  %4 = math.sin %3 : f32
3256  %5 = arith.truncf %4 : f32 to bf16
3257  return %5 : bf16
3258}
3259
3260// CHECK-LABEL: @eliminate_cast_to_f16
3261// CHECK: return [[arg0:%.+]] : f32
3262func.func @eliminate_cast_to_f16(%arg0: f32) -> f32 {
3263  %0 = arith.truncf %arg0 fastmath<contract> : f32 to f16
3264  %1 = arith.extf %0 fastmath<contract> : f16 to f32
3265  return %1 : f32
3266}
3267
3268// CHECK-LABEL: @eliminate_cast_to_bf16
3269// CHECK: return [[arg0:%.+]] : f32
3270func.func @eliminate_cast_to_bf16(%arg0: f32) -> f32 {
3271  %0 = arith.truncf %arg0 fastmath<contract> : f32 to bf16
3272  %1 = arith.extf %0 fastmath<contract> : bf16 to f32
3273  return %1 : f32
3274}
3275
3276// CHECK-LABEL: @bf16_sin_vector
3277// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>)
3278// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]
3279// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]
3280// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]
3281// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]
3282// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16>
3283func.func @bf16_sin_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {
3284  %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3285  %1 = math.absf %0 : vector<32x32x32xf32>
3286  %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3287  %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3288  %4 = math.sin %3 : vector<32x32x32xf32>
3289  %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3290  return %5 : vector<32x32x32xbf16>
3291}
3292
3293// CHECK-LABEL: @f16_sin_vector
3294// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xf16>)
3295// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]
3296// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]
3297// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]
3298// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]
3299// CHECK: return [[TRUNCF]] : vector<32x32x32xf16>
3300func.func @f16_sin_vector(%arg0: vector<32x32x32xf16>) -> vector<32x32x32xf16> {
3301  %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32>
3302  %1 = math.absf %0 : vector<32x32x32xf32>
3303  %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16>
3304  %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32>
3305  %4 = math.sin %3 : vector<32x32x32xf32>
3306  %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16>
3307  return %5 : vector<32x32x32xf16>
3308}
3309
3310// CHECK-LABEL: @bf16_branch_vector
3311// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>)
3312// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]
3313// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]
3314// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]]
3315// CHECK-DAG: [[COS:%.+]] = math.cos [[ABSF]]
3316// CHECK: [[ADDF:%.+]] = arith.addf [[SIN]], [[COS]]
3317// CHECK: [[TRUNCF:%.+]] = arith.truncf [[ADDF]]
3318// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16>
3319func.func @bf16_branch_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {
3320  %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3321  %1 = math.absf %0 : vector<32x32x32xf32>
3322  %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3323  %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3324  %4 = math.sin %3 : vector<32x32x32xf32>
3325  %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3326  %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3327  %7 = math.cos %3 : vector<32x32x32xf32>
3328  %8 = arith.truncf %7 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3329  %9 = arith.extf %8 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3330  %10 = arith.addf %6, %9 : vector<32x32x32xf32>
3331  %11 = arith.truncf %10 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3332  return %11 : vector<32x32x32xbf16>
3333}
3334
3335// CHECK-LABEL: @bf16_fma
3336// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>, [[ARG1:%.+]]: vector<32x32x32xbf16>, [[ARG2:%.+]]: vector<32x32x32xbf16>)
3337// CHECK: [[EXTF0:%.+]] = arith.extf [[ARG0]]
3338// CHECK: [[ABSF:%.+]] = math.absf [[EXTF0]]
3339// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]]
3340// CHECK: [[TRUNCF0:%.+]] = arith.truncf [[SIN]]
3341// CHECK-DAG: [[FMA:%.+]] = math.fma [[TRUNCF0]], [[ARG1]], [[ARG2]]
3342// CHECK: [[EXTF1:%.+]] = arith.extf [[FMA]]
3343// CHECK: [[ADDF:%.+]] = arith.addf [[EXTF1]], [[SIN]]
3344// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ADDF]]
3345// CHECK: return [[TRUNCF1]] : vector<32x32x32xbf16>
3346func.func @bf16_fma(%arg0: vector<32x32x32xbf16>, %arg1: vector<32x32x32xbf16>, %arg2: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {
3347  %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3348  %1 = math.absf %0 : vector<32x32x32xf32>
3349  %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3350  %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3351  %4 = math.sin %3 : vector<32x32x32xf32>
3352  %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3353  %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3354  %7 = math.fma %5, %arg1, %arg2 : vector<32x32x32xbf16>
3355  %8 = arith.extf %7 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>
3356  %9 = arith.addf %8, %6 : vector<32x32x32xf32>
3357  %10 = arith.truncf %9 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>
3358  return %10 : vector<32x32x32xbf16>
3359}
3360
3361{-#
3362  dialect_resources: {
3363    builtin: {
3364      // Note: This is just copied blob, the actual value isn't used or checked.
3365      blob1: "0x08000000010000000000000002000000000000000300000000000000"
3366    }
3367  }
3368#-}
3369