1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=-f16c -fixup-byte-word-insts=1 \
3; RUN:   | FileCheck %s -check-prefixes=CHECK,CHECK-LIBCALL,BWON
4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=-f16c  -fixup-byte-word-insts=0 \
5; RUN:   | FileCheck %s -check-prefixes=CHECK,CHECK-LIBCALL,BWOFF
6; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+f16c -fixup-byte-word-insts=1 \
7; RUN:    | FileCheck %s -check-prefixes=CHECK,BWON,BWON-F16C
8; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr +sse2 -fixup-byte-word-insts=0  \
9; RUN:    | FileCheck %s -check-prefixes=CHECK-I686
10
11define void @test_load_store(ptr %in, ptr %out) #0 {
12; CHECK-LIBCALL-LABEL: test_load_store:
13; CHECK-LIBCALL:       # %bb.0:
14; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
15; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
16; CHECK-LIBCALL-NEXT:    movw %ax, (%rsi)
17; CHECK-LIBCALL-NEXT:    retq
18;
19; BWON-F16C-LABEL: test_load_store:
20; BWON-F16C:       # %bb.0:
21; BWON-F16C-NEXT:    vpinsrw $0, (%rdi), %xmm0, %xmm0
22; BWON-F16C-NEXT:    vpextrw $0, %xmm0, (%rsi)
23; BWON-F16C-NEXT:    retq
24;
25; CHECK-I686-LABEL: test_load_store:
26; CHECK-I686:       # %bb.0:
27; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
28; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %ecx
29; CHECK-I686-NEXT:    pinsrw $0, (%ecx), %xmm0
30; CHECK-I686-NEXT:    pextrw $0, %xmm0, %ecx
31; CHECK-I686-NEXT:    movw %cx, (%eax)
32; CHECK-I686-NEXT:    retl
33  %val = load half, ptr %in
34  store half %val, ptr %out
35  ret void
36}
37
38define i16 @test_bitcast_from_half(ptr %addr) #0 {
39; BWON-LABEL: test_bitcast_from_half:
40; BWON:       # %bb.0:
41; BWON-NEXT:    movzwl (%rdi), %eax
42; BWON-NEXT:    retq
43;
44; BWOFF-LABEL: test_bitcast_from_half:
45; BWOFF:       # %bb.0:
46; BWOFF-NEXT:    movw (%rdi), %ax
47; BWOFF-NEXT:    retq
48;
49; CHECK-I686-LABEL: test_bitcast_from_half:
50; CHECK-I686:       # %bb.0:
51; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
52; CHECK-I686-NEXT:    movw (%eax), %ax
53; CHECK-I686-NEXT:    retl
54  %val = load half, ptr %addr
55  %val_int = bitcast half %val to i16
56  ret i16 %val_int
57}
58
59define void @test_bitcast_to_half(ptr %addr, i16 %in) #0 {
60; CHECK-LABEL: test_bitcast_to_half:
61; CHECK:       # %bb.0:
62; CHECK-NEXT:    movw %si, (%rdi)
63; CHECK-NEXT:    retq
64;
65; CHECK-I686-LABEL: test_bitcast_to_half:
66; CHECK-I686:       # %bb.0:
67; CHECK-I686-NEXT:    movw {{[0-9]+}}(%esp), %ax
68; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %ecx
69; CHECK-I686-NEXT:    movw %ax, (%ecx)
70; CHECK-I686-NEXT:    retl
71  %val_fp = bitcast i16 %in to half
72  store half %val_fp, ptr %addr
73  ret void
74}
75
76define float @test_extend32(ptr %addr) #0 {
77; CHECK-LIBCALL-LABEL: test_extend32:
78; CHECK-LIBCALL:       # %bb.0:
79; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
80; CHECK-LIBCALL-NEXT:    jmp __extendhfsf2@PLT # TAILCALL
81;
82; BWON-F16C-LABEL: test_extend32:
83; BWON-F16C:       # %bb.0:
84; BWON-F16C-NEXT:    movzwl (%rdi), %eax
85; BWON-F16C-NEXT:    vmovd %eax, %xmm0
86; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
87; BWON-F16C-NEXT:    retq
88;
89; CHECK-I686-LABEL: test_extend32:
90; CHECK-I686:       # %bb.0:
91; CHECK-I686-NEXT:    subl $12, %esp
92; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
93; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
94; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
95; CHECK-I686-NEXT:    movw %ax, (%esp)
96; CHECK-I686-NEXT:    calll __extendhfsf2
97; CHECK-I686-NEXT:    addl $12, %esp
98; CHECK-I686-NEXT:    retl
99  %val16 = load half, ptr %addr
100  %val32 = fpext half %val16 to float
101  ret float %val32
102}
103
104define double @test_extend64(ptr %addr) #0 {
105; CHECK-LIBCALL-LABEL: test_extend64:
106; CHECK-LIBCALL:       # %bb.0:
107; CHECK-LIBCALL-NEXT:    pushq %rax
108; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
109; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
110; CHECK-LIBCALL-NEXT:    cvtss2sd %xmm0, %xmm0
111; CHECK-LIBCALL-NEXT:    popq %rax
112; CHECK-LIBCALL-NEXT:    retq
113;
114; BWON-F16C-LABEL: test_extend64:
115; BWON-F16C:       # %bb.0:
116; BWON-F16C-NEXT:    movzwl (%rdi), %eax
117; BWON-F16C-NEXT:    vmovd %eax, %xmm0
118; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
119; BWON-F16C-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
120; BWON-F16C-NEXT:    retq
121;
122; CHECK-I686-LABEL: test_extend64:
123; CHECK-I686:       # %bb.0:
124; CHECK-I686-NEXT:    subl $12, %esp
125; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
126; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
127; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
128; CHECK-I686-NEXT:    movw %ax, (%esp)
129; CHECK-I686-NEXT:    calll __extendhfsf2
130; CHECK-I686-NEXT:    addl $12, %esp
131; CHECK-I686-NEXT:    retl
132  %val16 = load half, ptr %addr
133  %val32 = fpext half %val16 to double
134  ret double %val32
135}
136
137define void @test_trunc32(float %in, ptr %addr) #0 {
138; CHECK-LIBCALL-LABEL: test_trunc32:
139; CHECK-LIBCALL:       # %bb.0:
140; CHECK-LIBCALL-NEXT:    pushq %rbx
141; CHECK-LIBCALL-NEXT:    movq %rdi, %rbx
142; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
143; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
144; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
145; CHECK-LIBCALL-NEXT:    popq %rbx
146; CHECK-LIBCALL-NEXT:    retq
147;
148; BWON-F16C-LABEL: test_trunc32:
149; BWON-F16C:       # %bb.0:
150; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
151; BWON-F16C-NEXT:    vmovd %xmm0, %eax
152; BWON-F16C-NEXT:    movw %ax, (%rdi)
153; BWON-F16C-NEXT:    retq
154;
155; CHECK-I686-LABEL: test_trunc32:
156; CHECK-I686:       # %bb.0:
157; CHECK-I686-NEXT:    pushl %esi
158; CHECK-I686-NEXT:    subl $8, %esp
159; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
160; CHECK-I686-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
161; CHECK-I686-NEXT:    movd %xmm0, (%esp)
162; CHECK-I686-NEXT:    calll __truncsfhf2
163; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
164; CHECK-I686-NEXT:    movw %ax, (%esi)
165; CHECK-I686-NEXT:    addl $8, %esp
166; CHECK-I686-NEXT:    popl %esi
167; CHECK-I686-NEXT:    retl
168  %val16 = fptrunc float %in to half
169  store half %val16, ptr %addr
170  ret void
171}
172
173define void @test_trunc64(double %in, ptr %addr) #0 {
174; CHECK-LIBCALL-LABEL: test_trunc64:
175; CHECK-LIBCALL:       # %bb.0:
176; CHECK-LIBCALL-NEXT:    pushq %rbx
177; CHECK-LIBCALL-NEXT:    movq %rdi, %rbx
178; CHECK-LIBCALL-NEXT:    callq __truncdfhf2@PLT
179; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
180; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
181; CHECK-LIBCALL-NEXT:    popq %rbx
182; CHECK-LIBCALL-NEXT:    retq
183;
184; BWON-F16C-LABEL: test_trunc64:
185; BWON-F16C:       # %bb.0:
186; BWON-F16C-NEXT:    pushq %rbx
187; BWON-F16C-NEXT:    movq %rdi, %rbx
188; BWON-F16C-NEXT:    callq __truncdfhf2@PLT
189; BWON-F16C-NEXT:    vpextrw $0, %xmm0, (%rbx)
190; BWON-F16C-NEXT:    popq %rbx
191; BWON-F16C-NEXT:    retq
192;
193; CHECK-I686-LABEL: test_trunc64:
194; CHECK-I686:       # %bb.0:
195; CHECK-I686-NEXT:    pushl %esi
196; CHECK-I686-NEXT:    subl $8, %esp
197; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
198; CHECK-I686-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
199; CHECK-I686-NEXT:    movq %xmm0, (%esp)
200; CHECK-I686-NEXT:    calll __truncdfhf2
201; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
202; CHECK-I686-NEXT:    movw %ax, (%esi)
203; CHECK-I686-NEXT:    addl $8, %esp
204; CHECK-I686-NEXT:    popl %esi
205; CHECK-I686-NEXT:    retl
206  %val16 = fptrunc double %in to half
207  store half %val16, ptr %addr
208  ret void
209}
210
211define i64 @test_fptosi_i64(ptr %p) #0 {
212; CHECK-LIBCALL-LABEL: test_fptosi_i64:
213; CHECK-LIBCALL:       # %bb.0:
214; CHECK-LIBCALL-NEXT:    pushq %rax
215; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
216; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
217; CHECK-LIBCALL-NEXT:    cvttss2si %xmm0, %rax
218; CHECK-LIBCALL-NEXT:    popq %rcx
219; CHECK-LIBCALL-NEXT:    retq
220;
221; BWON-F16C-LABEL: test_fptosi_i64:
222; BWON-F16C:       # %bb.0:
223; BWON-F16C-NEXT:    movzwl (%rdi), %eax
224; BWON-F16C-NEXT:    vmovd %eax, %xmm0
225; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
226; BWON-F16C-NEXT:    vcvttss2si %xmm0, %rax
227; BWON-F16C-NEXT:    retq
228;
229; CHECK-I686-LABEL: test_fptosi_i64:
230; CHECK-I686:       # %bb.0:
231; CHECK-I686-NEXT:    subl $12, %esp
232; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
233; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
234; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
235; CHECK-I686-NEXT:    movw %ax, (%esp)
236; CHECK-I686-NEXT:    calll __fixhfdi
237; CHECK-I686-NEXT:    addl $12, %esp
238; CHECK-I686-NEXT:    retl
239  %a = load half, ptr %p, align 2
240  %r = fptosi half %a to i64
241  ret i64 %r
242}
243
244define void @test_sitofp_i64(i64 %a, ptr %p) #0 {
245; CHECK-LIBCALL-LABEL: test_sitofp_i64:
246; CHECK-LIBCALL:       # %bb.0:
247; CHECK-LIBCALL-NEXT:    pushq %rbx
248; CHECK-LIBCALL-NEXT:    movq %rsi, %rbx
249; CHECK-LIBCALL-NEXT:    cvtsi2ss %rdi, %xmm0
250; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
251; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
252; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
253; CHECK-LIBCALL-NEXT:    popq %rbx
254; CHECK-LIBCALL-NEXT:    retq
255;
256; BWON-F16C-LABEL: test_sitofp_i64:
257; BWON-F16C:       # %bb.0:
258; BWON-F16C-NEXT:    vcvtsi2ss %rdi, %xmm0, %xmm0
259; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
260; BWON-F16C-NEXT:    vmovd %xmm0, %eax
261; BWON-F16C-NEXT:    movw %ax, (%rsi)
262; BWON-F16C-NEXT:    retq
263;
264; CHECK-I686-LABEL: test_sitofp_i64:
265; CHECK-I686:       # %bb.0:
266; CHECK-I686-NEXT:    pushl %esi
267; CHECK-I686-NEXT:    subl $24, %esp
268; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
269; CHECK-I686-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
270; CHECK-I686-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
271; CHECK-I686-NEXT:    fildll {{[0-9]+}}(%esp)
272; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
273; CHECK-I686-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
274; CHECK-I686-NEXT:    movd %xmm0, (%esp)
275; CHECK-I686-NEXT:    calll __truncsfhf2
276; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
277; CHECK-I686-NEXT:    movw %ax, (%esi)
278; CHECK-I686-NEXT:    addl $24, %esp
279; CHECK-I686-NEXT:    popl %esi
280; CHECK-I686-NEXT:    retl
281  %r = sitofp i64 %a to half
282  store half %r, ptr %p
283  ret void
284}
285
286define i64 @test_fptoui_i64(ptr %p) #0 {
287; CHECK-LIBCALL-LABEL: test_fptoui_i64:
288; CHECK-LIBCALL:       # %bb.0:
289; CHECK-LIBCALL-NEXT:    pushq %rax
290; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
291; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
292; CHECK-LIBCALL-NEXT:    cvttss2si %xmm0, %rcx
293; CHECK-LIBCALL-NEXT:    movq %rcx, %rdx
294; CHECK-LIBCALL-NEXT:    sarq $63, %rdx
295; CHECK-LIBCALL-NEXT:    subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
296; CHECK-LIBCALL-NEXT:    cvttss2si %xmm0, %rax
297; CHECK-LIBCALL-NEXT:    andq %rdx, %rax
298; CHECK-LIBCALL-NEXT:    orq %rcx, %rax
299; CHECK-LIBCALL-NEXT:    popq %rcx
300; CHECK-LIBCALL-NEXT:    retq
301;
302; BWON-F16C-LABEL: test_fptoui_i64:
303; BWON-F16C:       # %bb.0:
304; BWON-F16C-NEXT:    movzwl (%rdi), %eax
305; BWON-F16C-NEXT:    vmovd %eax, %xmm0
306; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
307; BWON-F16C-NEXT:    vcvttss2si %xmm0, %rcx
308; BWON-F16C-NEXT:    movq %rcx, %rdx
309; BWON-F16C-NEXT:    sarq $63, %rdx
310; BWON-F16C-NEXT:    vsubss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
311; BWON-F16C-NEXT:    vcvttss2si %xmm0, %rax
312; BWON-F16C-NEXT:    andq %rdx, %rax
313; BWON-F16C-NEXT:    orq %rcx, %rax
314; BWON-F16C-NEXT:    retq
315;
316; CHECK-I686-LABEL: test_fptoui_i64:
317; CHECK-I686:       # %bb.0:
318; CHECK-I686-NEXT:    subl $12, %esp
319; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
320; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
321; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
322; CHECK-I686-NEXT:    movw %ax, (%esp)
323; CHECK-I686-NEXT:    calll __fixunshfdi
324; CHECK-I686-NEXT:    addl $12, %esp
325; CHECK-I686-NEXT:    retl
326  %a = load half, ptr %p, align 2
327  %r = fptoui half %a to i64
328  ret i64 %r
329}
330
331define void @test_uitofp_i64(i64 %a, ptr %p) #0 {
332; CHECK-LIBCALL-LABEL: test_uitofp_i64:
333; CHECK-LIBCALL:       # %bb.0:
334; CHECK-LIBCALL-NEXT:    pushq %rbx
335; CHECK-LIBCALL-NEXT:    movq %rsi, %rbx
336; CHECK-LIBCALL-NEXT:    testq %rdi, %rdi
337; CHECK-LIBCALL-NEXT:    js .LBB10_1
338; CHECK-LIBCALL-NEXT:  # %bb.2:
339; CHECK-LIBCALL-NEXT:    cvtsi2ss %rdi, %xmm0
340; CHECK-LIBCALL-NEXT:    jmp .LBB10_3
341; CHECK-LIBCALL-NEXT:  .LBB10_1:
342; CHECK-LIBCALL-NEXT:    movq %rdi, %rax
343; CHECK-LIBCALL-NEXT:    shrq %rax
344; CHECK-LIBCALL-NEXT:    andl $1, %edi
345; CHECK-LIBCALL-NEXT:    orq %rax, %rdi
346; CHECK-LIBCALL-NEXT:    cvtsi2ss %rdi, %xmm0
347; CHECK-LIBCALL-NEXT:    addss %xmm0, %xmm0
348; CHECK-LIBCALL-NEXT:  .LBB10_3:
349; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
350; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
351; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
352; CHECK-LIBCALL-NEXT:    popq %rbx
353; CHECK-LIBCALL-NEXT:    retq
354;
355; BWON-F16C-LABEL: test_uitofp_i64:
356; BWON-F16C:       # %bb.0:
357; BWON-F16C-NEXT:    testq %rdi, %rdi
358; BWON-F16C-NEXT:    js .LBB10_1
359; BWON-F16C-NEXT:  # %bb.2:
360; BWON-F16C-NEXT:    vcvtsi2ss %rdi, %xmm0, %xmm0
361; BWON-F16C-NEXT:    jmp .LBB10_3
362; BWON-F16C-NEXT:  .LBB10_1:
363; BWON-F16C-NEXT:    movq %rdi, %rax
364; BWON-F16C-NEXT:    shrq %rax
365; BWON-F16C-NEXT:    andl $1, %edi
366; BWON-F16C-NEXT:    orq %rax, %rdi
367; BWON-F16C-NEXT:    vcvtsi2ss %rdi, %xmm0, %xmm0
368; BWON-F16C-NEXT:    vaddss %xmm0, %xmm0, %xmm0
369; BWON-F16C-NEXT:  .LBB10_3:
370; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
371; BWON-F16C-NEXT:    vmovd %xmm0, %eax
372; BWON-F16C-NEXT:    movw %ax, (%rsi)
373; BWON-F16C-NEXT:    retq
374;
375; CHECK-I686-LABEL: test_uitofp_i64:
376; CHECK-I686:       # %bb.0:
377; CHECK-I686-NEXT:    pushl %esi
378; CHECK-I686-NEXT:    subl $24, %esp
379; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
380; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
381; CHECK-I686-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero
382; CHECK-I686-NEXT:    movq %xmm0, {{[0-9]+}}(%esp)
383; CHECK-I686-NEXT:    shrl $31, %eax
384; CHECK-I686-NEXT:    fildll {{[0-9]+}}(%esp)
385; CHECK-I686-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
386; CHECK-I686-NEXT:    fstps (%esp)
387; CHECK-I686-NEXT:    calll __truncsfhf2
388; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
389; CHECK-I686-NEXT:    movw %ax, (%esi)
390; CHECK-I686-NEXT:    addl $24, %esp
391; CHECK-I686-NEXT:    popl %esi
392; CHECK-I686-NEXT:    retl
393  %r = uitofp i64 %a to half
394  store half %r, ptr %p
395  ret void
396}
397
398define <4 x float> @test_extend32_vec4(ptr %p) #0 {
399; CHECK-LIBCALL-LABEL: test_extend32_vec4:
400; CHECK-LIBCALL:       # %bb.0:
401; CHECK-LIBCALL-NEXT:    subq $72, %rsp
402; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
403; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
404; CHECK-LIBCALL-NEXT:    pinsrw $0, 2(%rdi), %xmm0
405; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
406; CHECK-LIBCALL-NEXT:    pinsrw $0, 4(%rdi), %xmm0
407; CHECK-LIBCALL-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
408; CHECK-LIBCALL-NEXT:    pinsrw $0, 6(%rdi), %xmm0
409; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
410; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
411; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
412; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
413; CHECK-LIBCALL-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
414; CHECK-LIBCALL-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
415; CHECK-LIBCALL-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
416; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
417; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
418; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
419; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
420; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
421; CHECK-LIBCALL-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
422; CHECK-LIBCALL-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
423; CHECK-LIBCALL-NEXT:    unpcklpd (%rsp), %xmm0 # 16-byte Folded Reload
424; CHECK-LIBCALL-NEXT:    # xmm0 = xmm0[0],mem[0]
425; CHECK-LIBCALL-NEXT:    addq $72, %rsp
426; CHECK-LIBCALL-NEXT:    retq
427;
428; BWON-F16C-LABEL: test_extend32_vec4:
429; BWON-F16C:       # %bb.0:
430; BWON-F16C-NEXT:    vcvtph2ps (%rdi), %xmm0
431; BWON-F16C-NEXT:    retq
432;
433; CHECK-I686-LABEL: test_extend32_vec4:
434; CHECK-I686:       # %bb.0:
435; CHECK-I686-NEXT:    pushl %esi
436; CHECK-I686-NEXT:    subl $88, %esp
437; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
438; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
439; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
440; CHECK-I686-NEXT:    pinsrw $0, 6(%eax), %xmm0
441; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
442; CHECK-I686-NEXT:    pinsrw $0, 4(%eax), %xmm0
443; CHECK-I686-NEXT:    pinsrw $0, 2(%eax), %xmm1
444; CHECK-I686-NEXT:    pextrw $0, %xmm1, %eax
445; CHECK-I686-NEXT:    movw %ax, (%esp)
446; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
447; CHECK-I686-NEXT:    calll __extendhfsf2
448; CHECK-I686-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
449; CHECK-I686-NEXT:    movw %si, (%esp)
450; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
451; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
452; CHECK-I686-NEXT:    calll __extendhfsf2
453; CHECK-I686-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
454; CHECK-I686-NEXT:    movw %si, (%esp)
455; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
456; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
457; CHECK-I686-NEXT:    calll __extendhfsf2
458; CHECK-I686-NEXT:    movw %si, (%esp)
459; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
460; CHECK-I686-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
461; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
462; CHECK-I686-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
463; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
464; CHECK-I686-NEXT:    calll __extendhfsf2
465; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
466; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
467; CHECK-I686-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
468; CHECK-I686-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
469; CHECK-I686-NEXT:    movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
470; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
471; CHECK-I686-NEXT:    unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
472; CHECK-I686-NEXT:    movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
473; CHECK-I686-NEXT:    addl $88, %esp
474; CHECK-I686-NEXT:    popl %esi
475; CHECK-I686-NEXT:    retl
476  %a = load <4 x half>, ptr %p, align 8
477  %b = fpext <4 x half> %a to <4 x float>
478  ret <4 x float> %b
479}
480
481define <4 x double> @test_extend64_vec4(ptr %p) #0 {
482; CHECK-LIBCALL-LABEL: test_extend64_vec4:
483; CHECK-LIBCALL:       # %bb.0:
484; CHECK-LIBCALL-NEXT:    subq $72, %rsp
485; CHECK-LIBCALL-NEXT:    pinsrw $0, 4(%rdi), %xmm0
486; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
487; CHECK-LIBCALL-NEXT:    pinsrw $0, 6(%rdi), %xmm0
488; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
489; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rdi), %xmm0
490; CHECK-LIBCALL-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
491; CHECK-LIBCALL-NEXT:    pinsrw $0, 2(%rdi), %xmm0
492; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
493; CHECK-LIBCALL-NEXT:    cvtss2sd %xmm0, %xmm0
494; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
495; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
496; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
497; CHECK-LIBCALL-NEXT:    cvtss2sd %xmm0, %xmm0
498; CHECK-LIBCALL-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
499; CHECK-LIBCALL-NEXT:    # xmm0 = xmm0[0],mem[0]
500; CHECK-LIBCALL-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
501; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
502; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
503; CHECK-LIBCALL-NEXT:    cvtss2sd %xmm0, %xmm0
504; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
505; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
506; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
507; CHECK-LIBCALL-NEXT:    cvtss2sd %xmm0, %xmm1
508; CHECK-LIBCALL-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
509; CHECK-LIBCALL-NEXT:    # xmm1 = xmm1[0],mem[0]
510; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
511; CHECK-LIBCALL-NEXT:    addq $72, %rsp
512; CHECK-LIBCALL-NEXT:    retq
513;
514; BWON-F16C-LABEL: test_extend64_vec4:
515; BWON-F16C:       # %bb.0:
516; BWON-F16C-NEXT:    vcvtph2ps (%rdi), %xmm0
517; BWON-F16C-NEXT:    vcvtps2pd %xmm0, %ymm0
518; BWON-F16C-NEXT:    retq
519;
520; CHECK-I686-LABEL: test_extend64_vec4:
521; CHECK-I686:       # %bb.0:
522; CHECK-I686-NEXT:    pushl %esi
523; CHECK-I686-NEXT:    subl $104, %esp
524; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
525; CHECK-I686-NEXT:    pinsrw $0, 6(%eax), %xmm0
526; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
527; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
528; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
529; CHECK-I686-NEXT:    pinsrw $0, 2(%eax), %xmm0
530; CHECK-I686-NEXT:    pinsrw $0, 4(%eax), %xmm1
531; CHECK-I686-NEXT:    pextrw $0, %xmm1, %eax
532; CHECK-I686-NEXT:    movw %ax, (%esp)
533; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
534; CHECK-I686-NEXT:    calll __extendhfsf2
535; CHECK-I686-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
536; CHECK-I686-NEXT:    movw %si, (%esp)
537; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
538; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
539; CHECK-I686-NEXT:    calll __extendhfsf2
540; CHECK-I686-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
541; CHECK-I686-NEXT:    movw %si, (%esp)
542; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
543; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
544; CHECK-I686-NEXT:    calll __extendhfsf2
545; CHECK-I686-NEXT:    movw %si, (%esp)
546; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
547; CHECK-I686-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
548; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
549; CHECK-I686-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
550; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
551; CHECK-I686-NEXT:    calll __extendhfsf2
552; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
553; CHECK-I686-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
554; CHECK-I686-NEXT:    movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
555; CHECK-I686-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
556; CHECK-I686-NEXT:    movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]
557; CHECK-I686-NEXT:    addl $104, %esp
558; CHECK-I686-NEXT:    popl %esi
559; CHECK-I686-NEXT:    retl
560  %a = load <4 x half>, ptr %p, align 8
561  %b = fpext <4 x half> %a to <4 x double>
562  ret <4 x double> %b
563}
564
565define void @test_trunc32_vec4(<4 x float> %a, ptr %p) #0 {
566; CHECK-LIBCALL-LABEL: test_trunc32_vec4:
567; CHECK-LIBCALL:       # %bb.0:
568; CHECK-LIBCALL-NEXT:    pushq %rbx
569; CHECK-LIBCALL-NEXT:    subq $64, %rsp
570; CHECK-LIBCALL-NEXT:    movq %rdi, %rbx
571; CHECK-LIBCALL-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
572; CHECK-LIBCALL-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
573; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
574; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
575; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
576; CHECK-LIBCALL-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
577; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
578; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
579; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
580; CHECK-LIBCALL-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
581; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
582; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
583; CHECK-LIBCALL-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
584; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
585; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
586; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
587; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
588; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
589; CHECK-LIBCALL-NEXT:    movw %ax, 6(%rbx)
590; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
591; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
592; CHECK-LIBCALL-NEXT:    movw %ax, 4(%rbx)
593; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
594; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
595; CHECK-LIBCALL-NEXT:    movw %ax, 2(%rbx)
596; CHECK-LIBCALL-NEXT:    addq $64, %rsp
597; CHECK-LIBCALL-NEXT:    popq %rbx
598; CHECK-LIBCALL-NEXT:    retq
599;
600; BWON-F16C-LABEL: test_trunc32_vec4:
601; BWON-F16C:       # %bb.0:
602; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, (%rdi)
603; BWON-F16C-NEXT:    retq
604;
605; CHECK-I686-LABEL: test_trunc32_vec4:
606; CHECK-I686:       # %bb.0:
607; CHECK-I686-NEXT:    pushl %esi
608; CHECK-I686-NEXT:    subl $88, %esp
609; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
610; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
611; CHECK-I686-NEXT:    movaps %xmm0, %xmm1
612; CHECK-I686-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,1],xmm0[1,1]
613; CHECK-I686-NEXT:    movss %xmm1, (%esp)
614; CHECK-I686-NEXT:    calll __truncsfhf2
615; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
616; CHECK-I686-NEXT:    movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
617; CHECK-I686-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
618; CHECK-I686-NEXT:    movss %xmm0, (%esp)
619; CHECK-I686-NEXT:    calll __truncsfhf2
620; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
621; CHECK-I686-NEXT:    movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
622; CHECK-I686-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
623; CHECK-I686-NEXT:    movss %xmm0, (%esp)
624; CHECK-I686-NEXT:    calll __truncsfhf2
625; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
626; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
627; CHECK-I686-NEXT:    movd %xmm0, (%esp)
628; CHECK-I686-NEXT:    calll __truncsfhf2
629; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
630; CHECK-I686-NEXT:    movw %ax, (%esi)
631; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
632; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
633; CHECK-I686-NEXT:    movw %ax, 6(%esi)
634; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
635; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
636; CHECK-I686-NEXT:    movw %ax, 4(%esi)
637; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
638; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
639; CHECK-I686-NEXT:    movw %ax, 2(%esi)
640; CHECK-I686-NEXT:    addl $88, %esp
641; CHECK-I686-NEXT:    popl %esi
642; CHECK-I686-NEXT:    retl
643  %v = fptrunc <4 x float> %a to <4 x half>
644  store <4 x half> %v, ptr %p
645  ret void
646}
647
648define void @test_trunc64_vec4(<4 x double> %a, ptr %p) #0 {
649; CHECK-LIBCALL-LABEL: test_trunc64_vec4:
650; CHECK-LIBCALL:       # %bb.0:
651; CHECK-LIBCALL-NEXT:    pushq %rbx
652; CHECK-LIBCALL-NEXT:    subq $64, %rsp
653; CHECK-LIBCALL-NEXT:    movq %rdi, %rbx
654; CHECK-LIBCALL-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
655; CHECK-LIBCALL-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
656; CHECK-LIBCALL-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
657; CHECK-LIBCALL-NEXT:    callq __truncdfhf2@PLT
658; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
659; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
660; CHECK-LIBCALL-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
661; CHECK-LIBCALL-NEXT:    callq __truncdfhf2@PLT
662; CHECK-LIBCALL-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
663; CHECK-LIBCALL-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
664; CHECK-LIBCALL-NEXT:    callq __truncdfhf2@PLT
665; CHECK-LIBCALL-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
666; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
667; CHECK-LIBCALL-NEXT:    callq __truncdfhf2@PLT
668; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
669; CHECK-LIBCALL-NEXT:    movw %ax, 4(%rbx)
670; CHECK-LIBCALL-NEXT:    movdqa (%rsp), %xmm0 # 16-byte Reload
671; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
672; CHECK-LIBCALL-NEXT:    movw %ax, (%rbx)
673; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
674; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
675; CHECK-LIBCALL-NEXT:    movw %ax, 6(%rbx)
676; CHECK-LIBCALL-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
677; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
678; CHECK-LIBCALL-NEXT:    movw %ax, 2(%rbx)
679; CHECK-LIBCALL-NEXT:    addq $64, %rsp
680; CHECK-LIBCALL-NEXT:    popq %rbx
681; CHECK-LIBCALL-NEXT:    retq
682;
683; BWON-F16C-LABEL: test_trunc64_vec4:
684; BWON-F16C:       # %bb.0:
685; BWON-F16C-NEXT:    pushq %rbx
686; BWON-F16C-NEXT:    subq $64, %rsp
687; BWON-F16C-NEXT:    movq %rdi, %rbx
688; BWON-F16C-NEXT:    vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill
689; BWON-F16C-NEXT:    vextractf128 $1, %ymm0, %xmm0
690; BWON-F16C-NEXT:    vmovaps %xmm0, (%rsp) # 16-byte Spill
691; BWON-F16C-NEXT:    vzeroupper
692; BWON-F16C-NEXT:    callq __truncdfhf2@PLT
693; BWON-F16C-NEXT:    vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
694; BWON-F16C-NEXT:    vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload
695; BWON-F16C-NEXT:    # xmm0 = mem[1,0]
696; BWON-F16C-NEXT:    callq __truncdfhf2@PLT
697; BWON-F16C-NEXT:    vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
698; BWON-F16C-NEXT:    vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
699; BWON-F16C-NEXT:    vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
700; BWON-F16C-NEXT:    vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload
701; BWON-F16C-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
702; BWON-F16C-NEXT:    vzeroupper
703; BWON-F16C-NEXT:    callq __truncdfhf2@PLT
704; BWON-F16C-NEXT:    vmovaps %xmm0, (%rsp) # 16-byte Spill
705; BWON-F16C-NEXT:    vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
706; BWON-F16C-NEXT:    # xmm0 = mem[1,0]
707; BWON-F16C-NEXT:    callq __truncdfhf2@PLT
708; BWON-F16C-NEXT:    vmovdqa (%rsp), %xmm1 # 16-byte Reload
709; BWON-F16C-NEXT:    vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3]
710; BWON-F16C-NEXT:    vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload
711; BWON-F16C-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
712; BWON-F16C-NEXT:    vmovq %xmm0, (%rbx)
713; BWON-F16C-NEXT:    addq $64, %rsp
714; BWON-F16C-NEXT:    popq %rbx
715; BWON-F16C-NEXT:    retq
716;
717; CHECK-I686-LABEL: test_trunc64_vec4:
718; CHECK-I686:       # %bb.0:
719; CHECK-I686-NEXT:    pushl %esi
720; CHECK-I686-NEXT:    subl $88, %esp
721; CHECK-I686-NEXT:    movaps %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
722; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
723; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %esi
724; CHECK-I686-NEXT:    movlps %xmm0, (%esp)
725; CHECK-I686-NEXT:    calll __truncdfhf2
726; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
727; CHECK-I686-NEXT:    movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
728; CHECK-I686-NEXT:    movhps %xmm0, (%esp)
729; CHECK-I686-NEXT:    calll __truncdfhf2
730; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
731; CHECK-I686-NEXT:    movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
732; CHECK-I686-NEXT:    movlps %xmm0, (%esp)
733; CHECK-I686-NEXT:    calll __truncdfhf2
734; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
735; CHECK-I686-NEXT:    movaps {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
736; CHECK-I686-NEXT:    movhps %xmm0, (%esp)
737; CHECK-I686-NEXT:    calll __truncdfhf2
738; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
739; CHECK-I686-NEXT:    movw %ax, 6(%esi)
740; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
741; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
742; CHECK-I686-NEXT:    movw %ax, 4(%esi)
743; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
744; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
745; CHECK-I686-NEXT:    movw %ax, 2(%esi)
746; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
747; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
748; CHECK-I686-NEXT:    movw %ax, (%esi)
749; CHECK-I686-NEXT:    addl $88, %esp
750; CHECK-I686-NEXT:    popl %esi
751; CHECK-I686-NEXT:    retl
752  %v = fptrunc <4 x double> %a to <4 x half>
753  store <4 x half> %v, ptr %p
754  ret void
755}
756
757declare float @test_floatret();
758
759; On i686, if SSE2 is available, the return value from test_floatret is loaded
760; to f80 and then rounded to f32.  The DAG combiner should not combine this
761; fp_round and the subsequent fptrunc from float to half.
762define half @test_f80trunc_nodagcombine() #0 {
763; CHECK-LIBCALL-LABEL: test_f80trunc_nodagcombine:
764; CHECK-LIBCALL:       # %bb.0:
765; CHECK-LIBCALL-NEXT:    pushq %rax
766; CHECK-LIBCALL-NEXT:    callq test_floatret@PLT
767; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
768; CHECK-LIBCALL-NEXT:    popq %rax
769; CHECK-LIBCALL-NEXT:    retq
770;
771; BWON-F16C-LABEL: test_f80trunc_nodagcombine:
772; BWON-F16C:       # %bb.0:
773; BWON-F16C-NEXT:    pushq %rax
774; BWON-F16C-NEXT:    callq test_floatret@PLT
775; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
776; BWON-F16C-NEXT:    vmovd %xmm0, %eax
777; BWON-F16C-NEXT:    vpinsrw $0, %eax, %xmm0, %xmm0
778; BWON-F16C-NEXT:    popq %rax
779; BWON-F16C-NEXT:    retq
780;
781; CHECK-I686-LABEL: test_f80trunc_nodagcombine:
782; CHECK-I686:       # %bb.0:
783; CHECK-I686-NEXT:    subl $12, %esp
784; CHECK-I686-NEXT:    calll test_floatret@PLT
785; CHECK-I686-NEXT:    fstps (%esp)
786; CHECK-I686-NEXT:    calll __truncsfhf2
787; CHECK-I686-NEXT:    addl $12, %esp
788; CHECK-I686-NEXT:    retl
789  %1 = call float @test_floatret()
790  %2 = fptrunc float %1 to half
791  ret half %2
792}
793
794
795
796
797define float @test_sitofp_fadd_i32(i32 %a, ptr %b) #0 {
798; CHECK-LIBCALL-LABEL: test_sitofp_fadd_i32:
799; CHECK-LIBCALL:       # %bb.0:
800; CHECK-LIBCALL-NEXT:    subq $40, %rsp
801; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rsi), %xmm0
802; CHECK-LIBCALL-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
803; CHECK-LIBCALL-NEXT:    xorps %xmm0, %xmm0
804; CHECK-LIBCALL-NEXT:    cvtsi2ss %edi, %xmm0
805; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
806; CHECK-LIBCALL-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
807; CHECK-LIBCALL-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
808; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
809; CHECK-LIBCALL-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
810; CHECK-LIBCALL-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
811; CHECK-LIBCALL-NEXT:    # xmm0 = mem[0],zero,zero,zero
812; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
813; CHECK-LIBCALL-NEXT:    addss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Folded Reload
814; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
815; CHECK-LIBCALL-NEXT:    addq $40, %rsp
816; CHECK-LIBCALL-NEXT:    jmp __extendhfsf2@PLT # TAILCALL
817;
818; BWON-F16C-LABEL: test_sitofp_fadd_i32:
819; BWON-F16C:       # %bb.0:
820; BWON-F16C-NEXT:    movzwl (%rsi), %eax
821; BWON-F16C-NEXT:    vcvtsi2ss %edi, %xmm0, %xmm0
822; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
823; BWON-F16C-NEXT:    vpmovzxwq {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero
824; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
825; BWON-F16C-NEXT:    vmovd %eax, %xmm1
826; BWON-F16C-NEXT:    vcvtph2ps %xmm1, %xmm1
827; BWON-F16C-NEXT:    vaddss %xmm0, %xmm1, %xmm0
828; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
829; BWON-F16C-NEXT:    vmovd %xmm0, %eax
830; BWON-F16C-NEXT:    movzwl %ax, %eax
831; BWON-F16C-NEXT:    vmovd %eax, %xmm0
832; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
833; BWON-F16C-NEXT:    retq
834;
835; CHECK-I686-LABEL: test_sitofp_fadd_i32:
836; CHECK-I686:       # %bb.0:
837; CHECK-I686-NEXT:    subl $60, %esp
838; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
839; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
840; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
841; CHECK-I686-NEXT:    xorps %xmm0, %xmm0
842; CHECK-I686-NEXT:    cvtsi2ssl {{[0-9]+}}(%esp), %xmm0
843; CHECK-I686-NEXT:    movss %xmm0, (%esp)
844; CHECK-I686-NEXT:    calll __truncsfhf2
845; CHECK-I686-NEXT:    movaps %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
846; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
847; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
848; CHECK-I686-NEXT:    movw %ax, (%esp)
849; CHECK-I686-NEXT:    calll __extendhfsf2
850; CHECK-I686-NEXT:    movdqa {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 16-byte Reload
851; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
852; CHECK-I686-NEXT:    movw %ax, (%esp)
853; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
854; CHECK-I686-NEXT:    calll __extendhfsf2
855; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
856; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
857; CHECK-I686-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
858; CHECK-I686-NEXT:    movss %xmm0, (%esp)
859; CHECK-I686-NEXT:    calll __truncsfhf2
860; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
861; CHECK-I686-NEXT:    movw %ax, (%esp)
862; CHECK-I686-NEXT:    calll __extendhfsf2
863; CHECK-I686-NEXT:    addl $60, %esp
864; CHECK-I686-NEXT:    retl
865  %tmp0 = load half, ptr %b
866  %tmp1 = sitofp i32 %a to half
867  %tmp2 = fadd half %tmp0, %tmp1
868  %tmp3 = fpext half %tmp2 to float
869  ret float %tmp3
870}
871
872define half @PR40273(half) #0 {
873; CHECK-LIBCALL-LABEL: PR40273:
874; CHECK-LIBCALL:       # %bb.0:
875; CHECK-LIBCALL-NEXT:    pushq %rax
876; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
877; CHECK-LIBCALL-NEXT:    xorl %eax, %eax
878; CHECK-LIBCALL-NEXT:    xorps %xmm1, %xmm1
879; CHECK-LIBCALL-NEXT:    ucomiss %xmm1, %xmm0
880; CHECK-LIBCALL-NEXT:    movl $15360, %ecx # imm = 0x3C00
881; CHECK-LIBCALL-NEXT:    cmovnel %ecx, %eax
882; CHECK-LIBCALL-NEXT:    cmovpl %ecx, %eax
883; CHECK-LIBCALL-NEXT:    pinsrw $0, %eax, %xmm0
884; CHECK-LIBCALL-NEXT:    popq %rax
885; CHECK-LIBCALL-NEXT:    retq
886;
887; BWON-F16C-LABEL: PR40273:
888; BWON-F16C:       # %bb.0:
889; BWON-F16C-NEXT:    vpextrw $0, %xmm0, %eax
890; BWON-F16C-NEXT:    movzwl %ax, %eax
891; BWON-F16C-NEXT:    vmovd %eax, %xmm0
892; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
893; BWON-F16C-NEXT:    xorl %eax, %eax
894; BWON-F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1
895; BWON-F16C-NEXT:    vucomiss %xmm1, %xmm0
896; BWON-F16C-NEXT:    movl $15360, %ecx # imm = 0x3C00
897; BWON-F16C-NEXT:    cmovnel %ecx, %eax
898; BWON-F16C-NEXT:    cmovpl %ecx, %eax
899; BWON-F16C-NEXT:    vpinsrw $0, %eax, %xmm0, %xmm0
900; BWON-F16C-NEXT:    retq
901;
902; CHECK-I686-LABEL: PR40273:
903; CHECK-I686:       # %bb.0:
904; CHECK-I686-NEXT:    subl $12, %esp
905; CHECK-I686-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
906; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
907; CHECK-I686-NEXT:    movw %ax, (%esp)
908; CHECK-I686-NEXT:    calll __extendhfsf2
909; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
910; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
911; CHECK-I686-NEXT:    xorl %eax, %eax
912; CHECK-I686-NEXT:    xorps %xmm1, %xmm1
913; CHECK-I686-NEXT:    ucomiss %xmm1, %xmm0
914; CHECK-I686-NEXT:    movl $15360, %ecx # imm = 0x3C00
915; CHECK-I686-NEXT:    cmovnel %ecx, %eax
916; CHECK-I686-NEXT:    cmovpl %ecx, %eax
917; CHECK-I686-NEXT:    pinsrw $0, %eax, %xmm0
918; CHECK-I686-NEXT:    addl $12, %esp
919; CHECK-I686-NEXT:    retl
920  %2 = fcmp une half %0, 0xH0000
921  %3 = uitofp i1 %2 to half
922  ret half %3
923}
924
925define dso_local void @brcond(half %0) {
926; CHECK-LIBCALL-LABEL: brcond:
927; CHECK-LIBCALL:       # %bb.0: # %entry
928; CHECK-LIBCALL-NEXT:    pushq %rax
929; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 16
930; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
931; CHECK-LIBCALL-NEXT:    xorps %xmm1, %xmm1
932; CHECK-LIBCALL-NEXT:    ucomiss %xmm1, %xmm0
933; CHECK-LIBCALL-NEXT:    setp %al
934; CHECK-LIBCALL-NEXT:    setne %cl
935; CHECK-LIBCALL-NEXT:    orb %al, %cl
936; CHECK-LIBCALL-NEXT:    jne .LBB18_2
937; CHECK-LIBCALL-NEXT:  # %bb.1: # %if.then
938; CHECK-LIBCALL-NEXT:    popq %rax
939; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 8
940; CHECK-LIBCALL-NEXT:    retq
941; CHECK-LIBCALL-NEXT:  .LBB18_2: # %if.end
942;
943; BWON-F16C-LABEL: brcond:
944; BWON-F16C:       # %bb.0: # %entry
945; BWON-F16C-NEXT:    vpextrw $0, %xmm0, %eax
946; BWON-F16C-NEXT:    movzwl %ax, %eax
947; BWON-F16C-NEXT:    vmovd %eax, %xmm0
948; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
949; BWON-F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1
950; BWON-F16C-NEXT:    vucomiss %xmm1, %xmm0
951; BWON-F16C-NEXT:    setp %al
952; BWON-F16C-NEXT:    setne %cl
953; BWON-F16C-NEXT:    orb %al, %cl
954; BWON-F16C-NEXT:    jne .LBB18_2
955; BWON-F16C-NEXT:  # %bb.1: # %if.then
956; BWON-F16C-NEXT:    retq
957; BWON-F16C-NEXT:  .LBB18_2: # %if.end
958;
959; CHECK-I686-LABEL: brcond:
960; CHECK-I686:       # %bb.0: # %entry
961; CHECK-I686-NEXT:    subl $12, %esp
962; CHECK-I686-NEXT:    .cfi_def_cfa_offset 16
963; CHECK-I686-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
964; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
965; CHECK-I686-NEXT:    movw %ax, (%esp)
966; CHECK-I686-NEXT:    calll __extendhfsf2
967; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
968; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
969; CHECK-I686-NEXT:    xorps %xmm1, %xmm1
970; CHECK-I686-NEXT:    ucomiss %xmm1, %xmm0
971; CHECK-I686-NEXT:    setp %al
972; CHECK-I686-NEXT:    setne %cl
973; CHECK-I686-NEXT:    orb %al, %cl
974; CHECK-I686-NEXT:    jne .LBB18_2
975; CHECK-I686-NEXT:  # %bb.1: # %if.then
976; CHECK-I686-NEXT:    addl $12, %esp
977; CHECK-I686-NEXT:    .cfi_def_cfa_offset 4
978; CHECK-I686-NEXT:    retl
979; CHECK-I686-NEXT:  .LBB18_2: # %if.end
980entry:
981  %cmp = fcmp oeq half 0xH0000, %0
982  br i1 %cmp, label %if.then, label %if.end
983
984if.then:                                          ; preds = %entry
985  ret void
986
987if.end:                                           ; preds = %entry
988  unreachable
989}
990
991define half @test_sqrt(half %0) {
992; CHECK-LIBCALL-LABEL: test_sqrt:
993; CHECK-LIBCALL:       # %bb.0: # %entry
994; CHECK-LIBCALL-NEXT:    pushq %rax
995; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 16
996; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
997; CHECK-LIBCALL-NEXT:    sqrtss %xmm0, %xmm0
998; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
999; CHECK-LIBCALL-NEXT:    popq %rax
1000; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 8
1001; CHECK-LIBCALL-NEXT:    retq
1002;
1003; BWON-F16C-LABEL: test_sqrt:
1004; BWON-F16C:       # %bb.0: # %entry
1005; BWON-F16C-NEXT:    vpextrw $0, %xmm0, %eax
1006; BWON-F16C-NEXT:    movzwl %ax, %eax
1007; BWON-F16C-NEXT:    vmovd %eax, %xmm0
1008; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
1009; BWON-F16C-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
1010; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1011; BWON-F16C-NEXT:    vmovd %xmm0, %eax
1012; BWON-F16C-NEXT:    vpinsrw $0, %eax, %xmm0, %xmm0
1013; BWON-F16C-NEXT:    retq
1014;
1015; CHECK-I686-LABEL: test_sqrt:
1016; CHECK-I686:       # %bb.0: # %entry
1017; CHECK-I686-NEXT:    subl $12, %esp
1018; CHECK-I686-NEXT:    .cfi_def_cfa_offset 16
1019; CHECK-I686-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
1020; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
1021; CHECK-I686-NEXT:    movw %ax, (%esp)
1022; CHECK-I686-NEXT:    calll __extendhfsf2
1023; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
1024; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1025; CHECK-I686-NEXT:    sqrtss %xmm0, %xmm0
1026; CHECK-I686-NEXT:    movss %xmm0, (%esp)
1027; CHECK-I686-NEXT:    calll __truncsfhf2
1028; CHECK-I686-NEXT:    addl $12, %esp
1029; CHECK-I686-NEXT:    .cfi_def_cfa_offset 4
1030; CHECK-I686-NEXT:    retl
1031entry:
1032  %1 = call half @llvm.sqrt.f16(half %0)
1033  ret half %1
1034}
1035
1036declare half @llvm.sqrt.f16(half)
1037
1038define void @main.158() local_unnamed_addr #0 {
1039; CHECK-LIBCALL-LABEL: main.158:
1040; CHECK-LIBCALL:       # %bb.0: # %entry
1041; CHECK-LIBCALL-NEXT:    pushq %rax
1042; CHECK-LIBCALL-NEXT:    xorps %xmm0, %xmm0
1043; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
1044; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
1045; CHECK-LIBCALL-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1046; CHECK-LIBCALL-NEXT:    ucomiss %xmm0, %xmm1
1047; CHECK-LIBCALL-NEXT:    xorps %xmm0, %xmm0
1048; CHECK-LIBCALL-NEXT:    jae .LBB20_2
1049; CHECK-LIBCALL-NEXT:  # %bb.1: # %entry
1050; CHECK-LIBCALL-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1051; CHECK-LIBCALL-NEXT:  .LBB20_2: # %entry
1052; CHECK-LIBCALL-NEXT:    callq __truncsfhf2@PLT
1053; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
1054; CHECK-LIBCALL-NEXT:    movw %ax, (%rax)
1055; CHECK-LIBCALL-NEXT:    popq %rax
1056; CHECK-LIBCALL-NEXT:    retq
1057;
1058; BWON-F16C-LABEL: main.158:
1059; BWON-F16C:       # %bb.0: # %entry
1060; BWON-F16C-NEXT:    vxorps %xmm0, %xmm0, %xmm0
1061; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1062; BWON-F16C-NEXT:    vpmovzxwq {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero
1063; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
1064; BWON-F16C-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
1065; BWON-F16C-NEXT:    vucomiss %xmm0, %xmm1
1066; BWON-F16C-NEXT:    vxorps %xmm0, %xmm0, %xmm0
1067; BWON-F16C-NEXT:    jae .LBB20_2
1068; BWON-F16C-NEXT:  # %bb.1: # %entry
1069; BWON-F16C-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1070; BWON-F16C-NEXT:  .LBB20_2: # %entry
1071; BWON-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1072; BWON-F16C-NEXT:    vmovd %xmm0, %eax
1073; BWON-F16C-NEXT:    movw %ax, (%rax)
1074; BWON-F16C-NEXT:    retq
1075;
1076; CHECK-I686-LABEL: main.158:
1077; CHECK-I686:       # %bb.0: # %entry
1078; CHECK-I686-NEXT:    subl $12, %esp
1079; CHECK-I686-NEXT:    pxor %xmm0, %xmm0
1080; CHECK-I686-NEXT:    movd %xmm0, (%esp)
1081; CHECK-I686-NEXT:    calll __truncsfhf2
1082; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
1083; CHECK-I686-NEXT:    movw %ax, (%esp)
1084; CHECK-I686-NEXT:    calll __extendhfsf2
1085; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
1086; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1087; CHECK-I686-NEXT:    ucomiss {{[0-9]+}}(%esp), %xmm0
1088; CHECK-I686-NEXT:    xorps %xmm0, %xmm0
1089; CHECK-I686-NEXT:    jae .LBB20_2
1090; CHECK-I686-NEXT:  # %bb.1: # %entry
1091; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1092; CHECK-I686-NEXT:  .LBB20_2: # %entry
1093; CHECK-I686-NEXT:    movss %xmm0, (%esp)
1094; CHECK-I686-NEXT:    calll __truncsfhf2
1095; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
1096; CHECK-I686-NEXT:    movw %ax, (%eax)
1097; CHECK-I686-NEXT:    addl $12, %esp
1098; CHECK-I686-NEXT:    retl
1099entry:
1100  %0 = tail call half @llvm.fabs.f16(half undef)
1101  %1 = fpext half %0 to float
1102  %compare.2 = fcmp ole half %0, 0xH4800
1103  %multiply.95 = fmul float %1, 5.000000e-01
1104  %add.82 = fadd float %multiply.95, -2.000000e+00
1105  %multiply.68 = fmul float %add.82, 0.000000e+00
1106  %subtract.65 = fsub float %multiply.68, 0.000000e+00
1107  %multiply.57 = fmul float undef, 0.000000e+00
1108  %2 = select i1 %compare.2, float 0.000000e+00, float %multiply.57
1109  %3 = fptrunc float %2 to half
1110  store half %3, ptr undef, align 2
1111  ret void
1112}
1113
1114define void @main.45() local_unnamed_addr {
1115; CHECK-LIBCALL-LABEL: main.45:
1116; CHECK-LIBCALL:       # %bb.0: # %entry
1117; CHECK-LIBCALL-NEXT:    pushq %rbp
1118; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 16
1119; CHECK-LIBCALL-NEXT:    pushq %r15
1120; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 24
1121; CHECK-LIBCALL-NEXT:    pushq %r14
1122; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 32
1123; CHECK-LIBCALL-NEXT:    pushq %rbx
1124; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 40
1125; CHECK-LIBCALL-NEXT:    pushq %rax
1126; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 48
1127; CHECK-LIBCALL-NEXT:    .cfi_offset %rbx, -40
1128; CHECK-LIBCALL-NEXT:    .cfi_offset %r14, -32
1129; CHECK-LIBCALL-NEXT:    .cfi_offset %r15, -24
1130; CHECK-LIBCALL-NEXT:    .cfi_offset %rbp, -16
1131; CHECK-LIBCALL-NEXT:    pinsrw $0, (%rax), %xmm0
1132; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %eax
1133; CHECK-LIBCALL-NEXT:    movd %eax, %xmm1
1134; CHECK-LIBCALL-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,0,0,0,4,5,6,7]
1135; CHECK-LIBCALL-NEXT:    movq %xmm1, %rbx
1136; CHECK-LIBCALL-NEXT:    movq %rbx, %r14
1137; CHECK-LIBCALL-NEXT:    shrq $48, %r14
1138; CHECK-LIBCALL-NEXT:    movq %rbx, %r15
1139; CHECK-LIBCALL-NEXT:    shrq $32, %r15
1140; CHECK-LIBCALL-NEXT:    movl %ebx, %ebp
1141; CHECK-LIBCALL-NEXT:    shrl $16, %ebp
1142; CHECK-LIBCALL-NEXT:    callq __extendhfsf2@PLT
1143; CHECK-LIBCALL-NEXT:    ucomiss %xmm0, %xmm0
1144; CHECK-LIBCALL-NEXT:    movl $32256, %eax # imm = 0x7E00
1145; CHECK-LIBCALL-NEXT:    cmovpl %eax, %ebp
1146; CHECK-LIBCALL-NEXT:    cmovpl %eax, %r15d
1147; CHECK-LIBCALL-NEXT:    cmovpl %eax, %r14d
1148; CHECK-LIBCALL-NEXT:    cmovpl %eax, %ebx
1149; CHECK-LIBCALL-NEXT:    movw %bx, (%rax)
1150; CHECK-LIBCALL-NEXT:    movw %r14w, (%rax)
1151; CHECK-LIBCALL-NEXT:    movw %r15w, (%rax)
1152; CHECK-LIBCALL-NEXT:    movw %bp, (%rax)
1153; CHECK-LIBCALL-NEXT:    addq $8, %rsp
1154; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 40
1155; CHECK-LIBCALL-NEXT:    popq %rbx
1156; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 32
1157; CHECK-LIBCALL-NEXT:    popq %r14
1158; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 24
1159; CHECK-LIBCALL-NEXT:    popq %r15
1160; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 16
1161; CHECK-LIBCALL-NEXT:    popq %rbp
1162; CHECK-LIBCALL-NEXT:    .cfi_def_cfa_offset 8
1163; CHECK-LIBCALL-NEXT:    retq
1164;
1165; BWON-F16C-LABEL: main.45:
1166; BWON-F16C:       # %bb.0: # %entry
1167; BWON-F16C-NEXT:    movzwl (%rax), %eax
1168; BWON-F16C-NEXT:    vmovd %eax, %xmm0
1169; BWON-F16C-NEXT:    vpshuflw {{.*#+}} xmm1 = xmm0[0,0,0,0,4,5,6,7]
1170; BWON-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
1171; BWON-F16C-NEXT:    xorl %eax, %eax
1172; BWON-F16C-NEXT:    vucomiss %xmm0, %xmm0
1173; BWON-F16C-NEXT:    movl $65535, %ecx # imm = 0xFFFF
1174; BWON-F16C-NEXT:    cmovnpl %eax, %ecx
1175; BWON-F16C-NEXT:    vmovd %ecx, %xmm0
1176; BWON-F16C-NEXT:    vpshuflw {{.*#+}} xmm0 = xmm0[0,0,0,0,4,5,6,7]
1177; BWON-F16C-NEXT:    vpblendvb %xmm0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0
1178; BWON-F16C-NEXT:    vmovq %xmm0, (%rax)
1179; BWON-F16C-NEXT:    retq
1180;
1181; CHECK-I686-LABEL: main.45:
1182; CHECK-I686:       # %bb.0: # %entry
1183; CHECK-I686-NEXT:    pushl %edi
1184; CHECK-I686-NEXT:    .cfi_def_cfa_offset 8
1185; CHECK-I686-NEXT:    pushl %esi
1186; CHECK-I686-NEXT:    .cfi_def_cfa_offset 12
1187; CHECK-I686-NEXT:    subl $20, %esp
1188; CHECK-I686-NEXT:    .cfi_def_cfa_offset 32
1189; CHECK-I686-NEXT:    .cfi_offset %esi, -12
1190; CHECK-I686-NEXT:    .cfi_offset %edi, -8
1191; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
1192; CHECK-I686-NEXT:    pextrw $0, %xmm0, %eax
1193; CHECK-I686-NEXT:    movd %eax, %xmm0
1194; CHECK-I686-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,0,0,0,4,5,6,7]
1195; CHECK-I686-NEXT:    movd %xmm0, %esi
1196; CHECK-I686-NEXT:    movl %esi, %edi
1197; CHECK-I686-NEXT:    shrl $16, %edi
1198; CHECK-I686-NEXT:    movw %ax, (%esp)
1199; CHECK-I686-NEXT:    calll __extendhfsf2
1200; CHECK-I686-NEXT:    fstps {{[0-9]+}}(%esp)
1201; CHECK-I686-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
1202; CHECK-I686-NEXT:    ucomiss %xmm0, %xmm0
1203; CHECK-I686-NEXT:    movl $32256, %eax # imm = 0x7E00
1204; CHECK-I686-NEXT:    cmovpl %eax, %esi
1205; CHECK-I686-NEXT:    cmovpl %eax, %edi
1206; CHECK-I686-NEXT:    movw %di, (%eax)
1207; CHECK-I686-NEXT:    movw %si, (%eax)
1208; CHECK-I686-NEXT:    addl $20, %esp
1209; CHECK-I686-NEXT:    .cfi_def_cfa_offset 12
1210; CHECK-I686-NEXT:    popl %esi
1211; CHECK-I686-NEXT:    .cfi_def_cfa_offset 8
1212; CHECK-I686-NEXT:    popl %edi
1213; CHECK-I686-NEXT:    .cfi_def_cfa_offset 4
1214; CHECK-I686-NEXT:    retl
1215entry:
1216  %0 = load half, ptr undef, align 8
1217  %1 = bitcast half %0 to i16
1218  %broadcast.splatinsert = insertelement <4 x half> poison, half %0, i64 0
1219  %broadcast.splat = shufflevector <4 x half> %broadcast.splatinsert, <4 x half> poison, <4 x i32> zeroinitializer
1220  %broadcast.splatinsert13 = insertelement <4 x i16> poison, i16 %1, i64 0
1221  %broadcast.splat14 = shufflevector <4 x i16> %broadcast.splatinsert13, <4 x i16> poison, <4 x i32> zeroinitializer
1222  %2 = fcmp uno <4 x half> %broadcast.splat, zeroinitializer
1223  %3 = add <4 x i16> zeroinitializer, %broadcast.splat14
1224  %4 = select i1 undef, <4 x i16> undef, <4 x i16> %3
1225  %5 = select <4 x i1> undef, <4 x i16> undef, <4 x i16> %4
1226  %6 = bitcast <4 x i16> %5 to <4 x half>
1227  %7 = select <4 x i1> %2, <4 x half> <half 0xH7E00, half 0xH7E00, half 0xH7E00, half 0xH7E00>, <4 x half> %6
1228  store <4 x half> %7, ptr undef, align 16
1229  ret void
1230}
1231
1232define half @fcopysign(half %x, half %y) {
1233; CHECK-LIBCALL-LABEL: fcopysign:
1234; CHECK-LIBCALL:       # %bb.0:
1235; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm1, %eax
1236; CHECK-LIBCALL-NEXT:    andl $-32768, %eax # imm = 0x8000
1237; CHECK-LIBCALL-NEXT:    pextrw $0, %xmm0, %ecx
1238; CHECK-LIBCALL-NEXT:    andl $32767, %ecx # imm = 0x7FFF
1239; CHECK-LIBCALL-NEXT:    orl %eax, %ecx
1240; CHECK-LIBCALL-NEXT:    pinsrw $0, %ecx, %xmm0
1241; CHECK-LIBCALL-NEXT:    retq
1242;
1243; BWON-F16C-LABEL: fcopysign:
1244; BWON-F16C:       # %bb.0:
1245; BWON-F16C-NEXT:    vpextrw $0, %xmm1, %eax
1246; BWON-F16C-NEXT:    andl $-32768, %eax # imm = 0x8000
1247; BWON-F16C-NEXT:    vpextrw $0, %xmm0, %ecx
1248; BWON-F16C-NEXT:    andl $32767, %ecx # imm = 0x7FFF
1249; BWON-F16C-NEXT:    orl %eax, %ecx
1250; BWON-F16C-NEXT:    vpinsrw $0, %ecx, %xmm0, %xmm0
1251; BWON-F16C-NEXT:    retq
1252;
1253; CHECK-I686-LABEL: fcopysign:
1254; CHECK-I686:       # %bb.0:
1255; CHECK-I686-NEXT:    movl $-32768, %eax # imm = 0x8000
1256; CHECK-I686-NEXT:    andl {{[0-9]+}}(%esp), %eax
1257; CHECK-I686-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1258; CHECK-I686-NEXT:    andl $32767, %ecx # imm = 0x7FFF
1259; CHECK-I686-NEXT:    orl %eax, %ecx
1260; CHECK-I686-NEXT:    pinsrw $0, %ecx, %xmm0
1261; CHECK-I686-NEXT:    retl
1262  %a = call half @llvm.copysign.f16(half %x, half %y)
1263  ret half %a
1264}
1265
1266declare half @llvm.fabs.f16(half)
1267declare half @llvm.copysign.f16(half, half)
1268
1269define <8 x half> @select(i1 %c, <8 x half> %x, <8 x half> %y) {
1270; CHECK-LIBCALL-LABEL: select:
1271; CHECK-LIBCALL:       # %bb.0:
1272; CHECK-LIBCALL-NEXT:    testb $1, %dil
1273; CHECK-LIBCALL-NEXT:    jne .LBB23_2
1274; CHECK-LIBCALL-NEXT:  # %bb.1:
1275; CHECK-LIBCALL-NEXT:    movaps %xmm1, %xmm0
1276; CHECK-LIBCALL-NEXT:  .LBB23_2:
1277; CHECK-LIBCALL-NEXT:    retq
1278;
1279; BWON-F16C-LABEL: select:
1280; BWON-F16C:       # %bb.0:
1281; BWON-F16C-NEXT:    testb $1, %dil
1282; BWON-F16C-NEXT:    jne .LBB23_2
1283; BWON-F16C-NEXT:  # %bb.1:
1284; BWON-F16C-NEXT:    vmovaps %xmm1, %xmm0
1285; BWON-F16C-NEXT:  .LBB23_2:
1286; BWON-F16C-NEXT:    retq
1287;
1288; CHECK-I686-LABEL: select:
1289; CHECK-I686:       # %bb.0:
1290; CHECK-I686-NEXT:    testb $1, {{[0-9]+}}(%esp)
1291; CHECK-I686-NEXT:    jne .LBB23_2
1292; CHECK-I686-NEXT:  # %bb.1:
1293; CHECK-I686-NEXT:    movaps %xmm1, %xmm0
1294; CHECK-I686-NEXT:  .LBB23_2:
1295; CHECK-I686-NEXT:    retl
1296  %s = select i1 %c, <8 x half> %x, <8 x half> %y
1297  ret <8 x half> %s
1298}
1299
1300attributes #0 = { nounwind }
1301