1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck -check-prefixes=X64 %s
3 ; RUN: llc -mtriple=i386-pc-win32 < %s | FileCheck -check-prefix=WIN32 %s
5 define { half, i32 } @test_frexp_f16_i32(half %a) {
6 ; X64-LABEL: test_frexp_f16_i32:
8 ; X64-NEXT: subq $24, %rsp
9 ; X64-NEXT: .cfi_def_cfa_offset 32
10 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
11 ; X64-NEXT: callq __extendhfsf2@PLT
12 ; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
13 ; X64-NEXT: callq __truncsfhf2@PLT
14 ; X64-NEXT: pextrw $0, %xmm0, %ecx
15 ; X64-NEXT: movl %ecx, %eax
16 ; X64-NEXT: andl $31744, %eax # imm = 0x7C00
17 ; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
18 ; X64-NEXT: pextrw $0, %xmm0, %edx
19 ; X64-NEXT: movl %edx, %esi
20 ; X64-NEXT: andl $32767, %esi # imm = 0x7FFF
21 ; X64-NEXT: cmpl $1024, %esi # imm = 0x400
22 ; X64-NEXT: cmovael %edx, %ecx
23 ; X64-NEXT: cmovael %esi, %eax
24 ; X64-NEXT: shrl $10, %eax
25 ; X64-NEXT: leal -12(%rax), %edi
26 ; X64-NEXT: cmpl $1024, %esi # imm = 0x400
27 ; X64-NEXT: cmovael %eax, %edi
28 ; X64-NEXT: addl $-14, %edi
29 ; X64-NEXT: andl $-31745, %ecx # imm = 0x83FF
30 ; X64-NEXT: orl $14336, %ecx # imm = 0x3800
31 ; X64-NEXT: addl $-31744, %esi # imm = 0x8400
32 ; X64-NEXT: movzwl %si, %esi
33 ; X64-NEXT: xorl %eax, %eax
34 ; X64-NEXT: cmpl $33792, %esi # imm = 0x8400
35 ; X64-NEXT: cmoval %edi, %eax
36 ; X64-NEXT: cmovbel %edx, %ecx
37 ; X64-NEXT: pinsrw $0, %ecx, %xmm0
38 ; X64-NEXT: addq $24, %rsp
39 ; X64-NEXT: .cfi_def_cfa_offset 8
42 ; WIN32-LABEL: test_frexp_f16_i32:
44 ; WIN32-NEXT: pushl %esi
45 ; WIN32-NEXT: subl $20, %esp
46 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
47 ; WIN32-NEXT: movl %eax, (%esp)
48 ; WIN32-NEXT: calll ___gnu_h2f_ieee
49 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
50 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
51 ; WIN32-NEXT: fstpl (%esp)
52 ; WIN32-NEXT: calll _frexp
53 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
54 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
55 ; WIN32-NEXT: fstps (%esp)
56 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
57 ; WIN32-NEXT: calll ___gnu_f2h_ieee
58 ; WIN32-NEXT: movl %esi, %edx
59 ; WIN32-NEXT: addl $20, %esp
60 ; WIN32-NEXT: popl %esi
62 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
63 ret { half, i32 } %result
66 define half @test_frexp_f16_i32_only_use_fract(half %a) {
67 ; X64-LABEL: test_frexp_f16_i32_only_use_fract:
69 ; X64-NEXT: subq $24, %rsp
70 ; X64-NEXT: .cfi_def_cfa_offset 32
71 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
72 ; X64-NEXT: callq __extendhfsf2@PLT
73 ; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
74 ; X64-NEXT: callq __truncsfhf2@PLT
75 ; X64-NEXT: pextrw $0, %xmm0, %eax
76 ; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
77 ; X64-NEXT: pextrw $0, %xmm0, %ecx
78 ; X64-NEXT: movl %ecx, %edx
79 ; X64-NEXT: andl $32767, %edx # imm = 0x7FFF
80 ; X64-NEXT: cmpl $1024, %edx # imm = 0x400
81 ; X64-NEXT: cmovael %ecx, %eax
82 ; X64-NEXT: andl $-31745, %eax # imm = 0x83FF
83 ; X64-NEXT: orl $14336, %eax # imm = 0x3800
84 ; X64-NEXT: addl $-31744, %edx # imm = 0x8400
85 ; X64-NEXT: movzwl %dx, %edx
86 ; X64-NEXT: cmpl $33792, %edx # imm = 0x8400
87 ; X64-NEXT: cmovbel %ecx, %eax
88 ; X64-NEXT: pinsrw $0, %eax, %xmm0
89 ; X64-NEXT: addq $24, %rsp
90 ; X64-NEXT: .cfi_def_cfa_offset 8
93 ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
95 ; WIN32-NEXT: subl $20, %esp
96 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
97 ; WIN32-NEXT: movl %eax, (%esp)
98 ; WIN32-NEXT: calll ___gnu_h2f_ieee
99 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
100 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
101 ; WIN32-NEXT: fstpl (%esp)
102 ; WIN32-NEXT: calll _frexp
103 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
104 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
105 ; WIN32-NEXT: fstps (%esp)
106 ; WIN32-NEXT: calll ___gnu_f2h_ieee
107 ; WIN32-NEXT: addl $20, %esp
109 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
110 %result.0 = extractvalue { half, i32 } %result, 0
114 define i32 @test_frexp_f16_i32_only_use_exp(half %a) {
115 ; X64-LABEL: test_frexp_f16_i32_only_use_exp:
117 ; X64-NEXT: subq $24, %rsp
118 ; X64-NEXT: .cfi_def_cfa_offset 32
119 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
120 ; X64-NEXT: callq __extendhfsf2@PLT
121 ; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
122 ; X64-NEXT: callq __truncsfhf2@PLT
123 ; X64-NEXT: pextrw $0, %xmm0, %eax
124 ; X64-NEXT: andl $31744, %eax # imm = 0x7C00
125 ; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload
126 ; X64-NEXT: pextrw $0, %xmm0, %ecx
127 ; X64-NEXT: andl $32767, %ecx # imm = 0x7FFF
128 ; X64-NEXT: cmpl $1024, %ecx # imm = 0x400
129 ; X64-NEXT: cmovael %ecx, %eax
130 ; X64-NEXT: shrl $10, %eax
131 ; X64-NEXT: leal -12(%rax), %edx
132 ; X64-NEXT: cmpl $1024, %ecx # imm = 0x400
133 ; X64-NEXT: cmovael %eax, %edx
134 ; X64-NEXT: addl $-14, %edx
135 ; X64-NEXT: addl $-31744, %ecx # imm = 0x8400
136 ; X64-NEXT: movzwl %cx, %ecx
137 ; X64-NEXT: xorl %eax, %eax
138 ; X64-NEXT: cmpl $33792, %ecx # imm = 0x8400
139 ; X64-NEXT: cmoval %edx, %eax
140 ; X64-NEXT: addq $24, %rsp
141 ; X64-NEXT: .cfi_def_cfa_offset 8
144 ; WIN32-LABEL: test_frexp_f16_i32_only_use_exp:
146 ; WIN32-NEXT: subl $16, %esp
147 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
148 ; WIN32-NEXT: movl %eax, (%esp)
149 ; WIN32-NEXT: calll ___gnu_h2f_ieee
150 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
151 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
152 ; WIN32-NEXT: fstpl (%esp)
153 ; WIN32-NEXT: calll _frexp
154 ; WIN32-NEXT: fstp %st(0)
155 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
156 ; WIN32-NEXT: addl $16, %esp
158 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
159 %result.0 = extractvalue { half, i32 } %result, 1
164 ; define { <2 x half>, <2 x i32> } @test_frexp_v2f16_v2i32(<2 x half> %a) {
165 ; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
166 ; ret { <2 x half>, <2 x i32> } %result
169 ; define <2 x half> @test_frexp_v2f16_v2i32_only_use_fract(<2 x half> %a) {
170 ; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
171 ; %result.0 = extractvalue { <2 x half>, <2 x i32> } %result, 0
172 ; ret <2 x half> %result.0
175 ; define <2 x i32> @test_frexp_v2f16_v2i32_only_use_exp(<2 x half> %a) {
176 ; %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
177 ; %result.1 = extractvalue { <2 x half>, <2 x i32> } %result, 1
178 ; ret <2 x i32> %result.1
181 define { float, i32 } @test_frexp_f32_i32(float %a) {
182 ; X64-LABEL: test_frexp_f32_i32:
184 ; X64-NEXT: pushq %rax
185 ; X64-NEXT: .cfi_def_cfa_offset 16
186 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
187 ; X64-NEXT: callq frexpf@PLT
188 ; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
189 ; X64-NEXT: popq %rcx
190 ; X64-NEXT: .cfi_def_cfa_offset 8
193 ; WIN32-LABEL: test_frexp_f32_i32:
195 ; WIN32-NEXT: subl $20, %esp
196 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
197 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
198 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
199 ; WIN32-NEXT: fstpl (%esp)
200 ; WIN32-NEXT: calll _frexp
201 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
202 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
203 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
204 ; WIN32-NEXT: addl $20, %esp
206 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
207 ret { float, i32 } %result
210 define float @test_frexp_f32_i32_only_use_fract(float %a) {
211 ; X64-LABEL: test_frexp_f32_i32_only_use_fract:
213 ; X64-NEXT: pushq %rax
214 ; X64-NEXT: .cfi_def_cfa_offset 16
215 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
216 ; X64-NEXT: callq frexpf@PLT
217 ; X64-NEXT: popq %rax
218 ; X64-NEXT: .cfi_def_cfa_offset 8
221 ; WIN32-LABEL: test_frexp_f32_i32_only_use_fract:
223 ; WIN32-NEXT: subl $20, %esp
224 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
225 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
226 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
227 ; WIN32-NEXT: fstpl (%esp)
228 ; WIN32-NEXT: calll _frexp
229 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
230 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
231 ; WIN32-NEXT: addl $20, %esp
233 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
234 %result.0 = extractvalue { float, i32 } %result, 0
238 define i32 @test_frexp_f32_i32_only_use_exp(float %a) {
239 ; X64-LABEL: test_frexp_f32_i32_only_use_exp:
241 ; X64-NEXT: pushq %rax
242 ; X64-NEXT: .cfi_def_cfa_offset 16
243 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
244 ; X64-NEXT: callq frexpf@PLT
245 ; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
246 ; X64-NEXT: popq %rcx
247 ; X64-NEXT: .cfi_def_cfa_offset 8
250 ; WIN32-LABEL: test_frexp_f32_i32_only_use_exp:
252 ; WIN32-NEXT: subl $16, %esp
253 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
254 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
255 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
256 ; WIN32-NEXT: fstpl (%esp)
257 ; WIN32-NEXT: calll _frexp
258 ; WIN32-NEXT: fstp %st(0)
259 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
260 ; WIN32-NEXT: addl $16, %esp
262 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
263 %result.0 = extractvalue { float, i32 } %result, 1
267 ; FIXME: Widen vector result
268 ; define { <2 x float>, <2 x i32> } @test_frexp_v2f32_v2i32(<2 x float> %a) {
269 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
270 ; ret { <2 x float>, <2 x i32> } %result
273 ; define <2 x float> @test_frexp_v2f32_v2i32_only_use_fract(<2 x float> %a) {
274 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
275 ; %result.0 = extractvalue { <2 x float>, <2 x i32> } %result, 0
276 ; ret <2 x float> %result.0
279 ; define <2 x i32> @test_frexp_v2f32_v2i32_only_use_exp(<2 x float> %a) {
280 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
281 ; %result.1 = extractvalue { <2 x float>, <2 x i32> } %result, 1
282 ; ret <2 x i32> %result.1
285 define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) {
286 ; X64-LABEL: test_frexp_v4f32_v4i32:
288 ; X64-NEXT: subq $72, %rsp
289 ; X64-NEXT: .cfi_def_cfa_offset 80
290 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
291 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
292 ; X64-NEXT: movq %rsp, %rdi
293 ; X64-NEXT: callq frexpf@PLT
294 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
295 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
296 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
297 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
298 ; X64-NEXT: callq frexpf@PLT
299 ; X64-NEXT: unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
300 ; X64-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
301 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
302 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
303 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
304 ; X64-NEXT: callq frexpf@PLT
305 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
306 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
307 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
308 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
309 ; X64-NEXT: callq frexpf@PLT
310 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
311 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
312 ; X64-NEXT: unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
313 ; X64-NEXT: # xmm1 = xmm1[0],mem[0]
314 ; X64-NEXT: movaps %xmm1, %xmm0
315 ; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
316 ; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
317 ; X64-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
318 ; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
319 ; X64-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero
320 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
321 ; X64-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm2[0]
322 ; X64-NEXT: addq $72, %rsp
323 ; X64-NEXT: .cfi_def_cfa_offset 8
326 ; WIN32-LABEL: test_frexp_v4f32_v4i32:
328 ; WIN32-NEXT: pushl %edi
329 ; WIN32-NEXT: pushl %esi
330 ; WIN32-NEXT: subl $60, %esp
331 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
332 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
333 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
334 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
335 ; WIN32-NEXT: fstpl (%esp)
336 ; WIN32-NEXT: calll _frexp
337 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
338 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
339 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
340 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
341 ; WIN32-NEXT: fstpl (%esp)
342 ; WIN32-NEXT: calll _frexp
343 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
344 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
345 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
346 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
347 ; WIN32-NEXT: fstpl (%esp)
348 ; WIN32-NEXT: calll _frexp
349 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
350 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
351 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
352 ; WIN32-NEXT: fstpl (%esp)
353 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
354 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
355 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
356 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
357 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
358 ; WIN32-NEXT: calll _frexp
359 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
360 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
361 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
362 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
363 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
364 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
365 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
366 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
367 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
368 ; WIN32-NEXT: movl %edi, 28(%esi)
369 ; WIN32-NEXT: movl %edx, 24(%esi)
370 ; WIN32-NEXT: movl %ecx, 20(%esi)
371 ; WIN32-NEXT: movl %eax, 16(%esi)
372 ; WIN32-NEXT: fstps 12(%esi)
373 ; WIN32-NEXT: fstps 8(%esi)
374 ; WIN32-NEXT: fstps 4(%esi)
375 ; WIN32-NEXT: fstps (%esi)
376 ; WIN32-NEXT: movl %esi, %eax
377 ; WIN32-NEXT: addl $60, %esp
378 ; WIN32-NEXT: popl %esi
379 ; WIN32-NEXT: popl %edi
381 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
382 ret { <4 x float>, <4 x i32> } %result
385 define <4 x float> @test_frexp_v4f32_v4i32_only_use_fract(<4 x float> %a) {
386 ; X64-LABEL: test_frexp_v4f32_v4i32_only_use_fract:
388 ; X64-NEXT: subq $72, %rsp
389 ; X64-NEXT: .cfi_def_cfa_offset 80
390 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
391 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
392 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
393 ; X64-NEXT: callq frexpf@PLT
394 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
395 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
396 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
397 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
398 ; X64-NEXT: callq frexpf@PLT
399 ; X64-NEXT: unpcklps (%rsp), %xmm0 # 16-byte Folded Reload
400 ; X64-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
401 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
402 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
403 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
404 ; X64-NEXT: callq frexpf@PLT
405 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
406 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
407 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
408 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
409 ; X64-NEXT: callq frexpf@PLT
410 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
411 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
412 ; X64-NEXT: unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload
413 ; X64-NEXT: # xmm1 = xmm1[0],mem[0]
414 ; X64-NEXT: movaps %xmm1, %xmm0
415 ; X64-NEXT: addq $72, %rsp
416 ; X64-NEXT: .cfi_def_cfa_offset 8
419 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_fract:
421 ; WIN32-NEXT: pushl %esi
422 ; WIN32-NEXT: subl $60, %esp
423 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
424 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
425 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
426 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
427 ; WIN32-NEXT: fstpl (%esp)
428 ; WIN32-NEXT: calll _frexp
429 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
430 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
431 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
432 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
433 ; WIN32-NEXT: fstpl (%esp)
434 ; WIN32-NEXT: calll _frexp
435 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
436 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
437 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
438 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
439 ; WIN32-NEXT: fstpl (%esp)
440 ; WIN32-NEXT: calll _frexp
441 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
442 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
443 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
444 ; WIN32-NEXT: fstpl (%esp)
445 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
446 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
447 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
448 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
449 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
450 ; WIN32-NEXT: calll _frexp
451 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
452 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
453 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
454 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
455 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
456 ; WIN32-NEXT: fstps 12(%esi)
457 ; WIN32-NEXT: fstps 8(%esi)
458 ; WIN32-NEXT: fstps 4(%esi)
459 ; WIN32-NEXT: fstps (%esi)
460 ; WIN32-NEXT: movl %esi, %eax
461 ; WIN32-NEXT: addl $60, %esp
462 ; WIN32-NEXT: popl %esi
464 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
465 %result.0 = extractvalue { <4 x float>, <4 x i32> } %result, 0
466 ret <4 x float> %result.0
469 define <4 x i32> @test_frexp_v4f32_v4i32_only_use_exp(<4 x float> %a) {
470 ; X64-LABEL: test_frexp_v4f32_v4i32_only_use_exp:
472 ; X64-NEXT: subq $40, %rsp
473 ; X64-NEXT: .cfi_def_cfa_offset 48
474 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
475 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
476 ; X64-NEXT: movq %rsp, %rdi
477 ; X64-NEXT: callq frexpf@PLT
478 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
479 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
480 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
481 ; X64-NEXT: callq frexpf@PLT
482 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
483 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
484 ; X64-NEXT: callq frexpf@PLT
485 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
486 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
487 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
488 ; X64-NEXT: callq frexpf@PLT
489 ; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
490 ; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
491 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
492 ; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
493 ; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
494 ; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
495 ; X64-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]
496 ; X64-NEXT: addq $40, %rsp
497 ; X64-NEXT: .cfi_def_cfa_offset 8
500 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_exp:
502 ; WIN32-NEXT: pushl %edi
503 ; WIN32-NEXT: pushl %esi
504 ; WIN32-NEXT: subl $28, %esp
505 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
506 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
507 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
508 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
509 ; WIN32-NEXT: fstpl (%esp)
510 ; WIN32-NEXT: calll _frexp
511 ; WIN32-NEXT: fstp %st(0)
512 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
513 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
514 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
515 ; WIN32-NEXT: fstpl (%esp)
516 ; WIN32-NEXT: calll _frexp
517 ; WIN32-NEXT: fstp %st(0)
518 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
519 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
520 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
521 ; WIN32-NEXT: fstpl (%esp)
522 ; WIN32-NEXT: calll _frexp
523 ; WIN32-NEXT: fstp %st(0)
524 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
525 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
526 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
527 ; WIN32-NEXT: fstpl (%esp)
528 ; WIN32-NEXT: calll _frexp
529 ; WIN32-NEXT: fstp %st(0)
530 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
531 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx
532 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edx
533 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
534 ; WIN32-NEXT: movl %edi, 12(%esi)
535 ; WIN32-NEXT: movl %edx, 8(%esi)
536 ; WIN32-NEXT: movl %ecx, 4(%esi)
537 ; WIN32-NEXT: movl %eax, (%esi)
538 ; WIN32-NEXT: movl %esi, %eax
539 ; WIN32-NEXT: addl $28, %esp
540 ; WIN32-NEXT: popl %esi
541 ; WIN32-NEXT: popl %edi
543 %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
544 %result.1 = extractvalue { <4 x float>, <4 x i32> } %result, 1
545 ret <4 x i32> %result.1
548 define { double, i32 } @test_frexp_f64_i32(double %a) {
549 ; X64-LABEL: test_frexp_f64_i32:
551 ; X64-NEXT: pushq %rax
552 ; X64-NEXT: .cfi_def_cfa_offset 16
553 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
554 ; X64-NEXT: callq frexp@PLT
555 ; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
556 ; X64-NEXT: popq %rcx
557 ; X64-NEXT: .cfi_def_cfa_offset 8
560 ; WIN32-LABEL: test_frexp_f64_i32:
562 ; WIN32-NEXT: subl $16, %esp
563 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
564 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
565 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
566 ; WIN32-NEXT: fstpl (%esp)
567 ; WIN32-NEXT: calll _frexp
568 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
569 ; WIN32-NEXT: addl $16, %esp
571 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
572 ret { double, i32 } %result
575 define double @test_frexp_f64_i32_only_use_fract(double %a) {
576 ; X64-LABEL: test_frexp_f64_i32_only_use_fract:
578 ; X64-NEXT: pushq %rax
579 ; X64-NEXT: .cfi_def_cfa_offset 16
580 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
581 ; X64-NEXT: callq frexp@PLT
582 ; X64-NEXT: popq %rax
583 ; X64-NEXT: .cfi_def_cfa_offset 8
586 ; WIN32-LABEL: test_frexp_f64_i32_only_use_fract:
588 ; WIN32-NEXT: subl $16, %esp
589 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
590 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
591 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
592 ; WIN32-NEXT: fstpl (%esp)
593 ; WIN32-NEXT: calll _frexp
594 ; WIN32-NEXT: addl $16, %esp
596 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
597 %result.0 = extractvalue { double, i32 } %result, 0
601 define i32 @test_frexp_f64_i32_only_use_exp(double %a) {
602 ; X64-LABEL: test_frexp_f64_i32_only_use_exp:
604 ; X64-NEXT: pushq %rax
605 ; X64-NEXT: .cfi_def_cfa_offset 16
606 ; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi
607 ; X64-NEXT: callq frexp@PLT
608 ; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax
609 ; X64-NEXT: popq %rcx
610 ; X64-NEXT: .cfi_def_cfa_offset 8
613 ; WIN32-LABEL: test_frexp_f64_i32_only_use_exp:
615 ; WIN32-NEXT: subl $16, %esp
616 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
617 ; WIN32-NEXT: leal {{[0-9]+}}(%esp), %eax
618 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
619 ; WIN32-NEXT: fstpl (%esp)
620 ; WIN32-NEXT: calll _frexp
621 ; WIN32-NEXT: fstp %st(0)
622 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
623 ; WIN32-NEXT: addl $16, %esp
625 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
626 %result.0 = extractvalue { double, i32 } %result, 1
630 ; FIXME: Widen vector result
631 ; define { <2 x double>, <2 x i32> } @test_frexp_v2f64_v2i32(<2 x double> %a) {
632 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
633 ; ret { <2 x double>, <2 x i32> } %result
636 ; define <2 x double> @test_frexp_v2f64_v2i32_only_use_fract(<2 x double> %a) {
637 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
638 ; %result.0 = extractvalue { <2 x double>, <2 x i32> } %result, 0
639 ; ret <2 x double> %result.0
642 ; define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) {
643 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
644 ; %result.1 = extractvalue { <2 x double>, <2 x i32> } %result, 1
645 ; ret <2 x i32> %result.1
648 declare { float, i32 } @llvm.frexp.f32.i32(float) #0
649 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0
650 declare { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float>) #0
652 declare { half, i32 } @llvm.frexp.f16.i32(half) #0
653 declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0
655 declare { double, i32 } @llvm.frexp.f64.i32(double) #0
656 declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0
658 declare { half, i16 } @llvm.frexp.f16.i16(half) #0
659 declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0
661 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }