xref: /llvm-project/llvm/test/CodeGen/X86/half-constrained.ll (revision 67c3f2b4303972a6dc8ada54efe1d5d80d119a51)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefix=X86-NOF16C
3; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=f16c | FileCheck %s --check-prefix=X86-F16C
4; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefix=X64-NOF16C
5; RUN: llc < %s -mtriple=x86_64-linux-gnu -mattr=f16c | FileCheck %s --check-prefix=X64-F16C
6
7@a = global half 0xH0000, align 2
8@b = global half 0xH0000, align 2
9@c = global half 0xH0000, align 2
10
11define float @half_to_float() strictfp {
12; X86-NOF16C-LABEL: half_to_float:
13; X86-NOF16C:       # %bb.0:
14; X86-NOF16C-NEXT:    subl $12, %esp
15; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
16; X86-NOF16C-NEXT:    movzwl a, %eax
17; X86-NOF16C-NEXT:    movl %eax, (%esp)
18; X86-NOF16C-NEXT:    calll __gnu_h2f_ieee
19; X86-NOF16C-NEXT:    addl $12, %esp
20; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
21; X86-NOF16C-NEXT:    retl
22;
23; X86-F16C-LABEL: half_to_float:
24; X86-F16C:       # %bb.0:
25; X86-F16C-NEXT:    pushl %eax
26; X86-F16C-NEXT:    .cfi_def_cfa_offset 8
27; X86-F16C-NEXT:    movzwl a, %eax
28; X86-F16C-NEXT:    vmovd %eax, %xmm0
29; X86-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
30; X86-F16C-NEXT:    vmovss %xmm0, (%esp)
31; X86-F16C-NEXT:    flds (%esp)
32; X86-F16C-NEXT:    wait
33; X86-F16C-NEXT:    popl %eax
34; X86-F16C-NEXT:    .cfi_def_cfa_offset 4
35; X86-F16C-NEXT:    retl
36;
37; X64-NOF16C-LABEL: half_to_float:
38; X64-NOF16C:       # %bb.0:
39; X64-NOF16C-NEXT:    pushq %rax
40; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
41; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rax
42; X64-NOF16C-NEXT:    pinsrw $0, (%rax), %xmm0
43; X64-NOF16C-NEXT:    callq __extendhfsf2@PLT
44; X64-NOF16C-NEXT:    popq %rax
45; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
46; X64-NOF16C-NEXT:    retq
47;
48; X64-F16C-LABEL: half_to_float:
49; X64-F16C:       # %bb.0:
50; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
51; X64-F16C-NEXT:    movzwl (%rax), %eax
52; X64-F16C-NEXT:    vmovd %eax, %xmm0
53; X64-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
54; X64-F16C-NEXT:    retq
55  %1 = load half, ptr @a, align 2
56  %2 = tail call float @llvm.experimental.constrained.fpext.f32.f16(half %1, metadata !"fpexcept.strict") #0
57  ret float %2
58}
59
60define double @half_to_double() strictfp {
61; X86-NOF16C-LABEL: half_to_double:
62; X86-NOF16C:       # %bb.0:
63; X86-NOF16C-NEXT:    subl $12, %esp
64; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
65; X86-NOF16C-NEXT:    movzwl a, %eax
66; X86-NOF16C-NEXT:    movl %eax, (%esp)
67; X86-NOF16C-NEXT:    calll __gnu_h2f_ieee
68; X86-NOF16C-NEXT:    addl $12, %esp
69; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
70; X86-NOF16C-NEXT:    retl
71;
72; X86-F16C-LABEL: half_to_double:
73; X86-F16C:       # %bb.0:
74; X86-F16C-NEXT:    subl $12, %esp
75; X86-F16C-NEXT:    .cfi_def_cfa_offset 16
76; X86-F16C-NEXT:    movzwl a, %eax
77; X86-F16C-NEXT:    vmovd %eax, %xmm0
78; X86-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
79; X86-F16C-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
80; X86-F16C-NEXT:    vmovsd %xmm0, (%esp)
81; X86-F16C-NEXT:    fldl (%esp)
82; X86-F16C-NEXT:    wait
83; X86-F16C-NEXT:    addl $12, %esp
84; X86-F16C-NEXT:    .cfi_def_cfa_offset 4
85; X86-F16C-NEXT:    retl
86;
87; X64-NOF16C-LABEL: half_to_double:
88; X64-NOF16C:       # %bb.0:
89; X64-NOF16C-NEXT:    pushq %rax
90; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
91; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rax
92; X64-NOF16C-NEXT:    pinsrw $0, (%rax), %xmm0
93; X64-NOF16C-NEXT:    callq __extendhfsf2@PLT
94; X64-NOF16C-NEXT:    cvtss2sd %xmm0, %xmm0
95; X64-NOF16C-NEXT:    popq %rax
96; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
97; X64-NOF16C-NEXT:    retq
98;
99; X64-F16C-LABEL: half_to_double:
100; X64-F16C:       # %bb.0:
101; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
102; X64-F16C-NEXT:    movzwl (%rax), %eax
103; X64-F16C-NEXT:    vmovd %eax, %xmm0
104; X64-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
105; X64-F16C-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
106; X64-F16C-NEXT:    retq
107  %1 = load half, ptr @a, align 2
108  %2 = tail call double @llvm.experimental.constrained.fpext.f64.f16(half %1, metadata !"fpexcept.strict") #0
109  ret double %2
110}
111
112define x86_fp80 @half_to_fp80() strictfp {
113; X86-NOF16C-LABEL: half_to_fp80:
114; X86-NOF16C:       # %bb.0:
115; X86-NOF16C-NEXT:    subl $12, %esp
116; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
117; X86-NOF16C-NEXT:    movzwl a, %eax
118; X86-NOF16C-NEXT:    movl %eax, (%esp)
119; X86-NOF16C-NEXT:    calll __gnu_h2f_ieee
120; X86-NOF16C-NEXT:    addl $12, %esp
121; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
122; X86-NOF16C-NEXT:    retl
123;
124; X86-F16C-LABEL: half_to_fp80:
125; X86-F16C:       # %bb.0:
126; X86-F16C-NEXT:    subl $12, %esp
127; X86-F16C-NEXT:    .cfi_def_cfa_offset 16
128; X86-F16C-NEXT:    vpinsrw $0, a, %xmm0, %xmm0
129; X86-F16C-NEXT:    vpextrw $0, %xmm0, (%esp)
130; X86-F16C-NEXT:    calll __extendhfxf2
131; X86-F16C-NEXT:    addl $12, %esp
132; X86-F16C-NEXT:    .cfi_def_cfa_offset 4
133; X86-F16C-NEXT:    retl
134;
135; X64-NOF16C-LABEL: half_to_fp80:
136; X64-NOF16C:       # %bb.0:
137; X64-NOF16C-NEXT:    pushq %rax
138; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
139; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rax
140; X64-NOF16C-NEXT:    pinsrw $0, (%rax), %xmm0
141; X64-NOF16C-NEXT:    callq __extendhfxf2@PLT
142; X64-NOF16C-NEXT:    popq %rax
143; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
144; X64-NOF16C-NEXT:    retq
145;
146; X64-F16C-LABEL: half_to_fp80:
147; X64-F16C:       # %bb.0:
148; X64-F16C-NEXT:    pushq %rax
149; X64-F16C-NEXT:    .cfi_def_cfa_offset 16
150; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
151; X64-F16C-NEXT:    vpinsrw $0, (%rax), %xmm0, %xmm0
152; X64-F16C-NEXT:    callq __extendhfxf2@PLT
153; X64-F16C-NEXT:    popq %rax
154; X64-F16C-NEXT:    .cfi_def_cfa_offset 8
155; X64-F16C-NEXT:    retq
156  %1 = load half, ptr @a, align 2
157  %2 = tail call x86_fp80 @llvm.experimental.constrained.fpext.f80.f16(half %1, metadata !"fpexcept.strict") #0
158  ret x86_fp80 %2
159}
160
161define void @float_to_half(float %0) strictfp {
162; X86-NOF16C-LABEL: float_to_half:
163; X86-NOF16C:       # %bb.0:
164; X86-NOF16C-NEXT:    subl $12, %esp
165; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
166; X86-NOF16C-NEXT:    flds {{[0-9]+}}(%esp)
167; X86-NOF16C-NEXT:    fstps (%esp)
168; X86-NOF16C-NEXT:    wait
169; X86-NOF16C-NEXT:    calll __gnu_f2h_ieee
170; X86-NOF16C-NEXT:    movw %ax, a
171; X86-NOF16C-NEXT:    addl $12, %esp
172; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
173; X86-NOF16C-NEXT:    retl
174;
175; X86-F16C-LABEL: float_to_half:
176; X86-F16C:       # %bb.0:
177; X86-F16C-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
178; X86-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
179; X86-F16C-NEXT:    vpextrw $0, %xmm0, a
180; X86-F16C-NEXT:    retl
181;
182; X64-NOF16C-LABEL: float_to_half:
183; X64-NOF16C:       # %bb.0:
184; X64-NOF16C-NEXT:    pushq %rax
185; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
186; X64-NOF16C-NEXT:    callq __truncsfhf2@PLT
187; X64-NOF16C-NEXT:    pextrw $0, %xmm0, %eax
188; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rcx
189; X64-NOF16C-NEXT:    movw %ax, (%rcx)
190; X64-NOF16C-NEXT:    popq %rax
191; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
192; X64-NOF16C-NEXT:    retq
193;
194; X64-F16C-LABEL: float_to_half:
195; X64-F16C:       # %bb.0:
196; X64-F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1
197; X64-F16C-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
198; X64-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
199; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
200; X64-F16C-NEXT:    vpextrw $0, %xmm0, (%rax)
201; X64-F16C-NEXT:    retq
202  %2 = tail call half @llvm.experimental.constrained.fptrunc.f16.f32(float %0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
203  store half %2, ptr @a, align 2
204  ret void
205}
206
207define void @double_to_half(double %0) strictfp {
208; X86-NOF16C-LABEL: double_to_half:
209; X86-NOF16C:       # %bb.0:
210; X86-NOF16C-NEXT:    subl $12, %esp
211; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
212; X86-NOF16C-NEXT:    fldl {{[0-9]+}}(%esp)
213; X86-NOF16C-NEXT:    fstpl (%esp)
214; X86-NOF16C-NEXT:    wait
215; X86-NOF16C-NEXT:    calll __truncdfhf2
216; X86-NOF16C-NEXT:    movw %ax, a
217; X86-NOF16C-NEXT:    addl $12, %esp
218; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
219; X86-NOF16C-NEXT:    retl
220;
221; X86-F16C-LABEL: double_to_half:
222; X86-F16C:       # %bb.0:
223; X86-F16C-NEXT:    subl $12, %esp
224; X86-F16C-NEXT:    .cfi_def_cfa_offset 16
225; X86-F16C-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
226; X86-F16C-NEXT:    vmovq %xmm0, (%esp)
227; X86-F16C-NEXT:    calll __truncdfhf2
228; X86-F16C-NEXT:    vpextrw $0, %xmm0, a
229; X86-F16C-NEXT:    addl $12, %esp
230; X86-F16C-NEXT:    .cfi_def_cfa_offset 4
231; X86-F16C-NEXT:    retl
232;
233; X64-NOF16C-LABEL: double_to_half:
234; X64-NOF16C:       # %bb.0:
235; X64-NOF16C-NEXT:    pushq %rax
236; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
237; X64-NOF16C-NEXT:    callq __truncdfhf2@PLT
238; X64-NOF16C-NEXT:    pextrw $0, %xmm0, %eax
239; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rcx
240; X64-NOF16C-NEXT:    movw %ax, (%rcx)
241; X64-NOF16C-NEXT:    popq %rax
242; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
243; X64-NOF16C-NEXT:    retq
244;
245; X64-F16C-LABEL: double_to_half:
246; X64-F16C:       # %bb.0:
247; X64-F16C-NEXT:    pushq %rax
248; X64-F16C-NEXT:    .cfi_def_cfa_offset 16
249; X64-F16C-NEXT:    callq __truncdfhf2@PLT
250; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
251; X64-F16C-NEXT:    vpextrw $0, %xmm0, (%rax)
252; X64-F16C-NEXT:    popq %rax
253; X64-F16C-NEXT:    .cfi_def_cfa_offset 8
254; X64-F16C-NEXT:    retq
255  %2 = tail call half @llvm.experimental.constrained.fptrunc.f16.f64(double %0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
256  store half %2, ptr @a, align 2
257  ret void
258}
259
260define void @fp80_to_half(x86_fp80 %0) strictfp {
261; X86-NOF16C-LABEL: fp80_to_half:
262; X86-NOF16C:       # %bb.0:
263; X86-NOF16C-NEXT:    subl $12, %esp
264; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
265; X86-NOF16C-NEXT:    fldt {{[0-9]+}}(%esp)
266; X86-NOF16C-NEXT:    fstpt (%esp)
267; X86-NOF16C-NEXT:    wait
268; X86-NOF16C-NEXT:    calll __truncxfhf2
269; X86-NOF16C-NEXT:    movw %ax, a
270; X86-NOF16C-NEXT:    addl $12, %esp
271; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
272; X86-NOF16C-NEXT:    retl
273;
274; X86-F16C-LABEL: fp80_to_half:
275; X86-F16C:       # %bb.0:
276; X86-F16C-NEXT:    subl $12, %esp
277; X86-F16C-NEXT:    .cfi_def_cfa_offset 16
278; X86-F16C-NEXT:    fldt {{[0-9]+}}(%esp)
279; X86-F16C-NEXT:    fstpt (%esp)
280; X86-F16C-NEXT:    wait
281; X86-F16C-NEXT:    calll __truncxfhf2
282; X86-F16C-NEXT:    vpextrw $0, %xmm0, a
283; X86-F16C-NEXT:    addl $12, %esp
284; X86-F16C-NEXT:    .cfi_def_cfa_offset 4
285; X86-F16C-NEXT:    retl
286;
287; X64-NOF16C-LABEL: fp80_to_half:
288; X64-NOF16C:       # %bb.0:
289; X64-NOF16C-NEXT:    subq $24, %rsp
290; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 32
291; X64-NOF16C-NEXT:    fldt {{[0-9]+}}(%rsp)
292; X64-NOF16C-NEXT:    fstpt (%rsp)
293; X64-NOF16C-NEXT:    wait
294; X64-NOF16C-NEXT:    callq __truncxfhf2@PLT
295; X64-NOF16C-NEXT:    pextrw $0, %xmm0, %eax
296; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rcx
297; X64-NOF16C-NEXT:    movw %ax, (%rcx)
298; X64-NOF16C-NEXT:    addq $24, %rsp
299; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
300; X64-NOF16C-NEXT:    retq
301;
302; X64-F16C-LABEL: fp80_to_half:
303; X64-F16C:       # %bb.0:
304; X64-F16C-NEXT:    subq $24, %rsp
305; X64-F16C-NEXT:    .cfi_def_cfa_offset 32
306; X64-F16C-NEXT:    fldt {{[0-9]+}}(%rsp)
307; X64-F16C-NEXT:    fstpt (%rsp)
308; X64-F16C-NEXT:    wait
309; X64-F16C-NEXT:    callq __truncxfhf2@PLT
310; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
311; X64-F16C-NEXT:    vpextrw $0, %xmm0, (%rax)
312; X64-F16C-NEXT:    addq $24, %rsp
313; X64-F16C-NEXT:    .cfi_def_cfa_offset 8
314; X64-F16C-NEXT:    retq
315  %2 = tail call half @llvm.experimental.constrained.fptrunc.f16.f80(x86_fp80 %0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
316  store half %2, ptr @a, align 2
317  ret void
318}
319
320define void @add() strictfp {
321; X86-NOF16C-LABEL: add:
322; X86-NOF16C:       # %bb.0:
323; X86-NOF16C-NEXT:    subl $12, %esp
324; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
325; X86-NOF16C-NEXT:    movzwl a, %eax
326; X86-NOF16C-NEXT:    movl %eax, (%esp)
327; X86-NOF16C-NEXT:    calll __gnu_h2f_ieee
328; X86-NOF16C-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
329; X86-NOF16C-NEXT:    wait
330; X86-NOF16C-NEXT:    movzwl b, %eax
331; X86-NOF16C-NEXT:    movl %eax, (%esp)
332; X86-NOF16C-NEXT:    calll __gnu_h2f_ieee
333; X86-NOF16C-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
334; X86-NOF16C-NEXT:    faddp %st, %st(1)
335; X86-NOF16C-NEXT:    fstps (%esp)
336; X86-NOF16C-NEXT:    wait
337; X86-NOF16C-NEXT:    calll __gnu_f2h_ieee
338; X86-NOF16C-NEXT:    movw %ax, c
339; X86-NOF16C-NEXT:    addl $12, %esp
340; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
341; X86-NOF16C-NEXT:    retl
342;
343; X86-F16C-LABEL: add:
344; X86-F16C:       # %bb.0:
345; X86-F16C-NEXT:    movzwl a, %eax
346; X86-F16C-NEXT:    vmovd %eax, %xmm0
347; X86-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
348; X86-F16C-NEXT:    movzwl b, %eax
349; X86-F16C-NEXT:    vmovd %eax, %xmm1
350; X86-F16C-NEXT:    vcvtph2ps %xmm1, %xmm1
351; X86-F16C-NEXT:    vaddss %xmm1, %xmm0, %xmm0
352; X86-F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1
353; X86-F16C-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
354; X86-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
355; X86-F16C-NEXT:    vpextrw $0, %xmm0, c
356; X86-F16C-NEXT:    retl
357;
358; X64-NOF16C-LABEL: add:
359; X64-NOF16C:       # %bb.0:
360; X64-NOF16C-NEXT:    pushq %rax
361; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 16
362; X64-NOF16C-NEXT:    movq a@GOTPCREL(%rip), %rax
363; X64-NOF16C-NEXT:    pinsrw $0, (%rax), %xmm0
364; X64-NOF16C-NEXT:    callq __extendhfsf2@PLT
365; X64-NOF16C-NEXT:    movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill
366; X64-NOF16C-NEXT:    movq b@GOTPCREL(%rip), %rax
367; X64-NOF16C-NEXT:    pinsrw $0, (%rax), %xmm0
368; X64-NOF16C-NEXT:    callq __extendhfsf2@PLT
369; X64-NOF16C-NEXT:    addss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Folded Reload
370; X64-NOF16C-NEXT:    callq __truncsfhf2@PLT
371; X64-NOF16C-NEXT:    pextrw $0, %xmm0, %eax
372; X64-NOF16C-NEXT:    movq c@GOTPCREL(%rip), %rcx
373; X64-NOF16C-NEXT:    movw %ax, (%rcx)
374; X64-NOF16C-NEXT:    popq %rax
375; X64-NOF16C-NEXT:    .cfi_def_cfa_offset 8
376; X64-NOF16C-NEXT:    retq
377;
378; X64-F16C-LABEL: add:
379; X64-F16C:       # %bb.0:
380; X64-F16C-NEXT:    movq a@GOTPCREL(%rip), %rax
381; X64-F16C-NEXT:    movzwl (%rax), %eax
382; X64-F16C-NEXT:    vmovd %eax, %xmm0
383; X64-F16C-NEXT:    vcvtph2ps %xmm0, %xmm0
384; X64-F16C-NEXT:    movq b@GOTPCREL(%rip), %rax
385; X64-F16C-NEXT:    movzwl (%rax), %eax
386; X64-F16C-NEXT:    vmovd %eax, %xmm1
387; X64-F16C-NEXT:    vcvtph2ps %xmm1, %xmm1
388; X64-F16C-NEXT:    vaddss %xmm1, %xmm0, %xmm0
389; X64-F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1
390; X64-F16C-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]
391; X64-F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
392; X64-F16C-NEXT:    movq c@GOTPCREL(%rip), %rax
393; X64-F16C-NEXT:    vpextrw $0, %xmm0, (%rax)
394; X64-F16C-NEXT:    retq
395  %1 = load half, ptr @a, align 2
396  %2 = tail call float @llvm.experimental.constrained.fpext.f32.f16(half %1, metadata !"fpexcept.strict") #0
397  %3 = load half, ptr @b, align 2
398  %4 = tail call float @llvm.experimental.constrained.fpext.f32.f16(half %3, metadata !"fpexcept.strict") #0
399  %5 = tail call float @llvm.experimental.constrained.fadd.f32(float %2, float %4, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
400  %6 = tail call half @llvm.experimental.constrained.fptrunc.f16.f32(float %5, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
401  store half %6, ptr @c, align 2
402  ret void
403}
404
405declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)
406declare double @llvm.experimental.constrained.fpext.f64.f16(half, metadata)
407declare x86_fp80 @llvm.experimental.constrained.fpext.f80.f16(half, metadata)
408declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
409declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)
410declare half @llvm.experimental.constrained.fptrunc.f16.f64(double, metadata, metadata)
411declare half @llvm.experimental.constrained.fptrunc.f16.f80(x86_fp80, metadata, metadata)
412
413attributes #0 = { strictfp }
414
415