1// RUN: mlir-opt %s -canonicalize --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: @selToNot
58//       CHECK:       %[[trueval:.+]] = arith.constant true
59//       CHECK:       %[[res:.+]] = arith.xori %arg0, %[[trueval]] : i1
60//       CHECK:   return %[[res]]
61func.func @selToNot(%arg0: i1) -> i1 {
62  %true = arith.constant true
63  %false = arith.constant false
64  %res = arith.select %arg0, %false, %true : i1
65  return %res : i1
66}
67
68// CHECK-LABEL: @selToArith
69//       CHECK-NEXT:       %[[trueval:.+]] = arith.constant true
70//       CHECK-NEXT:       %[[notcmp:.+]] = arith.xori %arg0, %[[trueval]] : i1
71//       CHECK-NEXT:       %[[condtrue:.+]] = arith.andi %arg0, %arg1 : i1
72//       CHECK-NEXT:       %[[condfalse:.+]] = arith.andi %[[notcmp]], %arg2 : i1
73//       CHECK-NEXT:       %[[res:.+]] = arith.ori %[[condtrue]], %[[condfalse]] : i1
74//       CHECK:   return %[[res]]
75func.func @selToArith(%arg0: i1, %arg1 : i1, %arg2 : i1) -> i1 {
76  %res = arith.select %arg0, %arg1, %arg2 : i1
77  return %res : i1
78}
79
80// Test case: Folding of comparisons with equal operands.
81// CHECK-LABEL: @cmpi_equal_operands
82//   CHECK-DAG:   %[[T:.*]] = arith.constant true
83//   CHECK-DAG:   %[[F:.*]] = arith.constant false
84//       CHECK:   return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],
85//  CHECK-SAME:          %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]
86func.func @cmpi_equal_operands(%arg0: i64)
87    -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
88  %0 = arith.cmpi eq, %arg0, %arg0 : i64
89  %1 = arith.cmpi sle, %arg0, %arg0 : i64
90  %2 = arith.cmpi sge, %arg0, %arg0 : i64
91  %3 = arith.cmpi ule, %arg0, %arg0 : i64
92  %4 = arith.cmpi uge, %arg0, %arg0 : i64
93  %5 = arith.cmpi ne, %arg0, %arg0 : i64
94  %6 = arith.cmpi slt, %arg0, %arg0 : i64
95  %7 = arith.cmpi sgt, %arg0, %arg0 : i64
96  %8 = arith.cmpi ult, %arg0, %arg0 : i64
97  %9 = arith.cmpi ugt, %arg0, %arg0 : i64
98  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9
99      : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
100}
101
102// Test case: Folding of comparisons with equal vector operands.
103// CHECK-LABEL: @cmpi_equal_vector_operands
104//   CHECK-DAG:   %[[T:.*]] = arith.constant dense<true>
105//   CHECK-DAG:   %[[F:.*]] = arith.constant dense<false>
106//       CHECK:   return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],
107//  CHECK-SAME:          %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]
108func.func @cmpi_equal_vector_operands(%arg0: vector<1x8xi64>)
109    -> (vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
110        vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
111	vector<1x8xi1>, vector<1x8xi1>) {
112  %0 = arith.cmpi eq, %arg0, %arg0 : vector<1x8xi64>
113  %1 = arith.cmpi sle, %arg0, %arg0 : vector<1x8xi64>
114  %2 = arith.cmpi sge, %arg0, %arg0 : vector<1x8xi64>
115  %3 = arith.cmpi ule, %arg0, %arg0 : vector<1x8xi64>
116  %4 = arith.cmpi uge, %arg0, %arg0 : vector<1x8xi64>
117  %5 = arith.cmpi ne, %arg0, %arg0 : vector<1x8xi64>
118  %6 = arith.cmpi slt, %arg0, %arg0 : vector<1x8xi64>
119  %7 = arith.cmpi sgt, %arg0, %arg0 : vector<1x8xi64>
120  %8 = arith.cmpi ult, %arg0, %arg0 : vector<1x8xi64>
121  %9 = arith.cmpi ugt, %arg0, %arg0 : vector<1x8xi64>
122  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9
123      : vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
124        vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,
125	vector<1x8xi1>, vector<1x8xi1>
126}
127
128// -----
129
130// CHECK-LABEL: @cmpOfExtSI
131//  CHECK-NEXT:   return %arg0
132func.func @cmpOfExtSI(%arg0: i1) -> i1 {
133  %ext = arith.extsi %arg0 : i1 to i64
134  %c0 = arith.constant 0 : i64
135  %res = arith.cmpi ne, %ext, %c0 : i64
136  return %res : i1
137}
138
139// CHECK-LABEL: @cmpOfExtUI
140//  CHECK-NEXT:   return %arg0
141func.func @cmpOfExtUI(%arg0: i1) -> i1 {
142  %ext = arith.extui %arg0 : i1 to i64
143  %c0 = arith.constant 0 : i64
144  %res = arith.cmpi ne, %ext, %c0 : i64
145  return %res : i1
146}
147
148// -----
149
150// CHECK-LABEL: @extSIOfExtUI
151//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
152//       CHECK:   return %[[res]]
153func.func @extSIOfExtUI(%arg0: i1) -> i64 {
154  %ext1 = arith.extui %arg0 : i1 to i8
155  %ext2 = arith.extsi %ext1 : i8 to i64
156  return %ext2 : i64
157}
158
159// CHECK-LABEL: @extUIOfExtUI
160//       CHECK:   %[[res:.+]] = arith.extui %arg0 : i1 to i64
161//       CHECK:   return %[[res]]
162func.func @extUIOfExtUI(%arg0: i1) -> i64 {
163  %ext1 = arith.extui %arg0 : i1 to i8
164  %ext2 = arith.extui %ext1 : i8 to i64
165  return %ext2 : i64
166}
167
168// CHECK-LABEL: @extSIOfExtSI
169//       CHECK:   %[[res:.+]] = arith.extsi %arg0 : i1 to i64
170//       CHECK:   return %[[res]]
171func.func @extSIOfExtSI(%arg0: i1) -> i64 {
172  %ext1 = arith.extsi %arg0 : i1 to i8
173  %ext2 = arith.extsi %ext1 : i8 to i64
174  return %ext2 : i64
175}
176
177// -----
178
179// CHECK-LABEL: @cmpIExtSINE
180//       CHECK:  %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
181//       CHECK:   return %[[comb]]
182func.func @cmpIExtSINE(%arg0: i8, %arg1: i8) -> i1 {
183  %ext0 = arith.extsi %arg0 : i8 to i64
184  %ext1 = arith.extsi %arg1 : i8 to i64
185  %res = arith.cmpi ne, %ext0, %ext1 : i64
186  return %res : i1
187}
188
189// CHECK-LABEL: @cmpIExtSIEQ
190//       CHECK:  %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
191//       CHECK:   return %[[comb]]
192func.func @cmpIExtSIEQ(%arg0: i8, %arg1: i8) -> i1 {
193  %ext0 = arith.extsi %arg0 : i8 to i64
194  %ext1 = arith.extsi %arg1 : i8 to i64
195  %res = arith.cmpi eq, %ext0, %ext1 : i64
196  return %res : i1
197}
198
199// CHECK-LABEL: @cmpIExtUINE
200//       CHECK:  %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
201//       CHECK:   return %[[comb]]
202func.func @cmpIExtUINE(%arg0: i8, %arg1: i8) -> i1 {
203  %ext0 = arith.extui %arg0 : i8 to i64
204  %ext1 = arith.extui %arg1 : i8 to i64
205  %res = arith.cmpi ne, %ext0, %ext1 : i64
206  return %res : i1
207}
208
209// CHECK-LABEL: @cmpIExtUIEQ
210//       CHECK:  %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
211//       CHECK:   return %[[comb]]
212func.func @cmpIExtUIEQ(%arg0: i8, %arg1: i8) -> i1 {
213  %ext0 = arith.extui %arg0 : i8 to i64
214  %ext1 = arith.extui %arg1 : i8 to i64
215  %res = arith.cmpi eq, %ext0, %ext1 : i64
216  return %res : i1
217}
218
219// -----
220
221// CHECK-LABEL: @andOfExtSI
222//       CHECK:  %[[comb:.+]] = arith.andi %arg0, %arg1 : i8
223//       CHECK:  %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64
224//       CHECK:   return %[[ext]]
225func.func @andOfExtSI(%arg0: i8, %arg1: i8) -> i64 {
226  %ext0 = arith.extsi %arg0 : i8 to i64
227  %ext1 = arith.extsi %arg1 : i8 to i64
228  %res = arith.andi %ext0, %ext1 : i64
229  return %res : i64
230}
231
232// CHECK-LABEL: @andOfExtUI
233//       CHECK:  %[[comb:.+]] = arith.andi %arg0, %arg1 : i8
234//       CHECK:  %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64
235//       CHECK:   return %[[ext]]
236func.func @andOfExtUI(%arg0: i8, %arg1: i8) -> i64 {
237  %ext0 = arith.extui %arg0 : i8 to i64
238  %ext1 = arith.extui %arg1 : i8 to i64
239  %res = arith.andi %ext0, %ext1 : i64
240  return %res : i64
241}
242
243// CHECK-LABEL: @orOfExtSI
244//       CHECK:  %[[comb:.+]] = arith.ori %arg0, %arg1 : i8
245//       CHECK:  %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64
246//       CHECK:   return %[[ext]]
247func.func @orOfExtSI(%arg0: i8, %arg1: i8) -> i64 {
248  %ext0 = arith.extsi %arg0 : i8 to i64
249  %ext1 = arith.extsi %arg1 : i8 to i64
250  %res = arith.ori %ext0, %ext1 : i64
251  return %res : i64
252}
253
254// CHECK-LABEL: @orOfExtUI
255//       CHECK:  %[[comb:.+]] = arith.ori %arg0, %arg1 : i8
256//       CHECK:  %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64
257//       CHECK:   return %[[ext]]
258func.func @orOfExtUI(%arg0: i8, %arg1: i8) -> i64 {
259  %ext0 = arith.extui %arg0 : i8 to i64
260  %ext1 = arith.extui %arg1 : i8 to i64
261  %res = arith.ori %ext0, %ext1 : i64
262  return %res : i64
263}
264
265// -----
266
267// CHECK-LABEL: @indexCastOfSignExtend
268//       CHECK:   %[[res:.+]] = arith.index_cast %arg0 : i8 to index
269//       CHECK:   return %[[res]]
270func.func @indexCastOfSignExtend(%arg0: i8) -> index {
271  %ext = arith.extsi %arg0 : i8 to i16
272  %idx = arith.index_cast %ext : i16 to index
273  return %idx : index
274}
275
276// CHECK-LABEL: @signExtendConstant
277//       CHECK:   %[[cres:.+]] = arith.constant -2 : i16
278//       CHECK:   return %[[cres]]
279func.func @signExtendConstant() -> i16 {
280  %c-2 = arith.constant -2 : i8
281  %ext = arith.extsi %c-2 : i8 to i16
282  return %ext : i16
283}
284
285// CHECK-LABEL: @signExtendConstantSplat
286//       CHECK:   %[[cres:.+]] = arith.constant dense<-2> : vector<4xi16>
287//       CHECK:   return %[[cres]]
288func.func @signExtendConstantSplat() -> vector<4xi16> {
289  %c-2 = arith.constant -2 : i8
290  %splat = vector.splat %c-2 : vector<4xi8>
291  %ext = arith.extsi %splat : vector<4xi8> to vector<4xi16>
292  return %ext : vector<4xi16>
293}
294
295// CHECK-LABEL: @signExtendConstantVector
296//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
297//       CHECK:   return %[[cres]]
298func.func @signExtendConstantVector() -> vector<4xi16> {
299  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
300  %ext = arith.extsi %vector : vector<4xi8> to vector<4xi16>
301  return %ext : vector<4xi16>
302}
303
304// CHECK-LABEL: @unsignedExtendConstant
305//       CHECK:   %[[cres:.+]] = arith.constant 2 : i16
306//       CHECK:   return %[[cres]]
307func.func @unsignedExtendConstant() -> i16 {
308  %c2 = arith.constant 2 : i8
309  %ext = arith.extui %c2 : i8 to i16
310  return %ext : i16
311}
312
313// CHECK-LABEL: @unsignedExtendConstantSplat
314//       CHECK:   %[[cres:.+]] = arith.constant dense<2> : vector<4xi16>
315//       CHECK:   return %[[cres]]
316func.func @unsignedExtendConstantSplat() -> vector<4xi16> {
317  %c2 = arith.constant 2 : i8
318  %splat = vector.splat %c2 : vector<4xi8>
319  %ext = arith.extui %splat : vector<4xi8> to vector<4xi16>
320  return %ext : vector<4xi16>
321}
322
323// CHECK-LABEL: @unsignedExtendConstantVector
324//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
325//       CHECK:   return %[[cres]]
326func.func @unsignedExtendConstantVector() -> vector<4xi16> {
327  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
328  %ext = arith.extui %vector : vector<4xi8> to vector<4xi16>
329  return %ext : vector<4xi16>
330}
331
332// CHECK-LABEL: @truncConstant
333//       CHECK:   %[[cres:.+]] = arith.constant -2 : i16
334//       CHECK:   return %[[cres]]
335func.func @truncConstant(%arg0: i8) -> i16 {
336  %c-2 = arith.constant -2 : i32
337  %tr = arith.trunci %c-2 : i32 to i16
338  return %tr : i16
339}
340
341// CHECK-LABEL: @truncConstantSplat
342//       CHECK:   %[[cres:.+]] = arith.constant dense<-2> : vector<4xi8>
343//       CHECK:   return %[[cres]]
344func.func @truncConstantSplat() -> vector<4xi8> {
345  %c-2 = arith.constant -2 : i16
346  %splat = vector.splat %c-2 : vector<4xi16>
347  %trunc = arith.trunci %splat : vector<4xi16> to vector<4xi8>
348  return %trunc : vector<4xi8>
349}
350
351// CHECK-LABEL: @truncConstantVector
352//       CHECK:   %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>
353//       CHECK:   return %[[cres]]
354func.func @truncConstantVector() -> vector<4xi8> {
355  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>
356  %trunc = arith.trunci %vector : vector<4xi16> to vector<4xi8>
357  return %trunc : vector<4xi8>
358}
359
360// CHECK-LABEL: @truncTrunc
361//       CHECK:   %[[cres:.+]] = arith.trunci %arg0 : i64 to i8
362//       CHECK:   return %[[cres]]
363func.func @truncTrunc(%arg0: i64) -> i8 {
364  %tr1 = arith.trunci %arg0 : i64 to i32
365  %tr2 = arith.trunci %tr1 : i32 to i8
366  return %tr2 : i8
367}
368
369// CHECK-LABEL: @truncFPConstant
370//       CHECK:   %[[cres:.+]] = arith.constant 1.000000e+00 : bf16
371//       CHECK:   return %[[cres]]
372func.func @truncFPConstant() -> bf16 {
373  %cst = arith.constant 1.000000e+00 : f32
374  %0 = arith.truncf %cst : f32 to bf16
375  return %0 : bf16
376}
377
378// Test that cases with rounding are NOT propagated
379// CHECK-LABEL: @truncFPConstantRounding
380//       CHECK:   arith.constant 1.444000e+25 : f32
381//       CHECK:   truncf
382func.func @truncFPConstantRounding() -> bf16 {
383  %cst = arith.constant 1.444000e+25 : f32
384  %0 = arith.truncf %cst : f32 to bf16
385  return %0 : bf16
386}
387
388// CHECK-LABEL: @tripleAddAdd
389//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
390//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
391//       CHECK:   return %[[add]]
392func.func @tripleAddAdd(%arg0: index) -> index {
393  %c17 = arith.constant 17 : index
394  %c42 = arith.constant 42 : index
395  %add1 = arith.addi %c17, %arg0 : index
396  %add2 = arith.addi %c42, %add1 : index
397  return %add2 : index
398}
399
400// CHECK-LABEL: @tripleAddSub0
401//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
402//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
403//       CHECK:   return %[[add]]
404func.func @tripleAddSub0(%arg0: index) -> index {
405  %c17 = arith.constant 17 : index
406  %c42 = arith.constant 42 : index
407  %add1 = arith.subi %c17, %arg0 : index
408  %add2 = arith.addi %c42, %add1 : index
409  return %add2 : index
410}
411
412// CHECK-LABEL: @tripleAddSub1
413//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
414//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
415//       CHECK:   return %[[add]]
416func.func @tripleAddSub1(%arg0: index) -> index {
417  %c17 = arith.constant 17 : index
418  %c42 = arith.constant 42 : index
419  %add1 = arith.subi %arg0, %c17 : index
420  %add2 = arith.addi %c42, %add1 : index
421  return %add2 : index
422}
423
424// CHECK-LABEL: @tripleSubAdd0
425//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
426//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
427//       CHECK:   return %[[add]]
428func.func @tripleSubAdd0(%arg0: index) -> index {
429  %c17 = arith.constant 17 : index
430  %c42 = arith.constant 42 : index
431  %add1 = arith.addi %c17, %arg0 : index
432  %add2 = arith.subi %c42, %add1 : index
433  return %add2 : index
434}
435
436// CHECK-LABEL: @tripleSubAdd1
437//       CHECK:   %[[cres:.+]] = arith.constant -25 : index
438//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
439//       CHECK:   return %[[add]]
440func.func @tripleSubAdd1(%arg0: index) -> index {
441  %c17 = arith.constant 17 : index
442  %c42 = arith.constant 42 : index
443  %add1 = arith.addi %c17, %arg0 : index
444  %add2 = arith.subi %add1, %c42 : index
445  return %add2 : index
446}
447
448// CHECK-LABEL: @tripleSubSub0
449//       CHECK:   %[[cres:.+]] = arith.constant 25 : index
450//       CHECK:   %[[add:.+]] = arith.addi %arg0, %[[cres]] : index
451//       CHECK:   return %[[add]]
452func.func @tripleSubSub0(%arg0: index) -> index {
453  %c17 = arith.constant 17 : index
454  %c42 = arith.constant 42 : index
455  %add1 = arith.subi %c17, %arg0 : index
456  %add2 = arith.subi %c42, %add1 : index
457  return %add2 : index
458}
459
460// CHECK-LABEL: @tripleSubSub1
461//       CHECK:   %[[cres:.+]] = arith.constant -25 : index
462//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
463//       CHECK:   return %[[add]]
464func.func @tripleSubSub1(%arg0: index) -> index {
465  %c17 = arith.constant 17 : index
466  %c42 = arith.constant 42 : index
467  %add1 = arith.subi %c17, %arg0 : index
468  %add2 = arith.subi %add1, %c42 : index
469  return %add2 : index
470}
471
472// CHECK-LABEL: @tripleSubSub2
473//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
474//       CHECK:   %[[add:.+]] = arith.subi %[[cres]], %arg0 : index
475//       CHECK:   return %[[add]]
476func.func @tripleSubSub2(%arg0: index) -> index {
477  %c17 = arith.constant 17 : index
478  %c42 = arith.constant 42 : index
479  %add1 = arith.subi %arg0, %c17 : index
480  %add2 = arith.subi %c42, %add1 : index
481  return %add2 : index
482}
483
484// CHECK-LABEL: @tripleSubSub3
485//       CHECK:   %[[cres:.+]] = arith.constant 59 : index
486//       CHECK:   %[[add:.+]] = arith.subi %arg0, %[[cres]] : index
487//       CHECK:   return %[[add]]
488func.func @tripleSubSub3(%arg0: index) -> index {
489  %c17 = arith.constant 17 : index
490  %c42 = arith.constant 42 : index
491  %add1 = arith.subi %arg0, %c17 : index
492  %add2 = arith.subi %add1, %c42 : index
493  return %add2 : index
494}
495
496// CHECK-LABEL: @doubleAddSub1
497//  CHECK-NEXT:   return %arg0
498func.func @doubleAddSub1(%arg0: index, %arg1 : index) -> index {
499  %sub = arith.subi %arg0, %arg1 : index
500  %add = arith.addi %sub, %arg1 : index
501  return %add : index
502}
503
504// CHECK-LABEL: @doubleAddSub2
505//  CHECK-NEXT:   return %arg0
506func.func @doubleAddSub2(%arg0: index, %arg1 : index) -> index {
507  %sub = arith.subi %arg0, %arg1 : index
508  %add = arith.addi %arg1, %sub : index
509  return %add : index
510}
511
512// CHECK-LABEL: @notCmpEQ
513//       CHECK:   %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
514//       CHECK:   return %[[cres]]
515func.func @notCmpEQ(%arg0: i8, %arg1: i8) -> i1 {
516  %true = arith.constant true
517  %cmp = arith.cmpi "eq", %arg0, %arg1 : i8
518  %ncmp = arith.xori %cmp, %true : i1
519  return %ncmp : i1
520}
521
522// CHECK-LABEL: @notCmpEQ2
523//       CHECK:   %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8
524//       CHECK:   return %[[cres]]
525func.func @notCmpEQ2(%arg0: i8, %arg1: i8) -> i1 {
526  %true = arith.constant true
527  %cmp = arith.cmpi "eq", %arg0, %arg1 : i8
528  %ncmp = arith.xori %true, %cmp : i1
529  return %ncmp : i1
530}
531
532// CHECK-LABEL: @notCmpNE
533//       CHECK:   %[[cres:.+]] = arith.cmpi eq, %arg0, %arg1 : i8
534//       CHECK:   return %[[cres]]
535func.func @notCmpNE(%arg0: i8, %arg1: i8) -> i1 {
536  %true = arith.constant true
537  %cmp = arith.cmpi "ne", %arg0, %arg1 : i8
538  %ncmp = arith.xori %cmp, %true : i1
539  return %ncmp : i1
540}
541
542// CHECK-LABEL: @notCmpSLT
543//       CHECK:   %[[cres:.+]] = arith.cmpi sge, %arg0, %arg1 : i8
544//       CHECK:   return %[[cres]]
545func.func @notCmpSLT(%arg0: i8, %arg1: i8) -> i1 {
546  %true = arith.constant true
547  %cmp = arith.cmpi "slt", %arg0, %arg1 : i8
548  %ncmp = arith.xori %cmp, %true : i1
549  return %ncmp : i1
550}
551
552// CHECK-LABEL: @notCmpSLE
553//       CHECK:   %[[cres:.+]] = arith.cmpi sgt, %arg0, %arg1 : i8
554//       CHECK:   return %[[cres]]
555func.func @notCmpSLE(%arg0: i8, %arg1: i8) -> i1 {
556  %true = arith.constant true
557  %cmp = arith.cmpi "sle", %arg0, %arg1 : i8
558  %ncmp = arith.xori %cmp, %true : i1
559  return %ncmp : i1
560}
561
562// CHECK-LABEL: @notCmpSGT
563//       CHECK:   %[[cres:.+]] = arith.cmpi sle, %arg0, %arg1 : i8
564//       CHECK:   return %[[cres]]
565func.func @notCmpSGT(%arg0: i8, %arg1: i8) -> i1 {
566  %true = arith.constant true
567  %cmp = arith.cmpi "sgt", %arg0, %arg1 : i8
568  %ncmp = arith.xori %cmp, %true : i1
569  return %ncmp : i1
570}
571
572// CHECK-LABEL: @notCmpSGE
573//       CHECK:   %[[cres:.+]] = arith.cmpi slt, %arg0, %arg1 : i8
574//       CHECK:   return %[[cres]]
575func.func @notCmpSGE(%arg0: i8, %arg1: i8) -> i1 {
576  %true = arith.constant true
577  %cmp = arith.cmpi "sge", %arg0, %arg1 : i8
578  %ncmp = arith.xori %cmp, %true : i1
579  return %ncmp : i1
580}
581
582// CHECK-LABEL: @notCmpULT
583//       CHECK:   %[[cres:.+]] = arith.cmpi uge, %arg0, %arg1 : i8
584//       CHECK:   return %[[cres]]
585func.func @notCmpULT(%arg0: i8, %arg1: i8) -> i1 {
586  %true = arith.constant true
587  %cmp = arith.cmpi "ult", %arg0, %arg1 : i8
588  %ncmp = arith.xori %cmp, %true : i1
589  return %ncmp : i1
590}
591
592// CHECK-LABEL: @notCmpULE
593//       CHECK:   %[[cres:.+]] = arith.cmpi ugt, %arg0, %arg1 : i8
594//       CHECK:   return %[[cres]]
595func.func @notCmpULE(%arg0: i8, %arg1: i8) -> i1 {
596  %true = arith.constant true
597  %cmp = arith.cmpi "ule", %arg0, %arg1 : i8
598  %ncmp = arith.xori %cmp, %true : i1
599  return %ncmp : i1
600}
601
602// CHECK-LABEL: @notCmpUGT
603//       CHECK:   %[[cres:.+]] = arith.cmpi ule, %arg0, %arg1 : i8
604//       CHECK:   return %[[cres]]
605func.func @notCmpUGT(%arg0: i8, %arg1: i8) -> i1 {
606  %true = arith.constant true
607  %cmp = arith.cmpi "ugt", %arg0, %arg1 : i8
608  %ncmp = arith.xori %cmp, %true : i1
609  return %ncmp : i1
610}
611
612// CHECK-LABEL: @notCmpUGE
613//       CHECK:   %[[cres:.+]] = arith.cmpi ult, %arg0, %arg1 : i8
614//       CHECK:   return %[[cres]]
615func.func @notCmpUGE(%arg0: i8, %arg1: i8) -> i1 {
616  %true = arith.constant true
617  %cmp = arith.cmpi "uge", %arg0, %arg1 : i8
618  %ncmp = arith.xori %cmp, %true : i1
619  return %ncmp : i1
620}
621
622// -----
623
624// CHECK-LABEL: @xorxor(
625//       CHECK-NOT: xori
626//       CHECK:   return %arg0
627func.func @xorxor(%cmp : i1) -> i1 {
628  %true = arith.constant true
629  %ncmp = arith.xori %cmp, %true : i1
630  %nncmp = arith.xori %ncmp, %true : i1
631  return %nncmp : i1
632}
633
634// -----
635
636// CHECK-LABEL: @bitcastSameType(
637// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
638func.func @bitcastSameType(%arg : f32) -> f32 {
639  // CHECK: return %[[ARG]]
640  %res = arith.bitcast %arg : f32 to f32
641  return %res : f32
642}
643
644// -----
645
646// CHECK-LABEL: @bitcastConstantFPtoI(
647func.func @bitcastConstantFPtoI() -> i32 {
648  // CHECK: %[[C0:.+]] = arith.constant 0 : i32
649  // CHECK: return %[[C0]]
650  %c0 = arith.constant 0.0 : f32
651  %res = arith.bitcast %c0 : f32 to i32
652  return %res : i32
653}
654
655// -----
656
657// CHECK-LABEL: @bitcastConstantItoFP(
658func.func @bitcastConstantItoFP() -> f32 {
659  // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f32
660  // CHECK: return %[[C0]]
661  %c0 = arith.constant 0 : i32
662  %res = arith.bitcast %c0 : i32 to f32
663  return %res : f32
664}
665
666// -----
667
668// CHECK-LABEL: @bitcastConstantFPtoFP(
669func.func @bitcastConstantFPtoFP() -> f16 {
670  // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f16
671  // CHECK: return %[[C0]]
672  %c0 = arith.constant 0.0 : bf16
673  %res = arith.bitcast %c0 : bf16 to f16
674  return %res : f16
675}
676
677// -----
678
679// CHECK-LABEL: @bitcastConstantVecFPtoI(
680func.func @bitcastConstantVecFPtoI() -> vector<3xf32> {
681  // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xf32>
682  // CHECK: return %[[C0]]
683  %c0 = arith.constant dense<0> : vector<3xi32>
684  %res = arith.bitcast %c0 : vector<3xi32> to vector<3xf32>
685  return %res : vector<3xf32>
686}
687
688// -----
689
690// CHECK-LABEL: @bitcastConstantVecItoFP(
691func.func @bitcastConstantVecItoFP() -> vector<3xi32> {
692  // CHECK: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32>
693  // CHECK: return %[[C0]]
694  %c0 = arith.constant dense<0.0> : vector<3xf32>
695  %res = arith.bitcast %c0 : vector<3xf32> to vector<3xi32>
696  return %res : vector<3xi32>
697}
698
699// -----
700
701// CHECK-LABEL: @bitcastConstantVecFPtoFP(
702func.func @bitcastConstantVecFPtoFP() -> vector<3xbf16> {
703  // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xbf16>
704  // CHECK: return %[[C0]]
705  %c0 = arith.constant dense<0.0> : vector<3xf16>
706  %res = arith.bitcast %c0 : vector<3xf16> to vector<3xbf16>
707  return %res : vector<3xbf16>
708}
709
710// -----
711
712// CHECK-LABEL: @bitcastBackAndForth(
713// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
714func.func @bitcastBackAndForth(%arg : i32) -> i32 {
715  // CHECK: return %[[ARG]]
716  %f = arith.bitcast %arg : i32 to f32
717  %res = arith.bitcast %f : f32 to i32
718  return %res : i32
719}
720
721// -----
722
723// CHECK-LABEL: @bitcastOfBitcast(
724// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]
725func.func @bitcastOfBitcast(%arg : i16) -> i16 {
726  // CHECK: return %[[ARG]]
727  %f = arith.bitcast %arg : i16 to f16
728  %bf = arith.bitcast %f : f16 to bf16
729  %res = arith.bitcast %bf : bf16 to i16
730  return %res : i16
731}
732
733// -----
734
735// CHECK-LABEL: test_maxsi
736// CHECK: %[[C0:.+]] = arith.constant 42
737// CHECK: %[[MAX_INT_CST:.+]] = arith.constant 127
738// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]
739// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
740func.func @test_maxsi(%arg0 : i8) -> (i8, i8, i8, i8) {
741  %maxIntCst = arith.constant 127 : i8
742  %minIntCst = arith.constant -128 : i8
743  %c0 = arith.constant 42 : i8
744  %0 = arith.maxsi %arg0, %arg0 : i8
745  %1 = arith.maxsi %arg0, %maxIntCst : i8
746  %2 = arith.maxsi %arg0, %minIntCst : i8
747  %3 = arith.maxsi %arg0, %c0 : i8
748  return %0, %1, %2, %3: i8, i8, i8, i8
749}
750
751// CHECK-LABEL: test_maxsi2
752// CHECK: %[[C0:.+]] = arith.constant 42
753// CHECK: %[[MAX_INT_CST:.+]] = arith.constant 127
754// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]
755// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
756func.func @test_maxsi2(%arg0 : i8) -> (i8, i8, i8, i8) {
757  %maxIntCst = arith.constant 127 : i8
758  %minIntCst = arith.constant -128 : i8
759  %c0 = arith.constant 42 : i8
760  %0 = arith.maxsi %arg0, %arg0 : i8
761  %1 = arith.maxsi %maxIntCst, %arg0: i8
762  %2 = arith.maxsi %minIntCst, %arg0: i8
763  %3 = arith.maxsi %c0, %arg0 : i8
764  return %0, %1, %2, %3: i8, i8, i8, i8
765}
766
767// -----
768
769// CHECK-LABEL: test_maxui
770// CHECK: %[[C0:.+]] = arith.constant 42
771// CHECK: %[[MAX_INT_CST:.+]] = arith.constant -1
772// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]
773// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
774func.func @test_maxui(%arg0 : i8) -> (i8, i8, i8, i8) {
775  %maxIntCst = arith.constant 255 : i8
776  %minIntCst = arith.constant 0 : i8
777  %c0 = arith.constant 42 : i8
778  %0 = arith.maxui %arg0, %arg0 : i8
779  %1 = arith.maxui %arg0, %maxIntCst : i8
780  %2 = arith.maxui %arg0, %minIntCst : i8
781  %3 = arith.maxui %arg0, %c0 : i8
782  return %0, %1, %2, %3: i8, i8, i8, i8
783}
784
785// CHECK-LABEL: test_maxui
786// CHECK: %[[C0:.+]] = arith.constant 42
787// CHECK: %[[MAX_INT_CST:.+]] = arith.constant -1
788// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]
789// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]
790func.func @test_maxui2(%arg0 : i8) -> (i8, i8, i8, i8) {
791  %maxIntCst = arith.constant 255 : i8
792  %minIntCst = arith.constant 0 : i8
793  %c0 = arith.constant 42 : i8
794  %0 = arith.maxui %arg0, %arg0 : i8
795  %1 = arith.maxui %maxIntCst, %arg0 : i8
796  %2 = arith.maxui %minIntCst, %arg0 : i8
797  %3 = arith.maxui %c0, %arg0 : i8
798  return %0, %1, %2, %3: i8, i8, i8, i8
799}
800
801// -----
802
803// CHECK-LABEL: test_minsi
804// CHECK: %[[C0:.+]] = arith.constant 42
805// CHECK: %[[MIN_INT_CST:.+]] = arith.constant -128
806// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]
807// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
808func.func @test_minsi(%arg0 : i8) -> (i8, i8, i8, i8) {
809  %maxIntCst = arith.constant 127 : i8
810  %minIntCst = arith.constant -128 : i8
811  %c0 = arith.constant 42 : i8
812  %0 = arith.minsi %arg0, %arg0 : i8
813  %1 = arith.minsi %arg0, %maxIntCst : i8
814  %2 = arith.minsi %arg0, %minIntCst : i8
815  %3 = arith.minsi %arg0, %c0 : i8
816  return %0, %1, %2, %3: i8, i8, i8, i8
817}
818
819// CHECK-LABEL: test_minsi
820// CHECK: %[[C0:.+]] = arith.constant 42
821// CHECK: %[[MIN_INT_CST:.+]] = arith.constant -128
822// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]
823// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
824func.func @test_minsi2(%arg0 : i8) -> (i8, i8, i8, i8) {
825  %maxIntCst = arith.constant 127 : i8
826  %minIntCst = arith.constant -128 : i8
827  %c0 = arith.constant 42 : i8
828  %0 = arith.minsi %arg0, %arg0 : i8
829  %1 = arith.minsi %maxIntCst, %arg0 : i8
830  %2 = arith.minsi %minIntCst, %arg0 : i8
831  %3 = arith.minsi %c0, %arg0 : i8
832  return %0, %1, %2, %3: i8, i8, i8, i8
833}
834
835// -----
836
837// CHECK-LABEL: test_minui
838// CHECK: %[[C0:.+]] = arith.constant 42
839// CHECK: %[[MIN_INT_CST:.+]] = arith.constant 0
840// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]
841// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
842func.func @test_minui(%arg0 : i8) -> (i8, i8, i8, i8) {
843  %maxIntCst = arith.constant 255 : i8
844  %minIntCst = arith.constant 0 : i8
845  %c0 = arith.constant 42 : i8
846  %0 = arith.minui %arg0, %arg0 : i8
847  %1 = arith.minui %arg0, %maxIntCst : i8
848  %2 = arith.minui %arg0, %minIntCst : i8
849  %3 = arith.minui %arg0, %c0 : i8
850  return %0, %1, %2, %3: i8, i8, i8, i8
851}
852
853// CHECK-LABEL: test_minui
854// CHECK: %[[C0:.+]] = arith.constant 42
855// CHECK: %[[MIN_INT_CST:.+]] = arith.constant 0
856// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]
857// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]
858func.func @test_minui2(%arg0 : i8) -> (i8, i8, i8, i8) {
859  %maxIntCst = arith.constant 255 : i8
860  %minIntCst = arith.constant 0 : i8
861  %c0 = arith.constant 42 : i8
862  %0 = arith.minui %arg0, %arg0 : i8
863  %1 = arith.minui %maxIntCst, %arg0 : i8
864  %2 = arith.minui %minIntCst, %arg0 : i8
865  %3 = arith.minui %c0, %arg0 : i8
866  return %0, %1, %2, %3: i8, i8, i8, i8
867}
868
869// -----
870
871// CHECK-LABEL: @test_minf(
872func.func @test_minf(%arg0 : f32) -> (f32, f32, f32) {
873  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
874  // CHECK-NEXT:  %[[X:.+]] = arith.minf %arg0, %[[C0]]
875  // CHECK-NEXT:  return %[[X]], %arg0, %arg0
876  %c0 = arith.constant 0.0 : f32
877  %inf = arith.constant 0x7F800000 : f32
878  %0 = arith.minf %c0, %arg0 : f32
879  %1 = arith.minf %arg0, %arg0 : f32
880  %2 = arith.minf %inf, %arg0 : f32
881  return %0, %1, %2 : f32, f32, f32
882}
883
884// -----
885
886// CHECK-LABEL: @test_maxf(
887func.func @test_maxf(%arg0 : f32) -> (f32, f32, f32) {
888  // CHECK-DAG:   %[[C0:.+]] = arith.constant
889  // CHECK-NEXT:  %[[X:.+]] = arith.maxf %arg0, %[[C0]]
890  // CHECK-NEXT:   return %[[X]], %arg0, %arg0
891  %c0 = arith.constant 0.0 : f32
892  %-inf = arith.constant 0xFF800000 : f32
893  %0 = arith.maxf %c0, %arg0 : f32
894  %1 = arith.maxf %arg0, %arg0 : f32
895  %2 = arith.maxf %-inf, %arg0 : f32
896  return %0, %1, %2 : f32, f32, f32
897}
898
899// -----
900
901// CHECK-LABEL: @test_addf(
902func.func @test_addf(%arg0 : f32) -> (f32, f32, f32, f32) {
903  // CHECK-DAG:   %[[C2:.+]] = arith.constant 2.0
904  // CHECK-DAG:   %[[C0:.+]] = arith.constant 0.0
905  // CHECK-NEXT:  %[[X:.+]] = arith.addf %arg0, %[[C0]]
906  // CHECK-NEXT:   return %[[X]], %arg0, %arg0, %[[C2]]
907  %c0 = arith.constant 0.0 : f32
908  %c-0 = arith.constant -0.0 : f32
909  %c1 = arith.constant 1.0 : f32
910  %0 = arith.addf %c0, %arg0 : f32
911  %1 = arith.addf %arg0, %c-0 : f32
912  %2 = arith.addf %c-0, %arg0 : f32
913  %3 = arith.addf %c1, %c1 : f32
914  return %0, %1, %2, %3 : f32, f32, f32, f32
915}
916
917// -----
918
919// CHECK-LABEL: @test_subf(
920func.func @test_subf(%arg0 : f16) -> (f16, f16, f16) {
921  // CHECK-DAG:   %[[C1:.+]] = arith.constant -1.0
922  // CHECK-DAG:   %[[C0:.+]] = arith.constant -0.0
923  // CHECK-NEXT:  %[[X:.+]] = arith.subf %arg0, %[[C0]]
924  // CHECK-NEXT:   return %arg0, %[[X]], %[[C1]]
925  %c0 = arith.constant 0.0 : f16
926  %c-0 = arith.constant -0.0 : f16
927  %c1 = arith.constant 1.0 : f16
928  %0 = arith.subf %arg0, %c0 : f16
929  %1 = arith.subf %arg0, %c-0 : f16
930  %2 = arith.subf %c0, %c1 : f16
931  return %0, %1, %2 : f16, f16, f16
932}
933
934// -----
935
936// CHECK-LABEL: @test_mulf(
937func.func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) {
938  // CHECK-DAG:   %[[C2:.+]] = arith.constant 2.0
939  // CHECK-DAG:   %[[C4:.+]] = arith.constant 4.0
940  // CHECK-NEXT:  %[[X:.+]] = arith.mulf %arg0, %[[C2]]
941  // CHECK-NEXT:  return %[[X]], %arg0, %arg0, %[[C4]]
942  %c1 = arith.constant 1.0 : f32
943  %c2 = arith.constant 2.0 : f32
944  %0 = arith.mulf %c2, %arg0 : f32
945  %1 = arith.mulf %arg0, %c1 : f32
946  %2 = arith.mulf %c1, %arg0 : f32
947  %3 = arith.mulf %c2, %c2 : f32
948  return %0, %1, %2, %3 : f32, f32, f32, f32
949}
950
951// -----
952
953// CHECK-LABEL: @test_divf(
954func.func @test_divf(%arg0 : f64) -> (f64, f64) {
955  // CHECK-NEXT:  %[[C5:.+]] = arith.constant 5.000000e-01
956  // CHECK-NEXT:   return %arg0, %[[C5]]
957  %c1 = arith.constant 1.0 : f64
958  %c2 = arith.constant 2.0 : f64
959  %0 = arith.divf %arg0, %c1 : f64
960  %1 = arith.divf %c1, %c2 : f64
961  return %0, %1 : f64, f64
962}
963
964// -----
965
966// CHECK-LABEL: @test_cmpf(
967func.func @test_cmpf(%arg0 : f32) -> (i1, i1, i1, i1) {
968//   CHECK-DAG:   %[[T:.*]] = arith.constant true
969//   CHECK-DAG:   %[[F:.*]] = arith.constant false
970//       CHECK:   return %[[F]], %[[F]], %[[T]], %[[T]]
971  %nan = arith.constant 0x7fffffff : f32
972  %0 = arith.cmpf olt, %nan, %arg0 : f32
973  %1 = arith.cmpf olt, %arg0, %nan : f32
974  %2 = arith.cmpf ugt, %nan, %arg0 : f32
975  %3 = arith.cmpf ugt, %arg0, %nan : f32
976  return %0, %1, %2, %3 : i1, i1, i1, i1
977}
978
979// -----
980
981// CHECK-LABEL: @constant_FPtoUI(
982func.func @constant_FPtoUI() -> i32 {
983  // CHECK: %[[C0:.+]] = arith.constant 2 : i32
984  // CHECK: return %[[C0]]
985  %c0 = arith.constant 2.0 : f32
986  %res = arith.fptoui %c0 : f32 to i32
987  return %res : i32
988}
989
990// CHECK-LABEL: @constant_FPtoUI_splat(
991func.func @constant_FPtoUI_splat() -> vector<4xi32> {
992  // CHECK: %[[C0:.+]] = arith.constant dense<2> : vector<4xi32>
993  // CHECK: return %[[C0]]
994  %c0 = arith.constant 2.0 : f32
995  %splat = vector.splat %c0 : vector<4xf32>
996  %res = arith.fptoui %splat : vector<4xf32> to vector<4xi32>
997  return %res : vector<4xi32>
998}
999
1000// CHECK-LABEL: @constant_FPtoUI_vector(
1001func.func @constant_FPtoUI_vector() -> vector<4xi32> {
1002  // CHECK: %[[C0:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
1003  // CHECK: return %[[C0]]
1004  %vector = arith.constant dense<[1.0, 3.0, 5.0, 7.0]> : vector<4xf32>
1005  %res = arith.fptoui %vector : vector<4xf32> to vector<4xi32>
1006  return %res : vector<4xi32>
1007}
1008
1009// -----
1010// CHECK-LABEL: @invalid_constant_FPtoUI(
1011func.func @invalid_constant_FPtoUI() -> i32 {
1012  // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32
1013  // CHECK: %[[C1:.+]] = arith.fptoui %[[C0]] : f32 to i32
1014  // CHECK: return %[[C1]]
1015  %c0 = arith.constant -2.0 : f32
1016  %res = arith.fptoui %c0 : f32 to i32
1017  return %res : i32
1018}
1019
1020// -----
1021// CHECK-LABEL: @constant_FPtoSI(
1022func.func @constant_FPtoSI() -> i32 {
1023  // CHECK: %[[C0:.+]] = arith.constant -2 : i32
1024  // CHECK: return %[[C0]]
1025  %c0 = arith.constant -2.0 : f32
1026  %res = arith.fptosi %c0 : f32 to i32
1027  return %res : i32
1028}
1029
1030// CHECK-LABEL: @constant_FPtoSI_splat(
1031func.func @constant_FPtoSI_splat() -> vector<4xi32> {
1032  // CHECK: %[[C0:.+]] = arith.constant dense<-2> : vector<4xi32>
1033  // CHECK: return %[[C0]]
1034  %c0 = arith.constant -2.0 : f32
1035  %splat = vector.splat %c0 : vector<4xf32>
1036  %res = arith.fptosi %splat : vector<4xf32> to vector<4xi32>
1037  return %res : vector<4xi32>
1038}
1039
1040// CHECK-LABEL: @constant_FPtoSI_vector(
1041func.func @constant_FPtoSI_vector() -> vector<4xi32> {
1042  // CHECK: %[[C0:.+]] = arith.constant dense<[-1, -3, -5, -7]> : vector<4xi32>
1043  // CHECK: return %[[C0]]
1044  %vector = arith.constant dense<[-1.0, -3.0, -5.0, -7.0]> : vector<4xf32>
1045  %res = arith.fptosi %vector : vector<4xf32> to vector<4xi32>
1046  return %res : vector<4xi32>
1047}
1048
1049// -----
1050// CHECK-LABEL: @invalid_constant_FPtoSI(
1051func.func @invalid_constant_FPtoSI() -> i8 {
1052  // CHECK: %[[C0:.+]] = arith.constant 2.000000e+10 : f32
1053  // CHECK: %[[C1:.+]] = arith.fptosi %[[C0]] : f32 to i8
1054  // CHECK: return %[[C1]]
1055  %c0 = arith.constant 2.0e10 : f32
1056  %res = arith.fptosi %c0 : f32 to i8
1057  return %res : i8
1058}
1059
1060// CHECK-LABEL: @constant_SItoFP(
1061func.func @constant_SItoFP() -> f32 {
1062  // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32
1063  // CHECK: return %[[C0]]
1064  %c0 = arith.constant -2 : i32
1065  %res = arith.sitofp %c0 : i32 to f32
1066  return %res : f32
1067}
1068
1069// CHECK-LABEL: @constant_SItoFP_splat(
1070func.func @constant_SItoFP_splat() -> vector<4xf32> {
1071  // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>
1072  // CHECK: return %[[C0]]
1073  %c0 = arith.constant 2 : i32
1074  %splat = vector.splat %c0 : vector<4xi32>
1075  %res = arith.sitofp %splat : vector<4xi32> to vector<4xf32>
1076  return %res : vector<4xf32>
1077}
1078
1079// CHECK-LABEL: @constant_SItoFP_vector(
1080func.func @constant_SItoFP_vector() -> vector<4xf32> {
1081  // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>
1082  // CHECK: return %[[C0]]
1083  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
1084  %res = arith.sitofp %vector : vector<4xi32> to vector<4xf32>
1085  return %res : vector<4xf32>
1086}
1087
1088// -----
1089// CHECK-LABEL: @constant_UItoFP(
1090func.func @constant_UItoFP() -> f32 {
1091  // CHECK: %[[C0:.+]] = arith.constant 2.000000e+00 : f32
1092  // CHECK: return %[[C0]]
1093  %c0 = arith.constant 2 : i32
1094  %res = arith.uitofp %c0 : i32 to f32
1095  return %res : f32
1096}
1097
1098// CHECK-LABEL: @constant_UItoFP_splat(
1099func.func @constant_UItoFP_splat() -> vector<4xf32> {
1100  // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>
1101  // CHECK: return %[[C0]]
1102  %c0 = arith.constant 2 : i32
1103  %splat = vector.splat %c0 : vector<4xi32>
1104  %res = arith.uitofp %splat : vector<4xi32> to vector<4xf32>
1105  return %res : vector<4xf32>
1106}
1107
1108// CHECK-LABEL: @constant_UItoFP_vector(
1109func.func @constant_UItoFP_vector() -> vector<4xf32> {
1110  // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>
1111  // CHECK: return %[[C0]]
1112  %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
1113  %res = arith.uitofp %vector : vector<4xi32> to vector<4xf32>
1114  return %res : vector<4xf32>
1115}
1116
1117// -----
1118
1119// Tests rewritten from https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/InstCombine/2008-11-08-FCmp.ll
1120// When inst combining an FCMP with the LHS coming from a arith.uitofp instruction, we
1121// can lower it to signed ICMP instructions.
1122
1123// CHECK-LABEL: @test1(
1124// CHECK-SAME: %[[arg0:.+]]:
1125func.func @test1(%arg0: i32) -> i1 {
1126  %cst = arith.constant 0.000000e+00 : f64
1127  %1 = arith.uitofp %arg0: i32 to f64
1128  %2 = arith.cmpf ole, %1, %cst : f64
1129  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
1130  // CHECK: arith.cmpi ule, %[[arg0]], %[[c0]] : i32
1131  return %2 : i1
1132}
1133
1134// CHECK-LABEL: @test2(
1135// CHECK-SAME: %[[arg0:.+]]:
1136func.func @test2(%arg0: i32) -> i1 {
1137  %cst = arith.constant 0.000000e+00 : f64
1138  %1 = arith.uitofp %arg0: i32 to f64
1139  %2 = arith.cmpf olt, %1, %cst : f64
1140  return %2 : i1
1141  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
1142  // CHECK: arith.cmpi ult, %[[arg0]], %[[c0]] : i32
1143}
1144
1145// CHECK-LABEL: @test3(
1146// CHECK-SAME: %[[arg0:.+]]:
1147func.func @test3(%arg0: i32) -> i1 {
1148  %cst = arith.constant 0.000000e+00 : f64
1149  %1 = arith.uitofp %arg0: i32 to f64
1150  %2 = arith.cmpf oge, %1, %cst : f64
1151  return %2 : i1
1152  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
1153  // CHECK: arith.cmpi uge, %[[arg0]], %[[c0]] : i32
1154}
1155
1156// CHECK-LABEL: @test4(
1157// CHECK-SAME: %[[arg0:.+]]:
1158func.func @test4(%arg0: i32) -> i1 {
1159  %cst = arith.constant 0.000000e+00 : f64
1160  %1 = arith.uitofp %arg0: i32 to f64
1161  %2 = arith.cmpf ogt, %1, %cst : f64
1162  // CHECK: %[[c0:.+]] = arith.constant 0 : i32
1163  // CHECK: arith.cmpi ugt, %[[arg0]], %[[c0]] : i32
1164  return %2 : i1
1165}
1166
1167// CHECK-LABEL: @test5(
1168func.func @test5(%arg0: i32) -> i1 {
1169  %cst = arith.constant -4.400000e+00 : f64
1170  %1 = arith.uitofp %arg0: i32 to f64
1171  %2 = arith.cmpf ogt, %1, %cst : f64
1172  return %2 : i1
1173  // CHECK: %[[true:.+]] = arith.constant true
1174  // CHECK: return %[[true]] : i1
1175}
1176
1177// CHECK-LABEL: @test6(
1178func.func @test6(%arg0: i32) -> i1 {
1179  %cst = arith.constant -4.400000e+00 : f64
1180  %1 = arith.uitofp %arg0: i32 to f64
1181  %2 = arith.cmpf olt, %1, %cst : f64
1182  return %2 : i1
1183  // CHECK: %[[false:.+]] = arith.constant false
1184  // CHECK: return %[[false]] : i1
1185}
1186
1187// Check that optimizing unsigned >= comparisons correctly distinguishes
1188// positive and negative constants.
1189// CHECK-LABEL: @test7(
1190// CHECK-SAME: %[[arg0:.+]]:
1191func.func @test7(%arg0: i32) -> i1 {
1192  %cst = arith.constant 3.200000e+00 : f64
1193  %1 = arith.uitofp %arg0: i32 to f64
1194  %2 = arith.cmpf oge, %1, %cst : f64
1195  return %2 : i1
1196  // CHECK: %[[c3:.+]] = arith.constant 3 : i32
1197  // CHECK: arith.cmpi ugt, %[[arg0]], %[[c3]] : i32
1198}
1199
1200// -----
1201
1202// CHECK-LABEL: @foldShl(
1203// CHECK: %[[res:.+]] = arith.constant 4294967296 : i64
1204// CHECK: return %[[res]]
1205func.func @foldShl() -> i64 {
1206  %c1 = arith.constant 1 : i64
1207  %c32 = arith.constant 32 : i64
1208  %r = arith.shli %c1, %c32 : i64
1209  return %r : i64
1210}
1211
1212// CHECK-LABEL: @nofoldShl(
1213// CHECK: %[[res:.+]] = arith.shli
1214// CHECK: return %[[res]]
1215func.func @nofoldShl() -> i64 {
1216  %c1 = arith.constant 1 : i64
1217  %c132 = arith.constant 132 : i64
1218  %r = arith.shli %c1, %c132 : i64
1219  return %r : i64
1220}
1221
1222// CHECK-LABEL: @nofoldShl2(
1223// CHECK: %[[res:.+]] = arith.shli
1224// CHECK: return %[[res]]
1225func.func @nofoldShl2() -> i64 {
1226  %c1 = arith.constant 1 : i64
1227  %cm32 = arith.constant -32 : i64
1228  %r = arith.shli %c1, %cm32 : i64
1229  return %r : i64
1230}
1231
1232// CHECK-LABEL: @foldShru(
1233// CHECK: %[[res:.+]] = arith.constant 2 : i64
1234// CHECK: return %[[res]]
1235func.func @foldShru() -> i64 {
1236  %c1 = arith.constant 8 : i64
1237  %c32 = arith.constant 2 : i64
1238  %r = arith.shrui %c1, %c32 : i64
1239  return %r : i64
1240}
1241
1242// CHECK-LABEL: @foldShru2(
1243// CHECK: %[[res:.+]] = arith.constant 9223372036854775807 : i64
1244// CHECK: return %[[res]]
1245func.func @foldShru2() -> i64 {
1246  %c1 = arith.constant -2 : i64
1247  %c32 = arith.constant 1 : i64
1248  %r = arith.shrui %c1, %c32 : i64
1249  return %r : i64
1250}
1251
1252// CHECK-LABEL: @nofoldShru(
1253// CHECK: %[[res:.+]] = arith.shrui
1254// CHECK: return %[[res]]
1255func.func @nofoldShru() -> i64 {
1256  %c1 = arith.constant 8 : i64
1257  %c132 = arith.constant 132 : i64
1258  %r = arith.shrui %c1, %c132 : i64
1259  return %r : i64
1260}
1261
1262// CHECK-LABEL: @nofoldShru2(
1263// CHECK: %[[res:.+]] = arith.shrui
1264// CHECK: return %[[res]]
1265func.func @nofoldShru2() -> i64 {
1266  %c1 = arith.constant 8 : i64
1267  %cm32 = arith.constant -32 : i64
1268  %r = arith.shrui %c1, %cm32 : i64
1269  return %r : i64
1270}
1271
1272// CHECK-LABEL: @foldShrs(
1273// CHECK: %[[res:.+]] = arith.constant 2 : i64
1274// CHECK: return %[[res]]
1275func.func @foldShrs() -> i64 {
1276  %c1 = arith.constant 8 : i64
1277  %c32 = arith.constant 2 : i64
1278  %r = arith.shrsi %c1, %c32 : i64
1279  return %r : i64
1280}
1281
1282// CHECK-LABEL: @foldShrs2(
1283// CHECK: %[[res:.+]] = arith.constant -1 : i64
1284// CHECK: return %[[res]]
1285func.func @foldShrs2() -> i64 {
1286  %c1 = arith.constant -2 : i64
1287  %c32 = arith.constant 1 : i64
1288  %r = arith.shrsi %c1, %c32 : i64
1289  return %r : i64
1290}
1291
1292// CHECK-LABEL: @nofoldShrs(
1293// CHECK: %[[res:.+]] = arith.shrsi
1294// CHECK: return %[[res]]
1295func.func @nofoldShrs() -> i64 {
1296  %c1 = arith.constant 8 : i64
1297  %c132 = arith.constant 132 : i64
1298  %r = arith.shrsi %c1, %c132 : i64
1299  return %r : i64
1300}
1301
1302// CHECK-LABEL: @nofoldShrs2(
1303// CHECK: %[[res:.+]] = arith.shrsi
1304// CHECK: return %[[res]]
1305func.func @nofoldShrs2() -> i64 {
1306  %c1 = arith.constant 8 : i64
1307  %cm32 = arith.constant -32 : i64
1308  %r = arith.shrsi %c1, %cm32 : i64
1309  return %r : i64
1310}
1311
1312// -----
1313
1314// CHECK-LABEL: @test_negf(
1315// CHECK: %[[res:.+]] = arith.constant -2.0
1316// CHECK: return %[[res]]
1317func.func @test_negf() -> (f32) {
1318  %c = arith.constant 2.0 : f32
1319  %0 = arith.negf %c : f32
1320  return %0: f32
1321}
1322
1323// -----
1324
1325// CHECK-LABEL: @test_remui(
1326// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>
1327// CHECK: return %[[res]]
1328func.func @test_remui() -> (vector<4xi32>) {
1329  %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>
1330  %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
1331  %0 = arith.remui %v1, %v2 : vector<4xi32>
1332  return %0 : vector<4xi32>
1333}
1334
1335// // -----
1336
1337// CHECK-LABEL: @test_remui_1(
1338// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>
1339// CHECK: return %[[res]]
1340func.func @test_remui_1(%arg : vector<4xi32>) -> (vector<4xi32>) {
1341  %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>
1342  %0 = arith.remui %arg, %v : vector<4xi32>
1343  return %0 : vector<4xi32>
1344}
1345
1346// -----
1347
1348// CHECK-LABEL: @test_remsi(
1349// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>
1350// CHECK: return %[[res]]
1351func.func @test_remsi() -> (vector<4xi32>) {
1352  %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>
1353  %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>
1354  %0 = arith.remsi %v1, %v2 : vector<4xi32>
1355  return %0 : vector<4xi32>
1356}
1357
1358// // -----
1359
1360// CHECK-LABEL: @test_remsi_1(
1361// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>
1362// CHECK: return %[[res]]
1363func.func @test_remsi_1(%arg : vector<4xi32>) -> (vector<4xi32>) {
1364  %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>
1365  %0 = arith.remsi %arg, %v : vector<4xi32>
1366  return %0 : vector<4xi32>
1367}
1368