xref: /llvm-project/llvm/test/CodeGen/AArch64/fpclamptosat.ll (revision bc7f11ccb01cbc2ae6c1631535ea5c181f70cb1e)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-CVT
3; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FP16
4
5; i32 saturate
6
7define i32 @stest_f64i32(double %x) {
8; CHECK-LABEL: stest_f64i32:
9; CHECK:       // %bb.0: // %entry
10; CHECK-NEXT:    fcvtzs w0, d0
11; CHECK-NEXT:    ret
12entry:
13  %conv = fptosi double %x to i64
14  %0 = icmp slt i64 %conv, 2147483647
15  %spec.store.select = select i1 %0, i64 %conv, i64 2147483647
16  %1 = icmp sgt i64 %spec.store.select, -2147483648
17  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
18  %conv6 = trunc i64 %spec.store.select7 to i32
19  ret i32 %conv6
20}
21
22define i32 @utest_f64i32(double %x) {
23; CHECK-LABEL: utest_f64i32:
24; CHECK:       // %bb.0: // %entry
25; CHECK-NEXT:    fcvtzu w0, d0
26; CHECK-NEXT:    ret
27entry:
28  %conv = fptoui double %x to i64
29  %0 = icmp ult i64 %conv, 4294967295
30  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
31  %conv6 = trunc i64 %spec.store.select to i32
32  ret i32 %conv6
33}
34
35define i32 @ustest_f64i32(double %x) {
36; CHECK-LABEL: ustest_f64i32:
37; CHECK:       // %bb.0: // %entry
38; CHECK-NEXT:    fcvtzu w0, d0
39; CHECK-NEXT:    ret
40entry:
41  %conv = fptosi double %x to i64
42  %0 = icmp slt i64 %conv, 4294967295
43  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
44  %1 = icmp sgt i64 %spec.store.select, 0
45  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
46  %conv6 = trunc i64 %spec.store.select7 to i32
47  ret i32 %conv6
48}
49
50define i32 @stest_f32i32(float %x) {
51; CHECK-LABEL: stest_f32i32:
52; CHECK:       // %bb.0: // %entry
53; CHECK-NEXT:    fcvtzs w0, s0
54; CHECK-NEXT:    ret
55entry:
56  %conv = fptosi float %x to i64
57  %0 = icmp slt i64 %conv, 2147483647
58  %spec.store.select = select i1 %0, i64 %conv, i64 2147483647
59  %1 = icmp sgt i64 %spec.store.select, -2147483648
60  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
61  %conv6 = trunc i64 %spec.store.select7 to i32
62  ret i32 %conv6
63}
64
65define i32 @utest_f32i32(float %x) {
66; CHECK-LABEL: utest_f32i32:
67; CHECK:       // %bb.0: // %entry
68; CHECK-NEXT:    fcvtzu w0, s0
69; CHECK-NEXT:    ret
70entry:
71  %conv = fptoui float %x to i64
72  %0 = icmp ult i64 %conv, 4294967295
73  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
74  %conv6 = trunc i64 %spec.store.select to i32
75  ret i32 %conv6
76}
77
78define i32 @ustest_f32i32(float %x) {
79; CHECK-LABEL: ustest_f32i32:
80; CHECK:       // %bb.0: // %entry
81; CHECK-NEXT:    fcvtzu w0, s0
82; CHECK-NEXT:    ret
83entry:
84  %conv = fptosi float %x to i64
85  %0 = icmp slt i64 %conv, 4294967295
86  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
87  %1 = icmp sgt i64 %spec.store.select, 0
88  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
89  %conv6 = trunc i64 %spec.store.select7 to i32
90  ret i32 %conv6
91}
92
93define i32 @stest_f16i32(half %x) {
94; CHECK-CVT-LABEL: stest_f16i32:
95; CHECK-CVT:       // %bb.0: // %entry
96; CHECK-CVT-NEXT:    fcvt s0, h0
97; CHECK-CVT-NEXT:    fcvtzs w0, s0
98; CHECK-CVT-NEXT:    ret
99;
100; CHECK-FP16-LABEL: stest_f16i32:
101; CHECK-FP16:       // %bb.0: // %entry
102; CHECK-FP16-NEXT:    fcvtzs w0, h0
103; CHECK-FP16-NEXT:    ret
104entry:
105  %conv = fptosi half %x to i64
106  %0 = icmp slt i64 %conv, 2147483647
107  %spec.store.select = select i1 %0, i64 %conv, i64 2147483647
108  %1 = icmp sgt i64 %spec.store.select, -2147483648
109  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648
110  %conv6 = trunc i64 %spec.store.select7 to i32
111  ret i32 %conv6
112}
113
114define i32 @utesth_f16i32(half %x) {
115; CHECK-CVT-LABEL: utesth_f16i32:
116; CHECK-CVT:       // %bb.0: // %entry
117; CHECK-CVT-NEXT:    fcvt s0, h0
118; CHECK-CVT-NEXT:    fcvtzu w0, s0
119; CHECK-CVT-NEXT:    ret
120;
121; CHECK-FP16-LABEL: utesth_f16i32:
122; CHECK-FP16:       // %bb.0: // %entry
123; CHECK-FP16-NEXT:    fcvtzu w0, h0
124; CHECK-FP16-NEXT:    ret
125entry:
126  %conv = fptoui half %x to i64
127  %0 = icmp ult i64 %conv, 4294967295
128  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
129  %conv6 = trunc i64 %spec.store.select to i32
130  ret i32 %conv6
131}
132
133define i32 @ustest_f16i32(half %x) {
134; CHECK-CVT-LABEL: ustest_f16i32:
135; CHECK-CVT:       // %bb.0: // %entry
136; CHECK-CVT-NEXT:    fcvt s0, h0
137; CHECK-CVT-NEXT:    fcvtzu w0, s0
138; CHECK-CVT-NEXT:    ret
139;
140; CHECK-FP16-LABEL: ustest_f16i32:
141; CHECK-FP16:       // %bb.0: // %entry
142; CHECK-FP16-NEXT:    fcvtzu w0, h0
143; CHECK-FP16-NEXT:    ret
144entry:
145  %conv = fptosi half %x to i64
146  %0 = icmp slt i64 %conv, 4294967295
147  %spec.store.select = select i1 %0, i64 %conv, i64 4294967295
148  %1 = icmp sgt i64 %spec.store.select, 0
149  %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0
150  %conv6 = trunc i64 %spec.store.select7 to i32
151  ret i32 %conv6
152}
153
154; i16 saturate
155
156define i16 @stest_f64i16(double %x) {
157; CHECK-LABEL: stest_f64i16:
158; CHECK:       // %bb.0: // %entry
159; CHECK-NEXT:    fcvtzs w8, d0
160; CHECK-NEXT:    mov w9, #32767 // =0x7fff
161; CHECK-NEXT:    cmp w8, w9
162; CHECK-NEXT:    csel w8, w8, w9, lt
163; CHECK-NEXT:    mov w9, #-32768 // =0xffff8000
164; CHECK-NEXT:    cmn w8, #8, lsl #12 // =32768
165; CHECK-NEXT:    csel w0, w8, w9, gt
166; CHECK-NEXT:    ret
167entry:
168  %conv = fptosi double %x to i32
169  %0 = icmp slt i32 %conv, 32767
170  %spec.store.select = select i1 %0, i32 %conv, i32 32767
171  %1 = icmp sgt i32 %spec.store.select, -32768
172  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
173  %conv6 = trunc i32 %spec.store.select7 to i16
174  ret i16 %conv6
175}
176
177define i16 @utest_f64i16(double %x) {
178; CHECK-LABEL: utest_f64i16:
179; CHECK:       // %bb.0: // %entry
180; CHECK-NEXT:    fcvtzu w8, d0
181; CHECK-NEXT:    mov w9, #65535 // =0xffff
182; CHECK-NEXT:    cmp w8, w9
183; CHECK-NEXT:    csel w0, w8, w9, lo
184; CHECK-NEXT:    ret
185entry:
186  %conv = fptoui double %x to i32
187  %0 = icmp ult i32 %conv, 65535
188  %spec.store.select = select i1 %0, i32 %conv, i32 65535
189  %conv6 = trunc i32 %spec.store.select to i16
190  ret i16 %conv6
191}
192
193define i16 @ustest_f64i16(double %x) {
194; CHECK-LABEL: ustest_f64i16:
195; CHECK:       // %bb.0: // %entry
196; CHECK-NEXT:    fcvtzs w8, d0
197; CHECK-NEXT:    mov w9, #65535 // =0xffff
198; CHECK-NEXT:    cmp w8, w9
199; CHECK-NEXT:    csel w8, w8, w9, lt
200; CHECK-NEXT:    bic w0, w8, w8, asr #31
201; CHECK-NEXT:    ret
202entry:
203  %conv = fptosi double %x to i32
204  %0 = icmp slt i32 %conv, 65535
205  %spec.store.select = select i1 %0, i32 %conv, i32 65535
206  %1 = icmp sgt i32 %spec.store.select, 0
207  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
208  %conv6 = trunc i32 %spec.store.select7 to i16
209  ret i16 %conv6
210}
211
212define i16 @stest_f32i16(float %x) {
213; CHECK-LABEL: stest_f32i16:
214; CHECK:       // %bb.0: // %entry
215; CHECK-NEXT:    fcvtzs w8, s0
216; CHECK-NEXT:    mov w9, #32767 // =0x7fff
217; CHECK-NEXT:    cmp w8, w9
218; CHECK-NEXT:    csel w8, w8, w9, lt
219; CHECK-NEXT:    mov w9, #-32768 // =0xffff8000
220; CHECK-NEXT:    cmn w8, #8, lsl #12 // =32768
221; CHECK-NEXT:    csel w0, w8, w9, gt
222; CHECK-NEXT:    ret
223entry:
224  %conv = fptosi float %x to i32
225  %0 = icmp slt i32 %conv, 32767
226  %spec.store.select = select i1 %0, i32 %conv, i32 32767
227  %1 = icmp sgt i32 %spec.store.select, -32768
228  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
229  %conv6 = trunc i32 %spec.store.select7 to i16
230  ret i16 %conv6
231}
232
233define i16 @utest_f32i16(float %x) {
234; CHECK-LABEL: utest_f32i16:
235; CHECK:       // %bb.0: // %entry
236; CHECK-NEXT:    fcvtzu w8, s0
237; CHECK-NEXT:    mov w9, #65535 // =0xffff
238; CHECK-NEXT:    cmp w8, w9
239; CHECK-NEXT:    csel w0, w8, w9, lo
240; CHECK-NEXT:    ret
241entry:
242  %conv = fptoui float %x to i32
243  %0 = icmp ult i32 %conv, 65535
244  %spec.store.select = select i1 %0, i32 %conv, i32 65535
245  %conv6 = trunc i32 %spec.store.select to i16
246  ret i16 %conv6
247}
248
249define i16 @ustest_f32i16(float %x) {
250; CHECK-LABEL: ustest_f32i16:
251; CHECK:       // %bb.0: // %entry
252; CHECK-NEXT:    fcvtzs w8, s0
253; CHECK-NEXT:    mov w9, #65535 // =0xffff
254; CHECK-NEXT:    cmp w8, w9
255; CHECK-NEXT:    csel w8, w8, w9, lt
256; CHECK-NEXT:    bic w0, w8, w8, asr #31
257; CHECK-NEXT:    ret
258entry:
259  %conv = fptosi float %x to i32
260  %0 = icmp slt i32 %conv, 65535
261  %spec.store.select = select i1 %0, i32 %conv, i32 65535
262  %1 = icmp sgt i32 %spec.store.select, 0
263  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
264  %conv6 = trunc i32 %spec.store.select7 to i16
265  ret i16 %conv6
266}
267
268define i16 @stest_f16i16(half %x) {
269; CHECK-CVT-LABEL: stest_f16i16:
270; CHECK-CVT:       // %bb.0: // %entry
271; CHECK-CVT-NEXT:    fcvt s0, h0
272; CHECK-CVT-NEXT:    mov w9, #32767 // =0x7fff
273; CHECK-CVT-NEXT:    fcvtzs w8, s0
274; CHECK-CVT-NEXT:    cmp w8, w9
275; CHECK-CVT-NEXT:    csel w8, w8, w9, lt
276; CHECK-CVT-NEXT:    mov w9, #-32768 // =0xffff8000
277; CHECK-CVT-NEXT:    cmn w8, #8, lsl #12 // =32768
278; CHECK-CVT-NEXT:    csel w0, w8, w9, gt
279; CHECK-CVT-NEXT:    ret
280;
281; CHECK-FP16-LABEL: stest_f16i16:
282; CHECK-FP16:       // %bb.0: // %entry
283; CHECK-FP16-NEXT:    fcvtzs w8, h0
284; CHECK-FP16-NEXT:    mov w9, #32767 // =0x7fff
285; CHECK-FP16-NEXT:    cmp w8, w9
286; CHECK-FP16-NEXT:    csel w8, w8, w9, lt
287; CHECK-FP16-NEXT:    mov w9, #-32768 // =0xffff8000
288; CHECK-FP16-NEXT:    cmn w8, #8, lsl #12 // =32768
289; CHECK-FP16-NEXT:    csel w0, w8, w9, gt
290; CHECK-FP16-NEXT:    ret
291entry:
292  %conv = fptosi half %x to i32
293  %0 = icmp slt i32 %conv, 32767
294  %spec.store.select = select i1 %0, i32 %conv, i32 32767
295  %1 = icmp sgt i32 %spec.store.select, -32768
296  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768
297  %conv6 = trunc i32 %spec.store.select7 to i16
298  ret i16 %conv6
299}
300
301define i16 @utesth_f16i16(half %x) {
302; CHECK-CVT-LABEL: utesth_f16i16:
303; CHECK-CVT:       // %bb.0: // %entry
304; CHECK-CVT-NEXT:    fcvt s0, h0
305; CHECK-CVT-NEXT:    mov w9, #65535 // =0xffff
306; CHECK-CVT-NEXT:    fcvtzu w8, s0
307; CHECK-CVT-NEXT:    cmp w8, w9
308; CHECK-CVT-NEXT:    csel w0, w8, w9, lo
309; CHECK-CVT-NEXT:    ret
310;
311; CHECK-FP16-LABEL: utesth_f16i16:
312; CHECK-FP16:       // %bb.0: // %entry
313; CHECK-FP16-NEXT:    fcvtzu w8, h0
314; CHECK-FP16-NEXT:    mov w9, #65535 // =0xffff
315; CHECK-FP16-NEXT:    cmp w8, w9
316; CHECK-FP16-NEXT:    csel w0, w8, w9, lo
317; CHECK-FP16-NEXT:    ret
318entry:
319  %conv = fptoui half %x to i32
320  %0 = icmp ult i32 %conv, 65535
321  %spec.store.select = select i1 %0, i32 %conv, i32 65535
322  %conv6 = trunc i32 %spec.store.select to i16
323  ret i16 %conv6
324}
325
326define i16 @ustest_f16i16(half %x) {
327; CHECK-CVT-LABEL: ustest_f16i16:
328; CHECK-CVT:       // %bb.0: // %entry
329; CHECK-CVT-NEXT:    fcvt s0, h0
330; CHECK-CVT-NEXT:    mov w9, #65535 // =0xffff
331; CHECK-CVT-NEXT:    fcvtzs w8, s0
332; CHECK-CVT-NEXT:    cmp w8, w9
333; CHECK-CVT-NEXT:    csel w8, w8, w9, lt
334; CHECK-CVT-NEXT:    bic w0, w8, w8, asr #31
335; CHECK-CVT-NEXT:    ret
336;
337; CHECK-FP16-LABEL: ustest_f16i16:
338; CHECK-FP16:       // %bb.0: // %entry
339; CHECK-FP16-NEXT:    fcvtzs w8, h0
340; CHECK-FP16-NEXT:    mov w9, #65535 // =0xffff
341; CHECK-FP16-NEXT:    cmp w8, w9
342; CHECK-FP16-NEXT:    csel w8, w8, w9, lt
343; CHECK-FP16-NEXT:    bic w0, w8, w8, asr #31
344; CHECK-FP16-NEXT:    ret
345entry:
346  %conv = fptosi half %x to i32
347  %0 = icmp slt i32 %conv, 65535
348  %spec.store.select = select i1 %0, i32 %conv, i32 65535
349  %1 = icmp sgt i32 %spec.store.select, 0
350  %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0
351  %conv6 = trunc i32 %spec.store.select7 to i16
352  ret i16 %conv6
353}
354
355; i64 saturate
356
357define i64 @stest_f64i64(double %x) {
358; CHECK-LABEL: stest_f64i64:
359; CHECK:       // %bb.0: // %entry
360; CHECK-NEXT:    fcvtzs x0, d0
361; CHECK-NEXT:    ret
362entry:
363  %conv = fptosi double %x to i128
364  %0 = icmp slt i128 %conv, 9223372036854775807
365  %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
366  %1 = icmp sgt i128 %spec.store.select, -9223372036854775808
367  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
368  %conv6 = trunc i128 %spec.store.select7 to i64
369  ret i64 %conv6
370}
371
372define i64 @utest_f64i64(double %x) {
373; CHECK-LABEL: utest_f64i64:
374; CHECK:       // %bb.0: // %entry
375; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
376; CHECK-NEXT:    .cfi_def_cfa_offset 16
377; CHECK-NEXT:    .cfi_offset w30, -16
378; CHECK-NEXT:    bl __fixunsdfti
379; CHECK-NEXT:    cmp x1, #0
380; CHECK-NEXT:    csel x0, x0, xzr, eq
381; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
382; CHECK-NEXT:    ret
383entry:
384  %conv = fptoui double %x to i128
385  %0 = icmp ult i128 %conv, 18446744073709551616
386  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
387  %conv6 = trunc i128 %spec.store.select to i64
388  ret i64 %conv6
389}
390
391define i64 @ustest_f64i64(double %x) {
392; CHECK-LABEL: ustest_f64i64:
393; CHECK:       // %bb.0: // %entry
394; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
395; CHECK-NEXT:    .cfi_def_cfa_offset 16
396; CHECK-NEXT:    .cfi_offset w30, -16
397; CHECK-NEXT:    bl __fixdfti
398; CHECK-NEXT:    cmp x1, #1
399; CHECK-NEXT:    csel x8, x0, xzr, lt
400; CHECK-NEXT:    csinc x9, x1, xzr, lt
401; CHECK-NEXT:    cmp xzr, x8
402; CHECK-NEXT:    ngcs xzr, x9
403; CHECK-NEXT:    csel x0, x8, xzr, lt
404; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
405; CHECK-NEXT:    ret
406entry:
407  %conv = fptosi double %x to i128
408  %0 = icmp slt i128 %conv, 18446744073709551616
409  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
410  %1 = icmp sgt i128 %spec.store.select, 0
411  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
412  %conv6 = trunc i128 %spec.store.select7 to i64
413  ret i64 %conv6
414}
415
416define i64 @stest_f32i64(float %x) {
417; CHECK-LABEL: stest_f32i64:
418; CHECK:       // %bb.0: // %entry
419; CHECK-NEXT:    fcvtzs x0, s0
420; CHECK-NEXT:    ret
421entry:
422  %conv = fptosi float %x to i128
423  %0 = icmp slt i128 %conv, 9223372036854775807
424  %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
425  %1 = icmp sgt i128 %spec.store.select, -9223372036854775808
426  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
427  %conv6 = trunc i128 %spec.store.select7 to i64
428  ret i64 %conv6
429}
430
431define i64 @utest_f32i64(float %x) {
432; CHECK-LABEL: utest_f32i64:
433; CHECK:       // %bb.0: // %entry
434; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
435; CHECK-NEXT:    .cfi_def_cfa_offset 16
436; CHECK-NEXT:    .cfi_offset w30, -16
437; CHECK-NEXT:    bl __fixunssfti
438; CHECK-NEXT:    cmp x1, #0
439; CHECK-NEXT:    csel x0, x0, xzr, eq
440; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
441; CHECK-NEXT:    ret
442entry:
443  %conv = fptoui float %x to i128
444  %0 = icmp ult i128 %conv, 18446744073709551616
445  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
446  %conv6 = trunc i128 %spec.store.select to i64
447  ret i64 %conv6
448}
449
450define i64 @ustest_f32i64(float %x) {
451; CHECK-LABEL: ustest_f32i64:
452; CHECK:       // %bb.0: // %entry
453; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
454; CHECK-NEXT:    .cfi_def_cfa_offset 16
455; CHECK-NEXT:    .cfi_offset w30, -16
456; CHECK-NEXT:    bl __fixsfti
457; CHECK-NEXT:    cmp x1, #1
458; CHECK-NEXT:    csel x8, x0, xzr, lt
459; CHECK-NEXT:    csinc x9, x1, xzr, lt
460; CHECK-NEXT:    cmp xzr, x8
461; CHECK-NEXT:    ngcs xzr, x9
462; CHECK-NEXT:    csel x0, x8, xzr, lt
463; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
464; CHECK-NEXT:    ret
465entry:
466  %conv = fptosi float %x to i128
467  %0 = icmp slt i128 %conv, 18446744073709551616
468  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
469  %1 = icmp sgt i128 %spec.store.select, 0
470  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
471  %conv6 = trunc i128 %spec.store.select7 to i64
472  ret i64 %conv6
473}
474
475define i64 @stest_f16i64(half %x) {
476; CHECK-CVT-LABEL: stest_f16i64:
477; CHECK-CVT:       // %bb.0: // %entry
478; CHECK-CVT-NEXT:    fcvt s0, h0
479; CHECK-CVT-NEXT:    fcvtzs x0, s0
480; CHECK-CVT-NEXT:    ret
481;
482; CHECK-FP16-LABEL: stest_f16i64:
483; CHECK-FP16:       // %bb.0: // %entry
484; CHECK-FP16-NEXT:    fcvtzs x0, h0
485; CHECK-FP16-NEXT:    ret
486entry:
487  %conv = fptosi half %x to i128
488  %0 = icmp slt i128 %conv, 9223372036854775807
489  %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807
490  %1 = icmp sgt i128 %spec.store.select, -9223372036854775808
491  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808
492  %conv6 = trunc i128 %spec.store.select7 to i64
493  ret i64 %conv6
494}
495
496define i64 @utesth_f16i64(half %x) {
497; CHECK-LABEL: utesth_f16i64:
498; CHECK:       // %bb.0: // %entry
499; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
500; CHECK-NEXT:    .cfi_def_cfa_offset 16
501; CHECK-NEXT:    .cfi_offset w30, -16
502; CHECK-NEXT:    bl __fixunshfti
503; CHECK-NEXT:    cmp x1, #0
504; CHECK-NEXT:    csel x0, x0, xzr, eq
505; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
506; CHECK-NEXT:    ret
507entry:
508  %conv = fptoui half %x to i128
509  %0 = icmp ult i128 %conv, 18446744073709551616
510  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
511  %conv6 = trunc i128 %spec.store.select to i64
512  ret i64 %conv6
513}
514
515define i64 @ustest_f16i64(half %x) {
516; CHECK-LABEL: ustest_f16i64:
517; CHECK:       // %bb.0: // %entry
518; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
519; CHECK-NEXT:    .cfi_def_cfa_offset 16
520; CHECK-NEXT:    .cfi_offset w30, -16
521; CHECK-NEXT:    bl __fixhfti
522; CHECK-NEXT:    cmp x1, #1
523; CHECK-NEXT:    csel x8, x0, xzr, lt
524; CHECK-NEXT:    csinc x9, x1, xzr, lt
525; CHECK-NEXT:    cmp xzr, x8
526; CHECK-NEXT:    ngcs xzr, x9
527; CHECK-NEXT:    csel x0, x8, xzr, lt
528; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
529; CHECK-NEXT:    ret
530entry:
531  %conv = fptosi half %x to i128
532  %0 = icmp slt i128 %conv, 18446744073709551616
533  %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616
534  %1 = icmp sgt i128 %spec.store.select, 0
535  %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0
536  %conv6 = trunc i128 %spec.store.select7 to i64
537  ret i64 %conv6
538}
539
540
541
542; i32 saturate
543
544define i32 @stest_f64i32_mm(double %x) {
545; CHECK-LABEL: stest_f64i32_mm:
546; CHECK:       // %bb.0: // %entry
547; CHECK-NEXT:    fcvtzs w0, d0
548; CHECK-NEXT:    ret
549entry:
550  %conv = fptosi double %x to i64
551  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
552  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
553  %conv6 = trunc i64 %spec.store.select7 to i32
554  ret i32 %conv6
555}
556
557define i32 @utest_f64i32_mm(double %x) {
558; CHECK-LABEL: utest_f64i32_mm:
559; CHECK:       // %bb.0: // %entry
560; CHECK-NEXT:    fcvtzu w0, d0
561; CHECK-NEXT:    ret
562entry:
563  %conv = fptoui double %x to i64
564  %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
565  %conv6 = trunc i64 %spec.store.select to i32
566  ret i32 %conv6
567}
568
569define i32 @ustest_f64i32_mm(double %x) {
570; CHECK-LABEL: ustest_f64i32_mm:
571; CHECK:       // %bb.0: // %entry
572; CHECK-NEXT:    fcvtzu w0, d0
573; CHECK-NEXT:    ret
574entry:
575  %conv = fptosi double %x to i64
576  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
577  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
578  %conv6 = trunc i64 %spec.store.select7 to i32
579  ret i32 %conv6
580}
581
582define i32 @stest_f32i32_mm(float %x) {
583; CHECK-LABEL: stest_f32i32_mm:
584; CHECK:       // %bb.0: // %entry
585; CHECK-NEXT:    fcvtzs w0, s0
586; CHECK-NEXT:    ret
587entry:
588  %conv = fptosi float %x to i64
589  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
590  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
591  %conv6 = trunc i64 %spec.store.select7 to i32
592  ret i32 %conv6
593}
594
595define i32 @utest_f32i32_mm(float %x) {
596; CHECK-LABEL: utest_f32i32_mm:
597; CHECK:       // %bb.0: // %entry
598; CHECK-NEXT:    fcvtzu w0, s0
599; CHECK-NEXT:    ret
600entry:
601  %conv = fptoui float %x to i64
602  %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
603  %conv6 = trunc i64 %spec.store.select to i32
604  ret i32 %conv6
605}
606
607define i32 @ustest_f32i32_mm(float %x) {
608; CHECK-LABEL: ustest_f32i32_mm:
609; CHECK:       // %bb.0: // %entry
610; CHECK-NEXT:    fcvtzu w0, s0
611; CHECK-NEXT:    ret
612entry:
613  %conv = fptosi float %x to i64
614  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
615  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
616  %conv6 = trunc i64 %spec.store.select7 to i32
617  ret i32 %conv6
618}
619
620define i32 @stest_f16i32_mm(half %x) {
621; CHECK-CVT-LABEL: stest_f16i32_mm:
622; CHECK-CVT:       // %bb.0: // %entry
623; CHECK-CVT-NEXT:    fcvt s0, h0
624; CHECK-CVT-NEXT:    fcvtzs w0, s0
625; CHECK-CVT-NEXT:    ret
626;
627; CHECK-FP16-LABEL: stest_f16i32_mm:
628; CHECK-FP16:       // %bb.0: // %entry
629; CHECK-FP16-NEXT:    fcvtzs w0, h0
630; CHECK-FP16-NEXT:    ret
631entry:
632  %conv = fptosi half %x to i64
633  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)
634  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648)
635  %conv6 = trunc i64 %spec.store.select7 to i32
636  ret i32 %conv6
637}
638
639define i32 @utesth_f16i32_mm(half %x) {
640; CHECK-CVT-LABEL: utesth_f16i32_mm:
641; CHECK-CVT:       // %bb.0: // %entry
642; CHECK-CVT-NEXT:    fcvt s0, h0
643; CHECK-CVT-NEXT:    fcvtzu w0, s0
644; CHECK-CVT-NEXT:    ret
645;
646; CHECK-FP16-LABEL: utesth_f16i32_mm:
647; CHECK-FP16:       // %bb.0: // %entry
648; CHECK-FP16-NEXT:    fcvtzu w0, h0
649; CHECK-FP16-NEXT:    ret
650entry:
651  %conv = fptoui half %x to i64
652  %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295)
653  %conv6 = trunc i64 %spec.store.select to i32
654  ret i32 %conv6
655}
656
657define i32 @ustest_f16i32_mm(half %x) {
658; CHECK-CVT-LABEL: ustest_f16i32_mm:
659; CHECK-CVT:       // %bb.0: // %entry
660; CHECK-CVT-NEXT:    fcvt s0, h0
661; CHECK-CVT-NEXT:    fcvtzu w0, s0
662; CHECK-CVT-NEXT:    ret
663;
664; CHECK-FP16-LABEL: ustest_f16i32_mm:
665; CHECK-FP16:       // %bb.0: // %entry
666; CHECK-FP16-NEXT:    fcvtzu w0, h0
667; CHECK-FP16-NEXT:    ret
668entry:
669  %conv = fptosi half %x to i64
670  %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295)
671  %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0)
672  %conv6 = trunc i64 %spec.store.select7 to i32
673  ret i32 %conv6
674}
675
676; i16 saturate
677
678define i16 @stest_f64i16_mm(double %x) {
679; CHECK-LABEL: stest_f64i16_mm:
680; CHECK:       // %bb.0: // %entry
681; CHECK-NEXT:    fcvtzs w8, d0
682; CHECK-NEXT:    mov w9, #32767 // =0x7fff
683; CHECK-NEXT:    cmp w8, w9
684; CHECK-NEXT:    csel w8, w8, w9, lt
685; CHECK-NEXT:    mov w9, #-32768 // =0xffff8000
686; CHECK-NEXT:    cmn w8, #8, lsl #12 // =32768
687; CHECK-NEXT:    csel w0, w8, w9, gt
688; CHECK-NEXT:    ret
689entry:
690  %conv = fptosi double %x to i32
691  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
692  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
693  %conv6 = trunc i32 %spec.store.select7 to i16
694  ret i16 %conv6
695}
696
697define i16 @utest_f64i16_mm(double %x) {
698; CHECK-LABEL: utest_f64i16_mm:
699; CHECK:       // %bb.0: // %entry
700; CHECK-NEXT:    fcvtzu w8, d0
701; CHECK-NEXT:    mov w9, #65535 // =0xffff
702; CHECK-NEXT:    cmp w8, w9
703; CHECK-NEXT:    csel w0, w8, w9, lo
704; CHECK-NEXT:    ret
705entry:
706  %conv = fptoui double %x to i32
707  %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
708  %conv6 = trunc i32 %spec.store.select to i16
709  ret i16 %conv6
710}
711
712define i16 @ustest_f64i16_mm(double %x) {
713; CHECK-LABEL: ustest_f64i16_mm:
714; CHECK:       // %bb.0: // %entry
715; CHECK-NEXT:    fcvtzs w8, d0
716; CHECK-NEXT:    mov w9, #65535 // =0xffff
717; CHECK-NEXT:    cmp w8, w9
718; CHECK-NEXT:    csel w8, w8, w9, lt
719; CHECK-NEXT:    bic w0, w8, w8, asr #31
720; CHECK-NEXT:    ret
721entry:
722  %conv = fptosi double %x to i32
723  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
724  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
725  %conv6 = trunc i32 %spec.store.select7 to i16
726  ret i16 %conv6
727}
728
729define i16 @stest_f32i16_mm(float %x) {
730; CHECK-LABEL: stest_f32i16_mm:
731; CHECK:       // %bb.0: // %entry
732; CHECK-NEXT:    fcvtzs w8, s0
733; CHECK-NEXT:    mov w9, #32767 // =0x7fff
734; CHECK-NEXT:    cmp w8, w9
735; CHECK-NEXT:    csel w8, w8, w9, lt
736; CHECK-NEXT:    mov w9, #-32768 // =0xffff8000
737; CHECK-NEXT:    cmn w8, #8, lsl #12 // =32768
738; CHECK-NEXT:    csel w0, w8, w9, gt
739; CHECK-NEXT:    ret
740entry:
741  %conv = fptosi float %x to i32
742  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
743  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
744  %conv6 = trunc i32 %spec.store.select7 to i16
745  ret i16 %conv6
746}
747
748define i16 @utest_f32i16_mm(float %x) {
749; CHECK-LABEL: utest_f32i16_mm:
750; CHECK:       // %bb.0: // %entry
751; CHECK-NEXT:    fcvtzu w8, s0
752; CHECK-NEXT:    mov w9, #65535 // =0xffff
753; CHECK-NEXT:    cmp w8, w9
754; CHECK-NEXT:    csel w0, w8, w9, lo
755; CHECK-NEXT:    ret
756entry:
757  %conv = fptoui float %x to i32
758  %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
759  %conv6 = trunc i32 %spec.store.select to i16
760  ret i16 %conv6
761}
762
763define i16 @ustest_f32i16_mm(float %x) {
764; CHECK-LABEL: ustest_f32i16_mm:
765; CHECK:       // %bb.0: // %entry
766; CHECK-NEXT:    fcvtzs w8, s0
767; CHECK-NEXT:    mov w9, #65535 // =0xffff
768; CHECK-NEXT:    cmp w8, w9
769; CHECK-NEXT:    csel w8, w8, w9, lt
770; CHECK-NEXT:    bic w0, w8, w8, asr #31
771; CHECK-NEXT:    ret
772entry:
773  %conv = fptosi float %x to i32
774  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
775  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
776  %conv6 = trunc i32 %spec.store.select7 to i16
777  ret i16 %conv6
778}
779
780define i16 @stest_f16i16_mm(half %x) {
781; CHECK-CVT-LABEL: stest_f16i16_mm:
782; CHECK-CVT:       // %bb.0: // %entry
783; CHECK-CVT-NEXT:    fcvt s0, h0
784; CHECK-CVT-NEXT:    mov w9, #32767 // =0x7fff
785; CHECK-CVT-NEXT:    fcvtzs w8, s0
786; CHECK-CVT-NEXT:    cmp w8, w9
787; CHECK-CVT-NEXT:    csel w8, w8, w9, lt
788; CHECK-CVT-NEXT:    mov w9, #-32768 // =0xffff8000
789; CHECK-CVT-NEXT:    cmn w8, #8, lsl #12 // =32768
790; CHECK-CVT-NEXT:    csel w0, w8, w9, gt
791; CHECK-CVT-NEXT:    ret
792;
793; CHECK-FP16-LABEL: stest_f16i16_mm:
794; CHECK-FP16:       // %bb.0: // %entry
795; CHECK-FP16-NEXT:    fcvtzs w8, h0
796; CHECK-FP16-NEXT:    mov w9, #32767 // =0x7fff
797; CHECK-FP16-NEXT:    cmp w8, w9
798; CHECK-FP16-NEXT:    csel w8, w8, w9, lt
799; CHECK-FP16-NEXT:    mov w9, #-32768 // =0xffff8000
800; CHECK-FP16-NEXT:    cmn w8, #8, lsl #12 // =32768
801; CHECK-FP16-NEXT:    csel w0, w8, w9, gt
802; CHECK-FP16-NEXT:    ret
803entry:
804  %conv = fptosi half %x to i32
805  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767)
806  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768)
807  %conv6 = trunc i32 %spec.store.select7 to i16
808  ret i16 %conv6
809}
810
811define i16 @utesth_f16i16_mm(half %x) {
812; CHECK-CVT-LABEL: utesth_f16i16_mm:
813; CHECK-CVT:       // %bb.0: // %entry
814; CHECK-CVT-NEXT:    fcvt s0, h0
815; CHECK-CVT-NEXT:    mov w9, #65535 // =0xffff
816; CHECK-CVT-NEXT:    fcvtzu w8, s0
817; CHECK-CVT-NEXT:    cmp w8, w9
818; CHECK-CVT-NEXT:    csel w0, w8, w9, lo
819; CHECK-CVT-NEXT:    ret
820;
821; CHECK-FP16-LABEL: utesth_f16i16_mm:
822; CHECK-FP16:       // %bb.0: // %entry
823; CHECK-FP16-NEXT:    fcvtzu w8, h0
824; CHECK-FP16-NEXT:    mov w9, #65535 // =0xffff
825; CHECK-FP16-NEXT:    cmp w8, w9
826; CHECK-FP16-NEXT:    csel w0, w8, w9, lo
827; CHECK-FP16-NEXT:    ret
828entry:
829  %conv = fptoui half %x to i32
830  %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535)
831  %conv6 = trunc i32 %spec.store.select to i16
832  ret i16 %conv6
833}
834
835define i16 @ustest_f16i16_mm(half %x) {
836; CHECK-CVT-LABEL: ustest_f16i16_mm:
837; CHECK-CVT:       // %bb.0: // %entry
838; CHECK-CVT-NEXT:    fcvt s0, h0
839; CHECK-CVT-NEXT:    mov w9, #65535 // =0xffff
840; CHECK-CVT-NEXT:    fcvtzs w8, s0
841; CHECK-CVT-NEXT:    cmp w8, w9
842; CHECK-CVT-NEXT:    csel w8, w8, w9, lt
843; CHECK-CVT-NEXT:    bic w0, w8, w8, asr #31
844; CHECK-CVT-NEXT:    ret
845;
846; CHECK-FP16-LABEL: ustest_f16i16_mm:
847; CHECK-FP16:       // %bb.0: // %entry
848; CHECK-FP16-NEXT:    fcvtzs w8, h0
849; CHECK-FP16-NEXT:    mov w9, #65535 // =0xffff
850; CHECK-FP16-NEXT:    cmp w8, w9
851; CHECK-FP16-NEXT:    csel w8, w8, w9, lt
852; CHECK-FP16-NEXT:    bic w0, w8, w8, asr #31
853; CHECK-FP16-NEXT:    ret
854entry:
855  %conv = fptosi half %x to i32
856  %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535)
857  %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0)
858  %conv6 = trunc i32 %spec.store.select7 to i16
859  ret i16 %conv6
860}
861
862; i64 saturate
863
864define i64 @stest_f64i64_mm(double %x) {
865; CHECK-LABEL: stest_f64i64_mm:
866; CHECK:       // %bb.0: // %entry
867; CHECK-NEXT:    fcvtzs x0, d0
868; CHECK-NEXT:    ret
869entry:
870  %conv = fptosi double %x to i128
871  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
872  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
873  %conv6 = trunc i128 %spec.store.select7 to i64
874  ret i64 %conv6
875}
876
877define i64 @utest_f64i64_mm(double %x) {
878; CHECK-LABEL: utest_f64i64_mm:
879; CHECK:       // %bb.0: // %entry
880; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
881; CHECK-NEXT:    .cfi_def_cfa_offset 16
882; CHECK-NEXT:    .cfi_offset w30, -16
883; CHECK-NEXT:    bl __fixunsdfti
884; CHECK-NEXT:    cmp x1, #0
885; CHECK-NEXT:    csel x0, x0, xzr, eq
886; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
887; CHECK-NEXT:    ret
888entry:
889  %conv = fptoui double %x to i128
890  %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
891  %conv6 = trunc i128 %spec.store.select to i64
892  ret i64 %conv6
893}
894
895define i64 @ustest_f64i64_mm(double %x) {
896; CHECK-LABEL: ustest_f64i64_mm:
897; CHECK:       // %bb.0: // %entry
898; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
899; CHECK-NEXT:    .cfi_def_cfa_offset 16
900; CHECK-NEXT:    .cfi_offset w30, -16
901; CHECK-NEXT:    bl __fixdfti
902; CHECK-NEXT:    cmp x1, #1
903; CHECK-NEXT:    csinc x8, x1, xzr, lt
904; CHECK-NEXT:    csel x9, x0, xzr, lt
905; CHECK-NEXT:    cmp x8, #0
906; CHECK-NEXT:    csel x0, xzr, x9, lt
907; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
908; CHECK-NEXT:    ret
909entry:
910  %conv = fptosi double %x to i128
911  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
912  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
913  %conv6 = trunc i128 %spec.store.select7 to i64
914  ret i64 %conv6
915}
916
917define i64 @stest_f32i64_mm(float %x) {
918; CHECK-LABEL: stest_f32i64_mm:
919; CHECK:       // %bb.0: // %entry
920; CHECK-NEXT:    fcvtzs x0, s0
921; CHECK-NEXT:    ret
922entry:
923  %conv = fptosi float %x to i128
924  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
925  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
926  %conv6 = trunc i128 %spec.store.select7 to i64
927  ret i64 %conv6
928}
929
930define i64 @utest_f32i64_mm(float %x) {
931; CHECK-LABEL: utest_f32i64_mm:
932; CHECK:       // %bb.0: // %entry
933; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
934; CHECK-NEXT:    .cfi_def_cfa_offset 16
935; CHECK-NEXT:    .cfi_offset w30, -16
936; CHECK-NEXT:    bl __fixunssfti
937; CHECK-NEXT:    cmp x1, #0
938; CHECK-NEXT:    csel x0, x0, xzr, eq
939; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
940; CHECK-NEXT:    ret
941entry:
942  %conv = fptoui float %x to i128
943  %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
944  %conv6 = trunc i128 %spec.store.select to i64
945  ret i64 %conv6
946}
947
948define i64 @ustest_f32i64_mm(float %x) {
949; CHECK-LABEL: ustest_f32i64_mm:
950; CHECK:       // %bb.0: // %entry
951; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
952; CHECK-NEXT:    .cfi_def_cfa_offset 16
953; CHECK-NEXT:    .cfi_offset w30, -16
954; CHECK-NEXT:    bl __fixsfti
955; CHECK-NEXT:    cmp x1, #1
956; CHECK-NEXT:    csinc x8, x1, xzr, lt
957; CHECK-NEXT:    csel x9, x0, xzr, lt
958; CHECK-NEXT:    cmp x8, #0
959; CHECK-NEXT:    csel x0, xzr, x9, lt
960; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
961; CHECK-NEXT:    ret
962entry:
963  %conv = fptosi float %x to i128
964  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
965  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
966  %conv6 = trunc i128 %spec.store.select7 to i64
967  ret i64 %conv6
968}
969
970define i64 @stest_f16i64_mm(half %x) {
971; CHECK-CVT-LABEL: stest_f16i64_mm:
972; CHECK-CVT:       // %bb.0: // %entry
973; CHECK-CVT-NEXT:    fcvt s0, h0
974; CHECK-CVT-NEXT:    fcvtzs x0, s0
975; CHECK-CVT-NEXT:    ret
976;
977; CHECK-FP16-LABEL: stest_f16i64_mm:
978; CHECK-FP16:       // %bb.0: // %entry
979; CHECK-FP16-NEXT:    fcvtzs x0, h0
980; CHECK-FP16-NEXT:    ret
981entry:
982  %conv = fptosi half %x to i128
983  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807)
984  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808)
985  %conv6 = trunc i128 %spec.store.select7 to i64
986  ret i64 %conv6
987}
988
989define i64 @utesth_f16i64_mm(half %x) {
990; CHECK-LABEL: utesth_f16i64_mm:
991; CHECK:       // %bb.0: // %entry
992; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
993; CHECK-NEXT:    .cfi_def_cfa_offset 16
994; CHECK-NEXT:    .cfi_offset w30, -16
995; CHECK-NEXT:    bl __fixunshfti
996; CHECK-NEXT:    cmp x1, #0
997; CHECK-NEXT:    csel x0, x0, xzr, eq
998; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
999; CHECK-NEXT:    ret
1000entry:
1001  %conv = fptoui half %x to i128
1002  %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616)
1003  %conv6 = trunc i128 %spec.store.select to i64
1004  ret i64 %conv6
1005}
1006
1007define i64 @ustest_f16i64_mm(half %x) {
1008; CHECK-LABEL: ustest_f16i64_mm:
1009; CHECK:       // %bb.0: // %entry
1010; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
1011; CHECK-NEXT:    .cfi_def_cfa_offset 16
1012; CHECK-NEXT:    .cfi_offset w30, -16
1013; CHECK-NEXT:    bl __fixhfti
1014; CHECK-NEXT:    cmp x1, #1
1015; CHECK-NEXT:    csinc x8, x1, xzr, lt
1016; CHECK-NEXT:    csel x9, x0, xzr, lt
1017; CHECK-NEXT:    cmp x8, #0
1018; CHECK-NEXT:    csel x0, xzr, x9, lt
1019; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
1020; CHECK-NEXT:    ret
1021entry:
1022  %conv = fptosi half %x to i128
1023  %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616)
1024  %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0)
1025  %conv6 = trunc i128 %spec.store.select7 to i64
1026  ret i64 %conv6
1027}
1028
1029declare i32 @llvm.smin.i32(i32, i32)
1030declare i32 @llvm.smax.i32(i32, i32)
1031declare i32 @llvm.umin.i32(i32, i32)
1032declare i64 @llvm.smin.i64(i64, i64)
1033declare i64 @llvm.smax.i64(i64, i64)
1034declare i64 @llvm.umin.i64(i64, i64)
1035declare i128 @llvm.smin.i128(i128, i128)
1036declare i128 @llvm.smax.i128(i128, i128)
1037declare i128 @llvm.umin.i128(i128, i128)
1038