• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -O0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs -mtriple=arm64-apple-darwin -mcpu=cyclone < %s | FileCheck %s
2
3;; Test various conversions.
4define zeroext i32 @trunc_(i8 zeroext %a, i16 zeroext %b, i32 %c, i64 %d) nounwind ssp {
5entry:
6; CHECK-LABEL: trunc_
7; CHECK: sub sp, sp, #16
8; CHECK: strb w0, [sp, #15]
9; CHECK: strh w1, [sp, #12]
10; CHECK: str w2, [sp, #8]
11; CHECK: str x3, [sp]
12; CHECK: ldr x3, [sp]
13; CHECK: mov x0, x3
14; CHECK: str w0, [sp, #8]
15; CHECK: ldr w0, [sp, #8]
16; CHECK: strh w0, [sp, #12]
17; CHECK: ldrh w0, [sp, #12]
18; CHECK: strb w0, [sp, #15]
19; CHECK: ldrb w0, [sp, #15]
20; CHECK: add sp, sp, #16
21; CHECK: ret
22  %a.addr = alloca i8, align 1
23  %b.addr = alloca i16, align 2
24  %c.addr = alloca i32, align 4
25  %d.addr = alloca i64, align 8
26  store i8 %a, i8* %a.addr, align 1
27  store i16 %b, i16* %b.addr, align 2
28  store i32 %c, i32* %c.addr, align 4
29  store i64 %d, i64* %d.addr, align 8
30  %tmp = load i64, i64* %d.addr, align 8
31  %conv = trunc i64 %tmp to i32
32  store i32 %conv, i32* %c.addr, align 4
33  %tmp1 = load i32, i32* %c.addr, align 4
34  %conv2 = trunc i32 %tmp1 to i16
35  store i16 %conv2, i16* %b.addr, align 2
36  %tmp3 = load i16, i16* %b.addr, align 2
37  %conv4 = trunc i16 %tmp3 to i8
38  store i8 %conv4, i8* %a.addr, align 1
39  %tmp5 = load i8, i8* %a.addr, align 1
40  %conv6 = zext i8 %tmp5 to i32
41  ret i32 %conv6
42}
43
44define i64 @zext_(i8 zeroext %a, i16 zeroext %b, i32 %c, i64 %d) nounwind ssp {
45entry:
46; CHECK-LABEL: zext_
47; CHECK: sub sp, sp, #16
48; CHECK: strb w0, [sp, #15]
49; CHECK: strh w1, [sp, #12]
50; CHECK: str w2, [sp, #8]
51; CHECK: str x3, [sp]
52; CHECK: ldrb w0, [sp, #15]
53; CHECK: strh w0, [sp, #12]
54; CHECK: ldrh w0, [sp, #12]
55; CHECK: str w0, [sp, #8]
56; CHECK: ldr w0, [sp, #8]
57; CHECK: mov x3, x0
58; CHECK: str x3, [sp]
59; CHECK: ldr x0, [sp]
60; CHECK: ret
61  %a.addr = alloca i8, align 1
62  %b.addr = alloca i16, align 2
63  %c.addr = alloca i32, align 4
64  %d.addr = alloca i64, align 8
65  store i8 %a, i8* %a.addr, align 1
66  store i16 %b, i16* %b.addr, align 2
67  store i32 %c, i32* %c.addr, align 4
68  store i64 %d, i64* %d.addr, align 8
69  %tmp = load i8, i8* %a.addr, align 1
70  %conv = zext i8 %tmp to i16
71  store i16 %conv, i16* %b.addr, align 2
72  %tmp1 = load i16, i16* %b.addr, align 2
73  %conv2 = zext i16 %tmp1 to i32
74  store i32 %conv2, i32* %c.addr, align 4
75  %tmp3 = load i32, i32* %c.addr, align 4
76  %conv4 = zext i32 %tmp3 to i64
77  store i64 %conv4, i64* %d.addr, align 8
78  %tmp5 = load i64, i64* %d.addr, align 8
79  ret i64 %tmp5
80}
81
82define i32 @zext_i1_i32(i1 zeroext %a) nounwind ssp {
83entry:
84; CHECK-LABEL: zext_i1_i32
85; CHECK-NOT:   and w0, w0, #0x1
86; CHECK:       ret
87  %conv = zext i1 %a to i32
88  ret i32 %conv;
89}
90
91define i64 @zext_i1_i64(i1 zeroext %a) nounwind ssp {
92entry:
93; CHECK-LABEL: zext_i1_i64
94; CHECK-NOT:   and w0, w0, #0x1
95; CHECK:       ret
96  %conv = zext i1 %a to i64
97  ret i64 %conv;
98}
99
100define i64 @sext_(i8 signext %a, i16 signext %b, i32 %c, i64 %d) nounwind ssp {
101entry:
102; CHECK-LABEL: sext_
103; CHECK: sub sp, sp, #16
104; CHECK: strb w0, [sp, #15]
105; CHECK: strh w1, [sp, #12]
106; CHECK: str w2, [sp, #8]
107; CHECK: str x3, [sp]
108; CHECK: ldrsb w0, [sp, #15]
109; CHECK: strh w0, [sp, #12]
110; CHECK: ldrsh w0, [sp, #12]
111; CHECK: str w0, [sp, #8]
112; CHECK: ldrsw x3, [sp, #8]
113; CHECK: str x3, [sp]
114; CHECK: ldr x0, [sp]
115; CHECK: ret
116  %a.addr = alloca i8, align 1
117  %b.addr = alloca i16, align 2
118  %c.addr = alloca i32, align 4
119  %d.addr = alloca i64, align 8
120  store i8 %a, i8* %a.addr, align 1
121  store i16 %b, i16* %b.addr, align 2
122  store i32 %c, i32* %c.addr, align 4
123  store i64 %d, i64* %d.addr, align 8
124  %tmp = load i8, i8* %a.addr, align 1
125  %conv = sext i8 %tmp to i16
126  store i16 %conv, i16* %b.addr, align 2
127  %tmp1 = load i16, i16* %b.addr, align 2
128  %conv2 = sext i16 %tmp1 to i32
129  store i32 %conv2, i32* %c.addr, align 4
130  %tmp3 = load i32, i32* %c.addr, align 4
131  %conv4 = sext i32 %tmp3 to i64
132  store i64 %conv4, i64* %d.addr, align 8
133  %tmp5 = load i64, i64* %d.addr, align 8
134  ret i64 %tmp5
135}
136
137; Test sext i8 to i64
138
139define zeroext i64 @sext_i8_i64(i8 zeroext %in) {
140; CHECK-LABEL: sext_i8_i64:
141; CHECK: mov x[[TMP:[0-9]+]], x0
142; CHECK: sxtb x0, w[[TMP]]
143  %big = sext i8 %in to i64
144  ret i64 %big
145}
146
147define zeroext i64 @sext_i16_i64(i16 zeroext %in) {
148; CHECK-LABEL: sext_i16_i64:
149; CHECK: mov x[[TMP:[0-9]+]], x0
150; CHECK: sxth x0, w[[TMP]]
151  %big = sext i16 %in to i64
152  ret i64 %big
153}
154
155; Test sext i1 to i32
156define i32 @sext_i1_i32(i1 signext %a) nounwind ssp {
157entry:
158; CHECK-LABEL: sext_i1_i32
159; CHECK-NOT:   sbfx w0, w0, #0, #1
160; CHECK:       ret
161  %conv = sext i1 %a to i32
162  ret i32 %conv
163}
164
165; Test sext i1 to i16
166define signext i16 @sext_i1_i16(i1 %a) nounwind ssp {
167entry:
168; CHECK-LABEL: sext_i1_i16
169; CHECK: sbfx w0, w0, #0, #1
170  %conv = sext i1 %a to i16
171  ret i16 %conv
172}
173
174; Test sext i1 to i8
175define signext i8 @sext_i1_i8(i1 %a) nounwind ssp {
176entry:
177; CHECK-LABEL: sext_i1_i8
178; CHECK: sbfx w0, w0, #0, #1
179  %conv = sext i1 %a to i8
180  ret i8 %conv
181}
182
183; Test fpext
184define double @fpext_(float %a) nounwind ssp {
185entry:
186; CHECK-LABEL: fpext_
187; CHECK: fcvt d0, s0
188  %conv = fpext float %a to double
189  ret double %conv
190}
191
192; Test fptrunc
193define float @fptrunc_(double %a) nounwind ssp {
194entry:
195; CHECK-LABEL: fptrunc_
196; CHECK: fcvt s0, d0
197  %conv = fptrunc double %a to float
198  ret float %conv
199}
200
201; Test fptosi
202define i32 @fptosi_ws(float %a) nounwind ssp {
203entry:
204; CHECK-LABEL: fptosi_ws
205; CHECK: fcvtzs w0, s0
206  %conv = fptosi float %a to i32
207  ret i32 %conv
208}
209
210; Test fptosi
211define i32 @fptosi_wd(double %a) nounwind ssp {
212entry:
213; CHECK-LABEL: fptosi_wd
214; CHECK: fcvtzs w0, d0
215  %conv = fptosi double %a to i32
216  ret i32 %conv
217}
218
219; Test fptoui
220define i32 @fptoui_ws(float %a) nounwind ssp {
221entry:
222; CHECK-LABEL: fptoui_ws
223; CHECK: fcvtzu w0, s0
224  %conv = fptoui float %a to i32
225  ret i32 %conv
226}
227
228; Test fptoui
229define i32 @fptoui_wd(double %a) nounwind ssp {
230entry:
231; CHECK-LABEL: fptoui_wd
232; CHECK: fcvtzu w0, d0
233  %conv = fptoui double %a to i32
234  ret i32 %conv
235}
236
237; Test sitofp
238define float @sitofp_sw_i1(i1 %a) nounwind ssp {
239entry:
240; CHECK-LABEL: sitofp_sw_i1
241; CHECK: sbfx w0, w0, #0, #1
242; CHECK: scvtf s0, w0
243  %conv = sitofp i1 %a to float
244  ret float %conv
245}
246
247; Test sitofp
248define float @sitofp_sw_i8(i8 %a) nounwind ssp {
249entry:
250; CHECK-LABEL: sitofp_sw_i8
251; CHECK: sxtb w0, w0
252; CHECK: scvtf s0, w0
253  %conv = sitofp i8 %a to float
254  ret float %conv
255}
256
257; Test sitofp
258define float @sitofp_sw_i16(i16 %a) nounwind ssp {
259entry:
260; CHECK-LABEL: sitofp_sw_i16
261  %conv = sitofp i16 %a to float
262  ret float %conv
263}
264
265; Test sitofp
266define float @sitofp_sw(i32 %a) nounwind ssp {
267entry:
268; CHECK-LABEL: sitofp_sw
269; CHECK: scvtf s0, w0
270  %conv = sitofp i32 %a to float
271  ret float %conv
272}
273
274; Test sitofp
275define float @sitofp_sx(i64 %a) nounwind ssp {
276entry:
277; CHECK-LABEL: sitofp_sx
278; CHECK: scvtf s0, x0
279  %conv = sitofp i64 %a to float
280  ret float %conv
281}
282
283; Test sitofp
284define double @sitofp_dw(i32 %a) nounwind ssp {
285entry:
286; CHECK-LABEL: sitofp_dw
287; CHECK: scvtf d0, w0
288  %conv = sitofp i32 %a to double
289  ret double %conv
290}
291
292; Test sitofp
293define double @sitofp_dx(i64 %a) nounwind ssp {
294entry:
295; CHECK-LABEL: sitofp_dx
296; CHECK: scvtf d0, x0
297  %conv = sitofp i64 %a to double
298  ret double %conv
299}
300
301; Test uitofp
302define float @uitofp_sw_i1(i1 %a) nounwind ssp {
303entry:
304; CHECK-LABEL: uitofp_sw_i1
305; CHECK: and w0, w0, #0x1
306; CHECK: ucvtf s0, w0
307  %conv = uitofp i1 %a to float
308  ret float %conv
309}
310
311; Test uitofp
312define float @uitofp_sw_i8(i8 %a) nounwind ssp {
313entry:
314; CHECK-LABEL: uitofp_sw_i8
315  %conv = uitofp i8 %a to float
316  ret float %conv
317}
318
319; Test uitofp
320define float @uitofp_sw_i16(i16 %a) nounwind ssp {
321entry:
322; CHECK-LABEL: uitofp_sw_i16
323  %conv = uitofp i16 %a to float
324  ret float %conv
325}
326
327; Test uitofp
328define float @uitofp_sw(i32 %a) nounwind ssp {
329entry:
330; CHECK-LABEL: uitofp_sw
331; CHECK: ucvtf s0, w0
332  %conv = uitofp i32 %a to float
333  ret float %conv
334}
335
336; Test uitofp
337define float @uitofp_sx(i64 %a) nounwind ssp {
338entry:
339; CHECK-LABEL: uitofp_sx
340; CHECK: ucvtf s0, x0
341  %conv = uitofp i64 %a to float
342  ret float %conv
343}
344
345; Test uitofp
346define double @uitofp_dw(i32 %a) nounwind ssp {
347entry:
348; CHECK-LABEL: uitofp_dw
349; CHECK: ucvtf d0, w0
350  %conv = uitofp i32 %a to double
351  ret double %conv
352}
353
354; Test uitofp
355define double @uitofp_dx(i64 %a) nounwind ssp {
356entry:
357; CHECK-LABEL: uitofp_dx
358; CHECK: ucvtf d0, x0
359  %conv = uitofp i64 %a to double
360  ret double %conv
361}
362
363define i32 @i64_trunc_i32(i64 %a) nounwind ssp {
364entry:
365; CHECK-LABEL: i64_trunc_i32
366; CHECK: mov x1, x0
367  %conv = trunc i64 %a to i32
368  ret i32 %conv
369}
370
371define zeroext i16 @i64_trunc_i16(i64 %a) nounwind ssp {
372entry:
373; CHECK-LABEL: i64_trunc_i16
374; CHECK: mov x[[REG:[0-9]+]], x0
375; CHECK: and [[REG2:w[0-9]+]], w[[REG]], #0xffff
376; CHECK: uxth w0, [[REG2]]
377  %conv = trunc i64 %a to i16
378  ret i16 %conv
379}
380
381define zeroext i8 @i64_trunc_i8(i64 %a) nounwind ssp {
382entry:
383; CHECK-LABEL: i64_trunc_i8
384; CHECK: mov x[[REG:[0-9]+]], x0
385; CHECK: and [[REG2:w[0-9]+]], w[[REG]], #0xff
386; CHECK: uxtb w0, [[REG2]]
387  %conv = trunc i64 %a to i8
388  ret i8 %conv
389}
390
391define zeroext i1 @i64_trunc_i1(i64 %a) nounwind ssp {
392entry:
393; CHECK-LABEL: i64_trunc_i1
394; CHECK: mov x[[REG:[0-9]+]], x0
395; CHECK: and [[REG2:w[0-9]+]], w[[REG]], #0x1
396; CHECK: and w0, [[REG2]], #0x1
397  %conv = trunc i64 %a to i1
398  ret i1 %conv
399}
400
401; rdar://15101939
402define void @stack_trunc() nounwind {
403; CHECK-LABEL: stack_trunc
404; CHECK: sub  sp, sp, #16
405; CHECK: ldr  [[REG:x[0-9]+]], [sp]
406; CHECK: mov  x[[REG2:[0-9]+]], [[REG]]
407; CHECK: and  [[REG3:w[0-9]+]], w[[REG2]], #0xff
408; CHECK: strb [[REG3]], [sp, #15]
409; CHECK: add  sp, sp, #16
410  %a = alloca i8, align 1
411  %b = alloca i64, align 8
412  %c = load i64, i64* %b, align 8
413  %d = trunc i64 %c to i8
414  store i8 %d, i8* %a, align 1
415  ret void
416}
417
418define zeroext i64 @zext_i8_i64(i8 zeroext %in) {
419; CHECK-LABEL: zext_i8_i64:
420; CHECK-NOT:   ubfx x0, {{x[0-9]+}}, #0, #8
421; CHECK:       ret
422  %big = zext i8 %in to i64
423  ret i64 %big
424}
425define zeroext i64 @zext_i16_i64(i16 zeroext %in) {
426; CHECK-LABEL: zext_i16_i64:
427; CHECK-NOT:   ubfx x0, {{x[0-9]+}}, #0, #16
428; CHECK:       ret
429  %big = zext i16 %in to i64
430  ret i64 %big
431}
432
433define float @bitcast_i32_to_float(i32 %a) {
434  %1 = bitcast i32 %a to float
435  ret float %1
436}
437
438define double @bitcast_i64_to_double(i64 %a) {
439  %1 = bitcast i64 %a to double
440  ret double %1
441}
442
443define i32 @bitcast_float_to_i32(float %a) {
444  %1 = bitcast float %a to i32
445  ret i32 %1
446}
447
448define i64 @bitcast_double_to_i64(double %a) {
449  %1 = bitcast double %a to i64
450  ret i64 %1
451}
452
453