xref: /llvm-project/llvm/test/CodeGen/AArch64/fpclamptosat_vec.ll (revision 61510b51c33464a6bc15e4cf5b1ee07e2e0ec1c9)
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 <2 x i32> @stest_f64i32(<2 x double> %x) {
8; CHECK-LABEL: stest_f64i32:
9; CHECK:       // %bb.0: // %entry
10; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
11; CHECK-NEXT:    sqxtn v0.2s, v0.2d
12; CHECK-NEXT:    ret
13entry:
14  %conv = fptosi <2 x double> %x to <2 x i64>
15  %0 = icmp slt <2 x i64> %conv, <i64 2147483647, i64 2147483647>
16  %spec.store.select = select <2 x i1> %0, <2 x i64> %conv, <2 x i64> <i64 2147483647, i64 2147483647>
17  %1 = icmp sgt <2 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648>
18  %spec.store.select7 = select <2 x i1> %1, <2 x i64> %spec.store.select, <2 x i64> <i64 -2147483648, i64 -2147483648>
19  %conv6 = trunc <2 x i64> %spec.store.select7 to <2 x i32>
20  ret <2 x i32> %conv6
21}
22
23define <2 x i32> @utest_f64i32(<2 x double> %x) {
24; CHECK-LABEL: utest_f64i32:
25; CHECK:       // %bb.0: // %entry
26; CHECK-NEXT:    mov d1, v0.d[1]
27; CHECK-NEXT:    fcvtzu w8, d0
28; CHECK-NEXT:    fcvtzu w9, d1
29; CHECK-NEXT:    fmov s0, w8
30; CHECK-NEXT:    mov v0.s[1], w9
31; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
32; CHECK-NEXT:    ret
33entry:
34  %conv = fptoui <2 x double> %x to <2 x i64>
35  %0 = icmp ult <2 x i64> %conv, <i64 4294967295, i64 4294967295>
36  %spec.store.select = select <2 x i1> %0, <2 x i64> %conv, <2 x i64> <i64 4294967295, i64 4294967295>
37  %conv6 = trunc <2 x i64> %spec.store.select to <2 x i32>
38  ret <2 x i32> %conv6
39}
40
41define <2 x i32> @ustest_f64i32(<2 x double> %x) {
42; CHECK-LABEL: ustest_f64i32:
43; CHECK:       // %bb.0: // %entry
44; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
45; CHECK-NEXT:    sqxtun v0.2s, v0.2d
46; CHECK-NEXT:    ret
47entry:
48  %conv = fptosi <2 x double> %x to <2 x i64>
49  %0 = icmp slt <2 x i64> %conv, <i64 4294967295, i64 4294967295>
50  %spec.store.select = select <2 x i1> %0, <2 x i64> %conv, <2 x i64> <i64 4294967295, i64 4294967295>
51  %1 = icmp sgt <2 x i64> %spec.store.select, zeroinitializer
52  %spec.store.select7 = select <2 x i1> %1, <2 x i64> %spec.store.select, <2 x i64> zeroinitializer
53  %conv6 = trunc <2 x i64> %spec.store.select7 to <2 x i32>
54  ret <2 x i32> %conv6
55}
56
57define <4 x i32> @stest_f32i32(<4 x float> %x) {
58; CHECK-LABEL: stest_f32i32:
59; CHECK:       // %bb.0: // %entry
60; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
61; CHECK-NEXT:    ret
62entry:
63  %conv = fptosi <4 x float> %x to <4 x i64>
64  %0 = icmp slt <4 x i64> %conv, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
65  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
66  %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
67  %spec.store.select7 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
68  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
69  ret <4 x i32> %conv6
70}
71
72define <4 x i32> @utest_f32i32(<4 x float> %x) {
73; CHECK-LABEL: utest_f32i32:
74; CHECK:       // %bb.0: // %entry
75; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
76; CHECK-NEXT:    ret
77entry:
78  %conv = fptoui <4 x float> %x to <4 x i64>
79  %0 = icmp ult <4 x i64> %conv, <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
80  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
81  %conv6 = trunc <4 x i64> %spec.store.select to <4 x i32>
82  ret <4 x i32> %conv6
83}
84
85define <4 x i32> @ustest_f32i32(<4 x float> %x) {
86; CHECK-LABEL: ustest_f32i32:
87; CHECK:       // %bb.0: // %entry
88; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
89; CHECK-NEXT:    ret
90entry:
91  %conv = fptosi <4 x float> %x to <4 x i64>
92  %0 = icmp slt <4 x i64> %conv, <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
93  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
94  %1 = icmp sgt <4 x i64> %spec.store.select, zeroinitializer
95  %spec.store.select7 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> zeroinitializer
96  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
97  ret <4 x i32> %conv6
98}
99
100define <4 x i32> @stest_f16i32(<4 x half> %x) {
101; CHECK-LABEL: stest_f16i32:
102; CHECK:       // %bb.0: // %entry
103; CHECK-NEXT:    fcvtl v0.4s, v0.4h
104; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
105; CHECK-NEXT:    ret
106entry:
107  %conv = fptosi <4 x half> %x to <4 x i64>
108  %0 = icmp slt <4 x i64> %conv, <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
109  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>
110  %1 = icmp sgt <4 x i64> %spec.store.select, <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
111  %spec.store.select7 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>
112  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
113  ret <4 x i32> %conv6
114}
115
116define <4 x i32> @utesth_f16i32(<4 x half> %x) {
117; CHECK-LABEL: utesth_f16i32:
118; CHECK:       // %bb.0: // %entry
119; CHECK-NEXT:    fcvtl v0.4s, v0.4h
120; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
121; CHECK-NEXT:    ret
122entry:
123  %conv = fptoui <4 x half> %x to <4 x i64>
124  %0 = icmp ult <4 x i64> %conv, <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
125  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
126  %conv6 = trunc <4 x i64> %spec.store.select to <4 x i32>
127  ret <4 x i32> %conv6
128}
129
130define <4 x i32> @ustest_f16i32(<4 x half> %x) {
131; CHECK-LABEL: ustest_f16i32:
132; CHECK:       // %bb.0: // %entry
133; CHECK-NEXT:    fcvtl v0.4s, v0.4h
134; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
135; CHECK-NEXT:    ret
136entry:
137  %conv = fptosi <4 x half> %x to <4 x i64>
138  %0 = icmp slt <4 x i64> %conv, <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
139  %spec.store.select = select <4 x i1> %0, <4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>
140  %1 = icmp sgt <4 x i64> %spec.store.select, zeroinitializer
141  %spec.store.select7 = select <4 x i1> %1, <4 x i64> %spec.store.select, <4 x i64> zeroinitializer
142  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
143  ret <4 x i32> %conv6
144}
145
146; i16 saturate
147
148define <2 x i16> @stest_f64i16(<2 x double> %x) {
149; CHECK-LABEL: stest_f64i16:
150; CHECK:       // %bb.0: // %entry
151; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
152; CHECK-NEXT:    movi v1.2s, #127, msl #8
153; CHECK-NEXT:    xtn v0.2s, v0.2d
154; CHECK-NEXT:    smin v0.2s, v0.2s, v1.2s
155; CHECK-NEXT:    mvni v1.2s, #127, msl #8
156; CHECK-NEXT:    smax v0.2s, v0.2s, v1.2s
157; CHECK-NEXT:    ret
158entry:
159  %conv = fptosi <2 x double> %x to <2 x i32>
160  %0 = icmp slt <2 x i32> %conv, <i32 32767, i32 32767>
161  %spec.store.select = select <2 x i1> %0, <2 x i32> %conv, <2 x i32> <i32 32767, i32 32767>
162  %1 = icmp sgt <2 x i32> %spec.store.select, <i32 -32768, i32 -32768>
163  %spec.store.select7 = select <2 x i1> %1, <2 x i32> %spec.store.select, <2 x i32> <i32 -32768, i32 -32768>
164  %conv6 = trunc <2 x i32> %spec.store.select7 to <2 x i16>
165  ret <2 x i16> %conv6
166}
167
168define <2 x i16> @utest_f64i16(<2 x double> %x) {
169; CHECK-LABEL: utest_f64i16:
170; CHECK:       // %bb.0: // %entry
171; CHECK-NEXT:    fcvtzu v0.2d, v0.2d
172; CHECK-NEXT:    movi d1, #0x00ffff0000ffff
173; CHECK-NEXT:    xtn v0.2s, v0.2d
174; CHECK-NEXT:    umin v0.2s, v0.2s, v1.2s
175; CHECK-NEXT:    ret
176entry:
177  %conv = fptoui <2 x double> %x to <2 x i32>
178  %0 = icmp ult <2 x i32> %conv, <i32 65535, i32 65535>
179  %spec.store.select = select <2 x i1> %0, <2 x i32> %conv, <2 x i32> <i32 65535, i32 65535>
180  %conv6 = trunc <2 x i32> %spec.store.select to <2 x i16>
181  ret <2 x i16> %conv6
182}
183
184define <2 x i16> @ustest_f64i16(<2 x double> %x) {
185; CHECK-LABEL: ustest_f64i16:
186; CHECK:       // %bb.0: // %entry
187; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
188; CHECK-NEXT:    movi d1, #0x00ffff0000ffff
189; CHECK-NEXT:    movi v2.2d, #0000000000000000
190; CHECK-NEXT:    xtn v0.2s, v0.2d
191; CHECK-NEXT:    smin v0.2s, v0.2s, v1.2s
192; CHECK-NEXT:    smax v0.2s, v0.2s, v2.2s
193; CHECK-NEXT:    ret
194entry:
195  %conv = fptosi <2 x double> %x to <2 x i32>
196  %0 = icmp slt <2 x i32> %conv, <i32 65535, i32 65535>
197  %spec.store.select = select <2 x i1> %0, <2 x i32> %conv, <2 x i32> <i32 65535, i32 65535>
198  %1 = icmp sgt <2 x i32> %spec.store.select, zeroinitializer
199  %spec.store.select7 = select <2 x i1> %1, <2 x i32> %spec.store.select, <2 x i32> zeroinitializer
200  %conv6 = trunc <2 x i32> %spec.store.select7 to <2 x i16>
201  ret <2 x i16> %conv6
202}
203
204define <4 x i16> @stest_f32i16(<4 x float> %x) {
205; CHECK-LABEL: stest_f32i16:
206; CHECK:       // %bb.0: // %entry
207; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
208; CHECK-NEXT:    sqxtn v0.4h, v0.4s
209; CHECK-NEXT:    ret
210entry:
211  %conv = fptosi <4 x float> %x to <4 x i32>
212  %0 = icmp slt <4 x i32> %conv, <i32 32767, i32 32767, i32 32767, i32 32767>
213  %spec.store.select = select <4 x i1> %0, <4 x i32> %conv, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>
214  %1 = icmp sgt <4 x i32> %spec.store.select, <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
215  %spec.store.select7 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>
216  %conv6 = trunc <4 x i32> %spec.store.select7 to <4 x i16>
217  ret <4 x i16> %conv6
218}
219
220define <4 x i16> @utest_f32i16(<4 x float> %x) {
221; CHECK-LABEL: utest_f32i16:
222; CHECK:       // %bb.0: // %entry
223; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
224; CHECK-NEXT:    uqxtn v0.4h, v0.4s
225; CHECK-NEXT:    ret
226entry:
227  %conv = fptoui <4 x float> %x to <4 x i32>
228  %0 = icmp ult <4 x i32> %conv, <i32 65535, i32 65535, i32 65535, i32 65535>
229  %spec.store.select = select <4 x i1> %0, <4 x i32> %conv, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
230  %conv6 = trunc <4 x i32> %spec.store.select to <4 x i16>
231  ret <4 x i16> %conv6
232}
233
234define <4 x i16> @ustest_f32i16(<4 x float> %x) {
235; CHECK-LABEL: ustest_f32i16:
236; CHECK:       // %bb.0: // %entry
237; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
238; CHECK-NEXT:    sqxtun v0.4h, v0.4s
239; CHECK-NEXT:    ret
240entry:
241  %conv = fptosi <4 x float> %x to <4 x i32>
242  %0 = icmp slt <4 x i32> %conv, <i32 65535, i32 65535, i32 65535, i32 65535>
243  %spec.store.select = select <4 x i1> %0, <4 x i32> %conv, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>
244  %1 = icmp sgt <4 x i32> %spec.store.select, zeroinitializer
245  %spec.store.select7 = select <4 x i1> %1, <4 x i32> %spec.store.select, <4 x i32> zeroinitializer
246  %conv6 = trunc <4 x i32> %spec.store.select7 to <4 x i16>
247  ret <4 x i16> %conv6
248}
249
250define <8 x i16> @stest_f16i16(<8 x half> %x) {
251; CHECK-CVT-LABEL: stest_f16i16:
252; CHECK-CVT:       // %bb.0: // %entry
253; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
254; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
255; CHECK-CVT-NEXT:    fcvtzs v1.4s, v1.4s
256; CHECK-CVT-NEXT:    fcvtzs v2.4s, v0.4s
257; CHECK-CVT-NEXT:    sqxtn v0.4h, v1.4s
258; CHECK-CVT-NEXT:    sqxtn2 v0.8h, v2.4s
259; CHECK-CVT-NEXT:    ret
260;
261; CHECK-FP16-LABEL: stest_f16i16:
262; CHECK-FP16:       // %bb.0: // %entry
263; CHECK-FP16-NEXT:    fcvtzs v0.8h, v0.8h
264; CHECK-FP16-NEXT:    ret
265entry:
266  %conv = fptosi <8 x half> %x to <8 x i32>
267  %0 = icmp slt <8 x i32> %conv, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
268  %spec.store.select = select <8 x i1> %0, <8 x i32> %conv, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
269  %1 = icmp sgt <8 x i32> %spec.store.select, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
270  %spec.store.select7 = select <8 x i1> %1, <8 x i32> %spec.store.select, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
271  %conv6 = trunc <8 x i32> %spec.store.select7 to <8 x i16>
272  ret <8 x i16> %conv6
273}
274
275define <8 x i16> @utesth_f16i16(<8 x half> %x) {
276; CHECK-CVT-LABEL: utesth_f16i16:
277; CHECK-CVT:       // %bb.0: // %entry
278; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
279; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
280; CHECK-CVT-NEXT:    fcvtzu v1.4s, v1.4s
281; CHECK-CVT-NEXT:    fcvtzu v2.4s, v0.4s
282; CHECK-CVT-NEXT:    uqxtn v0.4h, v1.4s
283; CHECK-CVT-NEXT:    uqxtn2 v0.8h, v2.4s
284; CHECK-CVT-NEXT:    ret
285;
286; CHECK-FP16-LABEL: utesth_f16i16:
287; CHECK-FP16:       // %bb.0: // %entry
288; CHECK-FP16-NEXT:    fcvtzu v0.8h, v0.8h
289; CHECK-FP16-NEXT:    ret
290entry:
291  %conv = fptoui <8 x half> %x to <8 x i32>
292  %0 = icmp ult <8 x i32> %conv, <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
293  %spec.store.select = select <8 x i1> %0, <8 x i32> %conv, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
294  %conv6 = trunc <8 x i32> %spec.store.select to <8 x i16>
295  ret <8 x i16> %conv6
296}
297
298define <8 x i16> @ustest_f16i16(<8 x half> %x) {
299; CHECK-CVT-LABEL: ustest_f16i16:
300; CHECK-CVT:       // %bb.0: // %entry
301; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
302; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
303; CHECK-CVT-NEXT:    fcvtzs v1.4s, v1.4s
304; CHECK-CVT-NEXT:    fcvtzs v2.4s, v0.4s
305; CHECK-CVT-NEXT:    sqxtun v0.4h, v1.4s
306; CHECK-CVT-NEXT:    sqxtun2 v0.8h, v2.4s
307; CHECK-CVT-NEXT:    ret
308;
309; CHECK-FP16-LABEL: ustest_f16i16:
310; CHECK-FP16:       // %bb.0: // %entry
311; CHECK-FP16-NEXT:    fcvtzu v0.8h, v0.8h
312; CHECK-FP16-NEXT:    ret
313entry:
314  %conv = fptosi <8 x half> %x to <8 x i32>
315  %0 = icmp slt <8 x i32> %conv, <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
316  %spec.store.select = select <8 x i1> %0, <8 x i32> %conv, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>
317  %1 = icmp sgt <8 x i32> %spec.store.select, zeroinitializer
318  %spec.store.select7 = select <8 x i1> %1, <8 x i32> %spec.store.select, <8 x i32> zeroinitializer
319  %conv6 = trunc <8 x i32> %spec.store.select7 to <8 x i16>
320  ret <8 x i16> %conv6
321}
322
323; i64 saturate
324
325define <2 x i64> @stest_f64i64(<2 x double> %x) {
326; CHECK-LABEL: stest_f64i64:
327; CHECK:       // %bb.0: // %entry
328; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
329; CHECK-NEXT:    ret
330entry:
331  %conv = fptosi <2 x double> %x to <2 x i128>
332  %0 = icmp slt <2 x i128> %conv, <i128 9223372036854775807, i128 9223372036854775807>
333  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>
334  %1 = icmp sgt <2 x i128> %spec.store.select, <i128 -9223372036854775808, i128 -9223372036854775808>
335  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>
336  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
337  ret <2 x i64> %conv6
338}
339
340define <2 x i64> @utest_f64i64(<2 x double> %x) {
341; CHECK-LABEL: utest_f64i64:
342; CHECK:       // %bb.0: // %entry
343; CHECK-NEXT:    sub sp, sp, #48
344; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
345; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
346; CHECK-NEXT:    .cfi_def_cfa_offset 48
347; CHECK-NEXT:    .cfi_offset w19, -8
348; CHECK-NEXT:    .cfi_offset w20, -16
349; CHECK-NEXT:    .cfi_offset w30, -32
350; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
351; CHECK-NEXT:    mov d0, v0.d[1]
352; CHECK-NEXT:    bl __fixunsdfti
353; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
354; CHECK-NEXT:    mov x19, x0
355; CHECK-NEXT:    mov x20, x1
356; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
357; CHECK-NEXT:    bl __fixunsdfti
358; CHECK-NEXT:    cmp x1, #0
359; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
360; CHECK-NEXT:    csel x8, x0, xzr, eq
361; CHECK-NEXT:    cmp x20, #0
362; CHECK-NEXT:    csel x9, x19, xzr, eq
363; CHECK-NEXT:    fmov d0, x8
364; CHECK-NEXT:    fmov d1, x9
365; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
366; CHECK-NEXT:    mov v0.d[1], v1.d[0]
367; CHECK-NEXT:    add sp, sp, #48
368; CHECK-NEXT:    ret
369entry:
370  %conv = fptoui <2 x double> %x to <2 x i128>
371  %0 = icmp ult <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
372  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
373  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
374  ret <2 x i64> %conv6
375}
376
377define <2 x i64> @ustest_f64i64(<2 x double> %x) {
378; CHECK-LABEL: ustest_f64i64:
379; CHECK:       // %bb.0: // %entry
380; CHECK-NEXT:    sub sp, sp, #48
381; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
382; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
383; CHECK-NEXT:    .cfi_def_cfa_offset 48
384; CHECK-NEXT:    .cfi_offset w19, -8
385; CHECK-NEXT:    .cfi_offset w20, -16
386; CHECK-NEXT:    .cfi_offset w30, -32
387; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
388; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
389; CHECK-NEXT:    bl __fixdfti
390; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
391; CHECK-NEXT:    mov x19, x0
392; CHECK-NEXT:    mov x20, x1
393; CHECK-NEXT:    mov d0, v0.d[1]
394; CHECK-NEXT:    bl __fixdfti
395; CHECK-NEXT:    cmp x1, #1
396; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
397; CHECK-NEXT:    csel x8, x0, xzr, lt
398; CHECK-NEXT:    csinc x9, x1, xzr, lt
399; CHECK-NEXT:    cmp x20, #1
400; CHECK-NEXT:    csel x10, x19, xzr, lt
401; CHECK-NEXT:    csinc x11, x20, xzr, lt
402; CHECK-NEXT:    cmp xzr, x10
403; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
404; CHECK-NEXT:    ngcs xzr, x11
405; CHECK-NEXT:    csel x10, x10, xzr, lt
406; CHECK-NEXT:    cmp xzr, x8
407; CHECK-NEXT:    ngcs xzr, x9
408; CHECK-NEXT:    fmov d0, x10
409; CHECK-NEXT:    csel x8, x8, xzr, lt
410; CHECK-NEXT:    fmov d1, x8
411; CHECK-NEXT:    mov v0.d[1], v1.d[0]
412; CHECK-NEXT:    add sp, sp, #48
413; CHECK-NEXT:    ret
414entry:
415  %conv = fptosi <2 x double> %x to <2 x i128>
416  %0 = icmp slt <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
417  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
418  %1 = icmp sgt <2 x i128> %spec.store.select, zeroinitializer
419  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> zeroinitializer
420  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
421  ret <2 x i64> %conv6
422}
423
424define <2 x i64> @stest_f32i64(<2 x float> %x) {
425; CHECK-LABEL: stest_f32i64:
426; CHECK:       // %bb.0: // %entry
427; CHECK-NEXT:    fcvtl v0.2d, v0.2s
428; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
429; CHECK-NEXT:    ret
430entry:
431  %conv = fptosi <2 x float> %x to <2 x i128>
432  %0 = icmp slt <2 x i128> %conv, <i128 9223372036854775807, i128 9223372036854775807>
433  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>
434  %1 = icmp sgt <2 x i128> %spec.store.select, <i128 -9223372036854775808, i128 -9223372036854775808>
435  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>
436  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
437  ret <2 x i64> %conv6
438}
439
440define <2 x i64> @utest_f32i64(<2 x float> %x) {
441; CHECK-LABEL: utest_f32i64:
442; CHECK:       // %bb.0: // %entry
443; CHECK-NEXT:    sub sp, sp, #48
444; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
445; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
446; CHECK-NEXT:    .cfi_def_cfa_offset 48
447; CHECK-NEXT:    .cfi_offset w19, -8
448; CHECK-NEXT:    .cfi_offset w20, -16
449; CHECK-NEXT:    .cfi_offset w30, -32
450; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
451; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
452; CHECK-NEXT:    mov s0, v0.s[1]
453; CHECK-NEXT:    bl __fixunssfti
454; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
455; CHECK-NEXT:    mov x19, x0
456; CHECK-NEXT:    mov x20, x1
457; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
458; CHECK-NEXT:    bl __fixunssfti
459; CHECK-NEXT:    cmp x1, #0
460; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
461; CHECK-NEXT:    csel x8, x0, xzr, eq
462; CHECK-NEXT:    cmp x20, #0
463; CHECK-NEXT:    csel x9, x19, xzr, eq
464; CHECK-NEXT:    fmov d0, x8
465; CHECK-NEXT:    fmov d1, x9
466; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
467; CHECK-NEXT:    mov v0.d[1], v1.d[0]
468; CHECK-NEXT:    add sp, sp, #48
469; CHECK-NEXT:    ret
470entry:
471  %conv = fptoui <2 x float> %x to <2 x i128>
472  %0 = icmp ult <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
473  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
474  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
475  ret <2 x i64> %conv6
476}
477
478define <2 x i64> @ustest_f32i64(<2 x float> %x) {
479; CHECK-LABEL: ustest_f32i64:
480; CHECK:       // %bb.0: // %entry
481; CHECK-NEXT:    sub sp, sp, #48
482; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
483; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
484; CHECK-NEXT:    .cfi_def_cfa_offset 48
485; CHECK-NEXT:    .cfi_offset w19, -8
486; CHECK-NEXT:    .cfi_offset w20, -16
487; CHECK-NEXT:    .cfi_offset w30, -32
488; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
489; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
490; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
491; CHECK-NEXT:    bl __fixsfti
492; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
493; CHECK-NEXT:    mov x19, x0
494; CHECK-NEXT:    mov x20, x1
495; CHECK-NEXT:    mov s0, v0.s[1]
496; CHECK-NEXT:    bl __fixsfti
497; CHECK-NEXT:    cmp x1, #1
498; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
499; CHECK-NEXT:    csinc x8, x1, xzr, lt
500; CHECK-NEXT:    csel x9, x0, xzr, lt
501; CHECK-NEXT:    cmp x20, #1
502; CHECK-NEXT:    csel x10, x19, xzr, lt
503; CHECK-NEXT:    csinc x11, x20, xzr, lt
504; CHECK-NEXT:    cmp xzr, x10
505; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
506; CHECK-NEXT:    ngcs xzr, x11
507; CHECK-NEXT:    csel x10, x10, xzr, lt
508; CHECK-NEXT:    cmp xzr, x9
509; CHECK-NEXT:    ngcs xzr, x8
510; CHECK-NEXT:    fmov d0, x10
511; CHECK-NEXT:    csel x8, x9, xzr, lt
512; CHECK-NEXT:    fmov d1, x8
513; CHECK-NEXT:    mov v0.d[1], v1.d[0]
514; CHECK-NEXT:    add sp, sp, #48
515; CHECK-NEXT:    ret
516entry:
517  %conv = fptosi <2 x float> %x to <2 x i128>
518  %0 = icmp slt <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
519  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
520  %1 = icmp sgt <2 x i128> %spec.store.select, zeroinitializer
521  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> zeroinitializer
522  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
523  ret <2 x i64> %conv6
524}
525
526define <2 x i64> @stest_f16i64(<2 x half> %x) {
527; CHECK-CVT-LABEL: stest_f16i64:
528; CHECK-CVT:       // %bb.0: // %entry
529; CHECK-CVT-NEXT:    // kill: def $d0 killed $d0 def $q0
530; CHECK-CVT-NEXT:    mov h1, v0.h[1]
531; CHECK-CVT-NEXT:    fcvt s0, h0
532; CHECK-CVT-NEXT:    fcvt s1, h1
533; CHECK-CVT-NEXT:    fcvtzs x8, s0
534; CHECK-CVT-NEXT:    fcvtzs x9, s1
535; CHECK-CVT-NEXT:    fmov d0, x8
536; CHECK-CVT-NEXT:    mov v0.d[1], x9
537; CHECK-CVT-NEXT:    ret
538;
539; CHECK-FP16-LABEL: stest_f16i64:
540; CHECK-FP16:       // %bb.0: // %entry
541; CHECK-FP16-NEXT:    // kill: def $d0 killed $d0 def $q0
542; CHECK-FP16-NEXT:    mov h1, v0.h[1]
543; CHECK-FP16-NEXT:    fcvtzs x8, h0
544; CHECK-FP16-NEXT:    fcvtzs x9, h1
545; CHECK-FP16-NEXT:    fmov d0, x8
546; CHECK-FP16-NEXT:    mov v0.d[1], x9
547; CHECK-FP16-NEXT:    ret
548entry:
549  %conv = fptosi <2 x half> %x to <2 x i128>
550  %0 = icmp slt <2 x i128> %conv, <i128 9223372036854775807, i128 9223372036854775807>
551  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>
552  %1 = icmp sgt <2 x i128> %spec.store.select, <i128 -9223372036854775808, i128 -9223372036854775808>
553  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>
554  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
555  ret <2 x i64> %conv6
556}
557
558define <2 x i64> @utesth_f16i64(<2 x half> %x) {
559; CHECK-LABEL: utesth_f16i64:
560; CHECK:       // %bb.0: // %entry
561; CHECK-NEXT:    sub sp, sp, #48
562; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
563; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
564; CHECK-NEXT:    .cfi_def_cfa_offset 48
565; CHECK-NEXT:    .cfi_offset w19, -8
566; CHECK-NEXT:    .cfi_offset w20, -16
567; CHECK-NEXT:    .cfi_offset w30, -32
568; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
569; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
570; CHECK-NEXT:    mov h0, v0.h[1]
571; CHECK-NEXT:    bl __fixunshfti
572; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
573; CHECK-NEXT:    mov x19, x0
574; CHECK-NEXT:    mov x20, x1
575; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $q0
576; CHECK-NEXT:    bl __fixunshfti
577; CHECK-NEXT:    cmp x1, #0
578; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
579; CHECK-NEXT:    csel x8, x0, xzr, eq
580; CHECK-NEXT:    cmp x20, #0
581; CHECK-NEXT:    csel x9, x19, xzr, eq
582; CHECK-NEXT:    fmov d0, x8
583; CHECK-NEXT:    fmov d1, x9
584; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
585; CHECK-NEXT:    mov v0.d[1], v1.d[0]
586; CHECK-NEXT:    add sp, sp, #48
587; CHECK-NEXT:    ret
588entry:
589  %conv = fptoui <2 x half> %x to <2 x i128>
590  %0 = icmp ult <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
591  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
592  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
593  ret <2 x i64> %conv6
594}
595
596define <2 x i64> @ustest_f16i64(<2 x half> %x) {
597; CHECK-LABEL: ustest_f16i64:
598; CHECK:       // %bb.0: // %entry
599; CHECK-NEXT:    sub sp, sp, #48
600; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
601; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
602; CHECK-NEXT:    .cfi_def_cfa_offset 48
603; CHECK-NEXT:    .cfi_offset w19, -8
604; CHECK-NEXT:    .cfi_offset w20, -16
605; CHECK-NEXT:    .cfi_offset w30, -32
606; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
607; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
608; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $q0
609; CHECK-NEXT:    bl __fixhfti
610; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
611; CHECK-NEXT:    mov x19, x0
612; CHECK-NEXT:    mov x20, x1
613; CHECK-NEXT:    mov h0, v0.h[1]
614; CHECK-NEXT:    bl __fixhfti
615; CHECK-NEXT:    cmp x1, #1
616; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
617; CHECK-NEXT:    csinc x8, x1, xzr, lt
618; CHECK-NEXT:    csel x9, x0, xzr, lt
619; CHECK-NEXT:    cmp x20, #1
620; CHECK-NEXT:    csel x10, x19, xzr, lt
621; CHECK-NEXT:    csinc x11, x20, xzr, lt
622; CHECK-NEXT:    cmp xzr, x10
623; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
624; CHECK-NEXT:    ngcs xzr, x11
625; CHECK-NEXT:    csel x10, x10, xzr, lt
626; CHECK-NEXT:    cmp xzr, x9
627; CHECK-NEXT:    ngcs xzr, x8
628; CHECK-NEXT:    fmov d0, x10
629; CHECK-NEXT:    csel x8, x9, xzr, lt
630; CHECK-NEXT:    fmov d1, x8
631; CHECK-NEXT:    mov v0.d[1], v1.d[0]
632; CHECK-NEXT:    add sp, sp, #48
633; CHECK-NEXT:    ret
634entry:
635  %conv = fptosi <2 x half> %x to <2 x i128>
636  %0 = icmp slt <2 x i128> %conv, <i128 18446744073709551616, i128 18446744073709551616>
637  %spec.store.select = select <2 x i1> %0, <2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>
638  %1 = icmp sgt <2 x i128> %spec.store.select, zeroinitializer
639  %spec.store.select7 = select <2 x i1> %1, <2 x i128> %spec.store.select, <2 x i128> zeroinitializer
640  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
641  ret <2 x i64> %conv6
642}
643
644
645
646; i32 saturate
647
648define <2 x i32> @stest_f64i32_mm(<2 x double> %x) {
649; CHECK-LABEL: stest_f64i32_mm:
650; CHECK:       // %bb.0: // %entry
651; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
652; CHECK-NEXT:    sqxtn v0.2s, v0.2d
653; CHECK-NEXT:    ret
654entry:
655  %conv = fptosi <2 x double> %x to <2 x i64>
656  %spec.store.select = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> <i64 2147483647, i64 2147483647>)
657  %spec.store.select7 = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %spec.store.select, <2 x i64> <i64 -2147483648, i64 -2147483648>)
658  %conv6 = trunc <2 x i64> %spec.store.select7 to <2 x i32>
659  ret <2 x i32> %conv6
660}
661
662define <2 x i32> @utest_f64i32_mm(<2 x double> %x) {
663; CHECK-LABEL: utest_f64i32_mm:
664; CHECK:       // %bb.0: // %entry
665; CHECK-NEXT:    mov d1, v0.d[1]
666; CHECK-NEXT:    fcvtzu w8, d0
667; CHECK-NEXT:    fcvtzu w9, d1
668; CHECK-NEXT:    fmov s0, w8
669; CHECK-NEXT:    mov v0.s[1], w9
670; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
671; CHECK-NEXT:    ret
672entry:
673  %conv = fptoui <2 x double> %x to <2 x i64>
674  %spec.store.select = call <2 x i64> @llvm.umin.v2i64(<2 x i64> %conv, <2 x i64> <i64 4294967295, i64 4294967295>)
675  %conv6 = trunc <2 x i64> %spec.store.select to <2 x i32>
676  ret <2 x i32> %conv6
677}
678
679define <2 x i32> @ustest_f64i32_mm(<2 x double> %x) {
680; CHECK-LABEL: ustest_f64i32_mm:
681; CHECK:       // %bb.0: // %entry
682; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
683; CHECK-NEXT:    sqxtun v0.2s, v0.2d
684; CHECK-NEXT:    ret
685entry:
686  %conv = fptosi <2 x double> %x to <2 x i64>
687  %spec.store.select = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> <i64 4294967295, i64 4294967295>)
688  %spec.store.select7 = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %spec.store.select, <2 x i64> zeroinitializer)
689  %conv6 = trunc <2 x i64> %spec.store.select7 to <2 x i32>
690  ret <2 x i32> %conv6
691}
692
693define <4 x i32> @stest_f32i32_mm(<4 x float> %x) {
694; CHECK-LABEL: stest_f32i32_mm:
695; CHECK:       // %bb.0: // %entry
696; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
697; CHECK-NEXT:    ret
698entry:
699  %conv = fptosi <4 x float> %x to <4 x i64>
700  %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
701  %spec.store.select7 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
702  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
703  ret <4 x i32> %conv6
704}
705
706define <4 x i32> @utest_f32i32_mm(<4 x float> %x) {
707; CHECK-LABEL: utest_f32i32_mm:
708; CHECK:       // %bb.0: // %entry
709; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
710; CHECK-NEXT:    ret
711entry:
712  %conv = fptoui <4 x float> %x to <4 x i64>
713  %spec.store.select = call <4 x i64> @llvm.umin.v4i64(<4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
714  %conv6 = trunc <4 x i64> %spec.store.select to <4 x i32>
715  ret <4 x i32> %conv6
716}
717
718define <4 x i32> @ustest_f32i32_mm(<4 x float> %x) {
719; CHECK-LABEL: ustest_f32i32_mm:
720; CHECK:       // %bb.0: // %entry
721; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
722; CHECK-NEXT:    ret
723entry:
724  %conv = fptosi <4 x float> %x to <4 x i64>
725  %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
726  %spec.store.select7 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> zeroinitializer)
727  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
728  ret <4 x i32> %conv6
729}
730
731define <4 x i32> @stest_f16i32_mm(<4 x half> %x) {
732; CHECK-LABEL: stest_f16i32_mm:
733; CHECK:       // %bb.0: // %entry
734; CHECK-NEXT:    fcvtl v0.4s, v0.4h
735; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
736; CHECK-NEXT:    ret
737entry:
738  %conv = fptosi <4 x half> %x to <4 x i64>
739  %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)
740  %spec.store.select7 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)
741  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
742  ret <4 x i32> %conv6
743}
744
745define <4 x i32> @utesth_f16i32_mm(<4 x half> %x) {
746; CHECK-LABEL: utesth_f16i32_mm:
747; CHECK:       // %bb.0: // %entry
748; CHECK-NEXT:    fcvtl v0.4s, v0.4h
749; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
750; CHECK-NEXT:    ret
751entry:
752  %conv = fptoui <4 x half> %x to <4 x i64>
753  %spec.store.select = call <4 x i64> @llvm.umin.v4i64(<4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
754  %conv6 = trunc <4 x i64> %spec.store.select to <4 x i32>
755  ret <4 x i32> %conv6
756}
757
758define <4 x i32> @ustest_f16i32_mm(<4 x half> %x) {
759; CHECK-LABEL: ustest_f16i32_mm:
760; CHECK:       // %bb.0: // %entry
761; CHECK-NEXT:    fcvtl v0.4s, v0.4h
762; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
763; CHECK-NEXT:    ret
764entry:
765  %conv = fptosi <4 x half> %x to <4 x i64>
766  %spec.store.select = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 4294967295, i64 4294967295, i64 4294967295, i64 4294967295>)
767  %spec.store.select7 = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %spec.store.select, <4 x i64> zeroinitializer)
768  %conv6 = trunc <4 x i64> %spec.store.select7 to <4 x i32>
769  ret <4 x i32> %conv6
770}
771
772; i16 saturate
773
774define <2 x i16> @stest_f64i16_mm(<2 x double> %x) {
775; CHECK-LABEL: stest_f64i16_mm:
776; CHECK:       // %bb.0: // %entry
777; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
778; CHECK-NEXT:    movi v1.2s, #127, msl #8
779; CHECK-NEXT:    xtn v0.2s, v0.2d
780; CHECK-NEXT:    smin v0.2s, v0.2s, v1.2s
781; CHECK-NEXT:    mvni v1.2s, #127, msl #8
782; CHECK-NEXT:    smax v0.2s, v0.2s, v1.2s
783; CHECK-NEXT:    ret
784entry:
785  %conv = fptosi <2 x double> %x to <2 x i32>
786  %spec.store.select = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %conv, <2 x i32> <i32 32767, i32 32767>)
787  %spec.store.select7 = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %spec.store.select, <2 x i32> <i32 -32768, i32 -32768>)
788  %conv6 = trunc <2 x i32> %spec.store.select7 to <2 x i16>
789  ret <2 x i16> %conv6
790}
791
792define <2 x i16> @utest_f64i16_mm(<2 x double> %x) {
793; CHECK-LABEL: utest_f64i16_mm:
794; CHECK:       // %bb.0: // %entry
795; CHECK-NEXT:    fcvtzu v0.2d, v0.2d
796; CHECK-NEXT:    movi d1, #0x00ffff0000ffff
797; CHECK-NEXT:    xtn v0.2s, v0.2d
798; CHECK-NEXT:    umin v0.2s, v0.2s, v1.2s
799; CHECK-NEXT:    ret
800entry:
801  %conv = fptoui <2 x double> %x to <2 x i32>
802  %spec.store.select = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %conv, <2 x i32> <i32 65535, i32 65535>)
803  %conv6 = trunc <2 x i32> %spec.store.select to <2 x i16>
804  ret <2 x i16> %conv6
805}
806
807define <2 x i16> @ustest_f64i16_mm(<2 x double> %x) {
808; CHECK-LABEL: ustest_f64i16_mm:
809; CHECK:       // %bb.0: // %entry
810; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
811; CHECK-NEXT:    movi d1, #0x00ffff0000ffff
812; CHECK-NEXT:    movi v2.2d, #0000000000000000
813; CHECK-NEXT:    xtn v0.2s, v0.2d
814; CHECK-NEXT:    smin v0.2s, v0.2s, v1.2s
815; CHECK-NEXT:    smax v0.2s, v0.2s, v2.2s
816; CHECK-NEXT:    ret
817entry:
818  %conv = fptosi <2 x double> %x to <2 x i32>
819  %spec.store.select = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %conv, <2 x i32> <i32 65535, i32 65535>)
820  %spec.store.select7 = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %spec.store.select, <2 x i32> zeroinitializer)
821  %conv6 = trunc <2 x i32> %spec.store.select7 to <2 x i16>
822  ret <2 x i16> %conv6
823}
824
825define <4 x i16> @stest_f32i16_mm(<4 x float> %x) {
826; CHECK-LABEL: stest_f32i16_mm:
827; CHECK:       // %bb.0: // %entry
828; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
829; CHECK-NEXT:    sqxtn v0.4h, v0.4s
830; CHECK-NEXT:    ret
831entry:
832  %conv = fptosi <4 x float> %x to <4 x i32>
833  %spec.store.select = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)
834  %spec.store.select7 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %spec.store.select, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
835  %conv6 = trunc <4 x i32> %spec.store.select7 to <4 x i16>
836  ret <4 x i16> %conv6
837}
838
839define <4 x i16> @utest_f32i16_mm(<4 x float> %x) {
840; CHECK-LABEL: utest_f32i16_mm:
841; CHECK:       // %bb.0: // %entry
842; CHECK-NEXT:    fcvtzu v0.4s, v0.4s
843; CHECK-NEXT:    uqxtn v0.4h, v0.4s
844; CHECK-NEXT:    ret
845entry:
846  %conv = fptoui <4 x float> %x to <4 x i32>
847  %spec.store.select = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %conv, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
848  %conv6 = trunc <4 x i32> %spec.store.select to <4 x i16>
849  ret <4 x i16> %conv6
850}
851
852define <4 x i16> @ustest_f32i16_mm(<4 x float> %x) {
853; CHECK-LABEL: ustest_f32i16_mm:
854; CHECK:       // %bb.0: // %entry
855; CHECK-NEXT:    fcvtzs v0.4s, v0.4s
856; CHECK-NEXT:    sqxtun v0.4h, v0.4s
857; CHECK-NEXT:    ret
858entry:
859  %conv = fptosi <4 x float> %x to <4 x i32>
860  %spec.store.select = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> <i32 65535, i32 65535, i32 65535, i32 65535>)
861  %spec.store.select7 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %spec.store.select, <4 x i32> zeroinitializer)
862  %conv6 = trunc <4 x i32> %spec.store.select7 to <4 x i16>
863  ret <4 x i16> %conv6
864}
865
866define <8 x i16> @stest_f16i16_mm(<8 x half> %x) {
867; CHECK-CVT-LABEL: stest_f16i16_mm:
868; CHECK-CVT:       // %bb.0: // %entry
869; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
870; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
871; CHECK-CVT-NEXT:    fcvtzs v1.4s, v1.4s
872; CHECK-CVT-NEXT:    fcvtzs v2.4s, v0.4s
873; CHECK-CVT-NEXT:    sqxtn v0.4h, v1.4s
874; CHECK-CVT-NEXT:    sqxtn2 v0.8h, v2.4s
875; CHECK-CVT-NEXT:    ret
876;
877; CHECK-FP16-LABEL: stest_f16i16_mm:
878; CHECK-FP16:       // %bb.0: // %entry
879; CHECK-FP16-NEXT:    fcvtzs v0.8h, v0.8h
880; CHECK-FP16-NEXT:    ret
881entry:
882  %conv = fptosi <8 x half> %x to <8 x i32>
883  %spec.store.select = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)
884  %spec.store.select7 = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %spec.store.select, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)
885  %conv6 = trunc <8 x i32> %spec.store.select7 to <8 x i16>
886  ret <8 x i16> %conv6
887}
888
889define <8 x i16> @utesth_f16i16_mm(<8 x half> %x) {
890; CHECK-CVT-LABEL: utesth_f16i16_mm:
891; CHECK-CVT:       // %bb.0: // %entry
892; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
893; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
894; CHECK-CVT-NEXT:    fcvtzu v1.4s, v1.4s
895; CHECK-CVT-NEXT:    fcvtzu v2.4s, v0.4s
896; CHECK-CVT-NEXT:    uqxtn v0.4h, v1.4s
897; CHECK-CVT-NEXT:    uqxtn2 v0.8h, v2.4s
898; CHECK-CVT-NEXT:    ret
899;
900; CHECK-FP16-LABEL: utesth_f16i16_mm:
901; CHECK-FP16:       // %bb.0: // %entry
902; CHECK-FP16-NEXT:    fcvtzu v0.8h, v0.8h
903; CHECK-FP16-NEXT:    ret
904entry:
905  %conv = fptoui <8 x half> %x to <8 x i32>
906  %spec.store.select = call <8 x i32> @llvm.umin.v8i32(<8 x i32> %conv, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
907  %conv6 = trunc <8 x i32> %spec.store.select to <8 x i16>
908  ret <8 x i16> %conv6
909}
910
911define <8 x i16> @ustest_f16i16_mm(<8 x half> %x) {
912; CHECK-CVT-LABEL: ustest_f16i16_mm:
913; CHECK-CVT:       // %bb.0: // %entry
914; CHECK-CVT-NEXT:    fcvtl v1.4s, v0.4h
915; CHECK-CVT-NEXT:    fcvtl2 v0.4s, v0.8h
916; CHECK-CVT-NEXT:    fcvtzs v1.4s, v1.4s
917; CHECK-CVT-NEXT:    fcvtzs v2.4s, v0.4s
918; CHECK-CVT-NEXT:    sqxtun v0.4h, v1.4s
919; CHECK-CVT-NEXT:    sqxtun2 v0.8h, v2.4s
920; CHECK-CVT-NEXT:    ret
921;
922; CHECK-FP16-LABEL: ustest_f16i16_mm:
923; CHECK-FP16:       // %bb.0: // %entry
924; CHECK-FP16-NEXT:    fcvtzu v0.8h, v0.8h
925; CHECK-FP16-NEXT:    ret
926entry:
927  %conv = fptosi <8 x half> %x to <8 x i32>
928  %spec.store.select = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> <i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535, i32 65535>)
929  %spec.store.select7 = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %spec.store.select, <8 x i32> zeroinitializer)
930  %conv6 = trunc <8 x i32> %spec.store.select7 to <8 x i16>
931  ret <8 x i16> %conv6
932}
933
934; i64 saturate
935
936define <2 x i64> @stest_f64i64_mm(<2 x double> %x) {
937; CHECK-LABEL: stest_f64i64_mm:
938; CHECK:       // %bb.0: // %entry
939; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
940; CHECK-NEXT:    ret
941entry:
942  %conv = fptosi <2 x double> %x to <2 x i128>
943  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>)
944  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>)
945  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
946  ret <2 x i64> %conv6
947}
948
949define <2 x i64> @utest_f64i64_mm(<2 x double> %x) {
950; CHECK-LABEL: utest_f64i64_mm:
951; CHECK:       // %bb.0: // %entry
952; CHECK-NEXT:    sub sp, sp, #48
953; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
954; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
955; CHECK-NEXT:    .cfi_def_cfa_offset 48
956; CHECK-NEXT:    .cfi_offset w19, -8
957; CHECK-NEXT:    .cfi_offset w20, -16
958; CHECK-NEXT:    .cfi_offset w30, -32
959; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
960; CHECK-NEXT:    mov d0, v0.d[1]
961; CHECK-NEXT:    bl __fixunsdfti
962; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
963; CHECK-NEXT:    mov x19, x0
964; CHECK-NEXT:    mov x20, x1
965; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
966; CHECK-NEXT:    bl __fixunsdfti
967; CHECK-NEXT:    cmp x1, #0
968; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
969; CHECK-NEXT:    csel x8, x0, xzr, eq
970; CHECK-NEXT:    cmp x20, #0
971; CHECK-NEXT:    csel x9, x19, xzr, eq
972; CHECK-NEXT:    fmov d0, x8
973; CHECK-NEXT:    fmov d1, x9
974; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
975; CHECK-NEXT:    mov v0.d[1], v1.d[0]
976; CHECK-NEXT:    add sp, sp, #48
977; CHECK-NEXT:    ret
978entry:
979  %conv = fptoui <2 x double> %x to <2 x i128>
980  %spec.store.select = call <2 x i128> @llvm.umin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
981  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
982  ret <2 x i64> %conv6
983}
984
985define <2 x i64> @ustest_f64i64_mm(<2 x double> %x) {
986; CHECK-LABEL: ustest_f64i64_mm:
987; CHECK:       // %bb.0: // %entry
988; CHECK-NEXT:    sub sp, sp, #48
989; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
990; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
991; CHECK-NEXT:    .cfi_def_cfa_offset 48
992; CHECK-NEXT:    .cfi_offset w19, -8
993; CHECK-NEXT:    .cfi_offset w20, -16
994; CHECK-NEXT:    .cfi_offset w30, -32
995; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
996; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
997; CHECK-NEXT:    bl __fixdfti
998; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
999; CHECK-NEXT:    mov x19, x0
1000; CHECK-NEXT:    mov x20, x1
1001; CHECK-NEXT:    mov d0, v0.d[1]
1002; CHECK-NEXT:    bl __fixdfti
1003; CHECK-NEXT:    cmp x1, #1
1004; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
1005; CHECK-NEXT:    csel x8, x0, xzr, lt
1006; CHECK-NEXT:    csinc x9, x1, xzr, lt
1007; CHECK-NEXT:    cmp x20, #1
1008; CHECK-NEXT:    csinc x10, x20, xzr, lt
1009; CHECK-NEXT:    csel x11, x19, xzr, lt
1010; CHECK-NEXT:    cmp x10, #0
1011; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
1012; CHECK-NEXT:    csel x10, xzr, x11, lt
1013; CHECK-NEXT:    cmp x9, #0
1014; CHECK-NEXT:    csel x8, xzr, x8, lt
1015; CHECK-NEXT:    fmov d0, x10
1016; CHECK-NEXT:    fmov d1, x8
1017; CHECK-NEXT:    mov v0.d[1], v1.d[0]
1018; CHECK-NEXT:    add sp, sp, #48
1019; CHECK-NEXT:    ret
1020entry:
1021  %conv = fptosi <2 x double> %x to <2 x i128>
1022  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
1023  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> zeroinitializer)
1024  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
1025  ret <2 x i64> %conv6
1026}
1027
1028define <2 x i64> @stest_f32i64_mm(<2 x float> %x) {
1029; CHECK-LABEL: stest_f32i64_mm:
1030; CHECK:       // %bb.0: // %entry
1031; CHECK-NEXT:    fcvtl v0.2d, v0.2s
1032; CHECK-NEXT:    fcvtzs v0.2d, v0.2d
1033; CHECK-NEXT:    ret
1034entry:
1035  %conv = fptosi <2 x float> %x to <2 x i128>
1036  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>)
1037  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>)
1038  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
1039  ret <2 x i64> %conv6
1040}
1041
1042define <2 x i64> @utest_f32i64_mm(<2 x float> %x) {
1043; CHECK-LABEL: utest_f32i64_mm:
1044; CHECK:       // %bb.0: // %entry
1045; CHECK-NEXT:    sub sp, sp, #48
1046; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
1047; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
1048; CHECK-NEXT:    .cfi_def_cfa_offset 48
1049; CHECK-NEXT:    .cfi_offset w19, -8
1050; CHECK-NEXT:    .cfi_offset w20, -16
1051; CHECK-NEXT:    .cfi_offset w30, -32
1052; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
1053; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
1054; CHECK-NEXT:    mov s0, v0.s[1]
1055; CHECK-NEXT:    bl __fixunssfti
1056; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
1057; CHECK-NEXT:    mov x19, x0
1058; CHECK-NEXT:    mov x20, x1
1059; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
1060; CHECK-NEXT:    bl __fixunssfti
1061; CHECK-NEXT:    cmp x1, #0
1062; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
1063; CHECK-NEXT:    csel x8, x0, xzr, eq
1064; CHECK-NEXT:    cmp x20, #0
1065; CHECK-NEXT:    csel x9, x19, xzr, eq
1066; CHECK-NEXT:    fmov d0, x8
1067; CHECK-NEXT:    fmov d1, x9
1068; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
1069; CHECK-NEXT:    mov v0.d[1], v1.d[0]
1070; CHECK-NEXT:    add sp, sp, #48
1071; CHECK-NEXT:    ret
1072entry:
1073  %conv = fptoui <2 x float> %x to <2 x i128>
1074  %spec.store.select = call <2 x i128> @llvm.umin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
1075  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
1076  ret <2 x i64> %conv6
1077}
1078
1079define <2 x i64> @ustest_f32i64_mm(<2 x float> %x) {
1080; CHECK-LABEL: ustest_f32i64_mm:
1081; CHECK:       // %bb.0: // %entry
1082; CHECK-NEXT:    sub sp, sp, #48
1083; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
1084; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
1085; CHECK-NEXT:    .cfi_def_cfa_offset 48
1086; CHECK-NEXT:    .cfi_offset w19, -8
1087; CHECK-NEXT:    .cfi_offset w20, -16
1088; CHECK-NEXT:    .cfi_offset w30, -32
1089; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
1090; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
1091; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $q0
1092; CHECK-NEXT:    bl __fixsfti
1093; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
1094; CHECK-NEXT:    mov x19, x0
1095; CHECK-NEXT:    mov x20, x1
1096; CHECK-NEXT:    mov s0, v0.s[1]
1097; CHECK-NEXT:    bl __fixsfti
1098; CHECK-NEXT:    cmp x1, #1
1099; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
1100; CHECK-NEXT:    csel x8, x0, xzr, lt
1101; CHECK-NEXT:    csinc x9, x1, xzr, lt
1102; CHECK-NEXT:    cmp x20, #1
1103; CHECK-NEXT:    csinc x10, x20, xzr, lt
1104; CHECK-NEXT:    csel x11, x19, xzr, lt
1105; CHECK-NEXT:    cmp x10, #0
1106; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
1107; CHECK-NEXT:    csel x10, xzr, x11, lt
1108; CHECK-NEXT:    cmp x9, #0
1109; CHECK-NEXT:    csel x8, xzr, x8, lt
1110; CHECK-NEXT:    fmov d0, x10
1111; CHECK-NEXT:    fmov d1, x8
1112; CHECK-NEXT:    mov v0.d[1], v1.d[0]
1113; CHECK-NEXT:    add sp, sp, #48
1114; CHECK-NEXT:    ret
1115entry:
1116  %conv = fptosi <2 x float> %x to <2 x i128>
1117  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
1118  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> zeroinitializer)
1119  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
1120  ret <2 x i64> %conv6
1121}
1122
1123define <2 x i64> @stest_f16i64_mm(<2 x half> %x) {
1124; CHECK-CVT-LABEL: stest_f16i64_mm:
1125; CHECK-CVT:       // %bb.0: // %entry
1126; CHECK-CVT-NEXT:    // kill: def $d0 killed $d0 def $q0
1127; CHECK-CVT-NEXT:    mov h1, v0.h[1]
1128; CHECK-CVT-NEXT:    fcvt s0, h0
1129; CHECK-CVT-NEXT:    fcvt s1, h1
1130; CHECK-CVT-NEXT:    fcvtzs x8, s0
1131; CHECK-CVT-NEXT:    fcvtzs x9, s1
1132; CHECK-CVT-NEXT:    fmov d0, x8
1133; CHECK-CVT-NEXT:    mov v0.d[1], x9
1134; CHECK-CVT-NEXT:    ret
1135;
1136; CHECK-FP16-LABEL: stest_f16i64_mm:
1137; CHECK-FP16:       // %bb.0: // %entry
1138; CHECK-FP16-NEXT:    // kill: def $d0 killed $d0 def $q0
1139; CHECK-FP16-NEXT:    mov h1, v0.h[1]
1140; CHECK-FP16-NEXT:    fcvtzs x8, h0
1141; CHECK-FP16-NEXT:    fcvtzs x9, h1
1142; CHECK-FP16-NEXT:    fmov d0, x8
1143; CHECK-FP16-NEXT:    mov v0.d[1], x9
1144; CHECK-FP16-NEXT:    ret
1145entry:
1146  %conv = fptosi <2 x half> %x to <2 x i128>
1147  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 9223372036854775807, i128 9223372036854775807>)
1148  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> <i128 -9223372036854775808, i128 -9223372036854775808>)
1149  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
1150  ret <2 x i64> %conv6
1151}
1152
1153define <2 x i64> @utesth_f16i64_mm(<2 x half> %x) {
1154; CHECK-LABEL: utesth_f16i64_mm:
1155; CHECK:       // %bb.0: // %entry
1156; CHECK-NEXT:    sub sp, sp, #48
1157; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
1158; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
1159; CHECK-NEXT:    .cfi_def_cfa_offset 48
1160; CHECK-NEXT:    .cfi_offset w19, -8
1161; CHECK-NEXT:    .cfi_offset w20, -16
1162; CHECK-NEXT:    .cfi_offset w30, -32
1163; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
1164; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
1165; CHECK-NEXT:    mov h0, v0.h[1]
1166; CHECK-NEXT:    bl __fixunshfti
1167; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
1168; CHECK-NEXT:    mov x19, x0
1169; CHECK-NEXT:    mov x20, x1
1170; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $q0
1171; CHECK-NEXT:    bl __fixunshfti
1172; CHECK-NEXT:    cmp x1, #0
1173; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
1174; CHECK-NEXT:    csel x8, x0, xzr, eq
1175; CHECK-NEXT:    cmp x20, #0
1176; CHECK-NEXT:    csel x9, x19, xzr, eq
1177; CHECK-NEXT:    fmov d0, x8
1178; CHECK-NEXT:    fmov d1, x9
1179; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
1180; CHECK-NEXT:    mov v0.d[1], v1.d[0]
1181; CHECK-NEXT:    add sp, sp, #48
1182; CHECK-NEXT:    ret
1183entry:
1184  %conv = fptoui <2 x half> %x to <2 x i128>
1185  %spec.store.select = call <2 x i128> @llvm.umin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
1186  %conv6 = trunc <2 x i128> %spec.store.select to <2 x i64>
1187  ret <2 x i64> %conv6
1188}
1189
1190define <2 x i64> @ustest_f16i64_mm(<2 x half> %x) {
1191; CHECK-LABEL: ustest_f16i64_mm:
1192; CHECK:       // %bb.0: // %entry
1193; CHECK-NEXT:    sub sp, sp, #48
1194; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
1195; CHECK-NEXT:    stp x20, x19, [sp, #32] // 16-byte Folded Spill
1196; CHECK-NEXT:    .cfi_def_cfa_offset 48
1197; CHECK-NEXT:    .cfi_offset w19, -8
1198; CHECK-NEXT:    .cfi_offset w20, -16
1199; CHECK-NEXT:    .cfi_offset w30, -32
1200; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
1201; CHECK-NEXT:    str q0, [sp] // 16-byte Folded Spill
1202; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $q0
1203; CHECK-NEXT:    bl __fixhfti
1204; CHECK-NEXT:    ldr q0, [sp] // 16-byte Folded Reload
1205; CHECK-NEXT:    mov x19, x0
1206; CHECK-NEXT:    mov x20, x1
1207; CHECK-NEXT:    mov h0, v0.h[1]
1208; CHECK-NEXT:    bl __fixhfti
1209; CHECK-NEXT:    cmp x1, #1
1210; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
1211; CHECK-NEXT:    csel x8, x0, xzr, lt
1212; CHECK-NEXT:    csinc x9, x1, xzr, lt
1213; CHECK-NEXT:    cmp x20, #1
1214; CHECK-NEXT:    csinc x10, x20, xzr, lt
1215; CHECK-NEXT:    csel x11, x19, xzr, lt
1216; CHECK-NEXT:    cmp x10, #0
1217; CHECK-NEXT:    ldp x20, x19, [sp, #32] // 16-byte Folded Reload
1218; CHECK-NEXT:    csel x10, xzr, x11, lt
1219; CHECK-NEXT:    cmp x9, #0
1220; CHECK-NEXT:    csel x8, xzr, x8, lt
1221; CHECK-NEXT:    fmov d0, x10
1222; CHECK-NEXT:    fmov d1, x8
1223; CHECK-NEXT:    mov v0.d[1], v1.d[0]
1224; CHECK-NEXT:    add sp, sp, #48
1225; CHECK-NEXT:    ret
1226entry:
1227  %conv = fptosi <2 x half> %x to <2 x i128>
1228  %spec.store.select = call <2 x i128> @llvm.smin.v2i128(<2 x i128> %conv, <2 x i128> <i128 18446744073709551616, i128 18446744073709551616>)
1229  %spec.store.select7 = call <2 x i128> @llvm.smax.v2i128(<2 x i128> %spec.store.select, <2 x i128> zeroinitializer)
1230  %conv6 = trunc <2 x i128> %spec.store.select7 to <2 x i64>
1231  ret <2 x i64> %conv6
1232}
1233
1234declare <2 x i32> @llvm.smin.v2i32(<2 x i32>, <2 x i32>)
1235declare <2 x i32> @llvm.smax.v2i32(<2 x i32>, <2 x i32>)
1236declare <2 x i32> @llvm.umin.v2i32(<2 x i32>, <2 x i32>)
1237declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)
1238declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)
1239declare <4 x i32> @llvm.umin.v4i32(<4 x i32>, <4 x i32>)
1240declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)
1241declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)
1242declare <8 x i32> @llvm.umin.v8i32(<8 x i32>, <8 x i32>)
1243declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)
1244declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)
1245declare <2 x i64> @llvm.umin.v2i64(<2 x i64>, <2 x i64>)
1246declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)
1247declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)
1248declare <4 x i64> @llvm.umin.v4i64(<4 x i64>, <4 x i64>)
1249declare <2 x i128> @llvm.smin.v2i128(<2 x i128>, <2 x i128>)
1250declare <2 x i128> @llvm.smax.v2i128(<2 x i128>, <2 x i128>)
1251declare <2 x i128> @llvm.umin.v2i128(<2 x i128>, <2 x i128>)
1252