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