Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / X86 / llvm.frexp.ll
blobcd560ad627de4cec6dc91b2145c13b39671c48e8
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:
7 ; X64:       # %bb.0:
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
40 ; X64-NEXT:    retq
42 ; WIN32-LABEL: test_frexp_f16_i32:
43 ; WIN32:       # %bb.0:
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
61 ; WIN32-NEXT:    retl
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:
68 ; X64:       # %bb.0:
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
91 ; X64-NEXT:    retq
93 ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
94 ; WIN32:       # %bb.0:
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
108 ; WIN32-NEXT:    retl
109   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
110   %result.0 = extractvalue { half, i32 } %result, 0
111   ret half %result.0
114 define i32 @test_frexp_f16_i32_only_use_exp(half %a) {
115 ; X64-LABEL: test_frexp_f16_i32_only_use_exp:
116 ; X64:       # %bb.0:
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
142 ; X64-NEXT:    retq
144 ; WIN32-LABEL: test_frexp_f16_i32_only_use_exp:
145 ; WIN32:       # %bb.0:
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
157 ; WIN32-NEXT:    retl
158   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
159   %result.0 = extractvalue { half, i32 } %result, 1
160   ret i32 %result.0
163 ; FIXME
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
167 ; }
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
173 ; }
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
179 ; }
181 define { float, i32 } @test_frexp_f32_i32(float %a) {
182 ; X64-LABEL: test_frexp_f32_i32:
183 ; X64:       # %bb.0:
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
191 ; X64-NEXT:    retq
193 ; WIN32-LABEL: test_frexp_f32_i32:
194 ; WIN32:       # %bb.0:
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
205 ; WIN32-NEXT:    retl
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:
212 ; X64:       # %bb.0:
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
219 ; X64-NEXT:    retq
221 ; WIN32-LABEL: test_frexp_f32_i32_only_use_fract:
222 ; WIN32:       # %bb.0:
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
232 ; WIN32-NEXT:    retl
233   %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
234   %result.0 = extractvalue { float, i32 } %result, 0
235   ret float %result.0
238 define i32 @test_frexp_f32_i32_only_use_exp(float %a) {
239 ; X64-LABEL: test_frexp_f32_i32_only_use_exp:
240 ; X64:       # %bb.0:
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
248 ; X64-NEXT:    retq
250 ; WIN32-LABEL: test_frexp_f32_i32_only_use_exp:
251 ; WIN32:       # %bb.0:
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
261 ; WIN32-NEXT:    retl
262   %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
263   %result.0 = extractvalue { float, i32 } %result, 1
264   ret i32 %result.0
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
271 ; }
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
277 ; }
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
283 ; }
285 define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) {
286 ; X64-LABEL: test_frexp_v4f32_v4i32:
287 ; X64:       # %bb.0:
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
324 ; X64-NEXT:    retq
326 ; WIN32-LABEL: test_frexp_v4f32_v4i32:
327 ; WIN32:       # %bb.0:
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
380 ; WIN32-NEXT:    retl
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:
387 ; X64:       # %bb.0:
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
417 ; X64-NEXT:    retq
419 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_fract:
420 ; WIN32:       # %bb.0:
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
463 ; WIN32-NEXT:    retl
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:
471 ; X64:       # %bb.0:
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
498 ; X64-NEXT:    retq
500 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_exp:
501 ; WIN32:       # %bb.0:
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
542 ; WIN32-NEXT:    retl
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:
550 ; X64:       # %bb.0:
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
558 ; X64-NEXT:    retq
560 ; WIN32-LABEL: test_frexp_f64_i32:
561 ; WIN32:       # %bb.0:
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
570 ; WIN32-NEXT:    retl
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:
577 ; X64:       # %bb.0:
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
584 ; X64-NEXT:    retq
586 ; WIN32-LABEL: test_frexp_f64_i32_only_use_fract:
587 ; WIN32:       # %bb.0:
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
595 ; WIN32-NEXT:    retl
596   %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
597   %result.0 = extractvalue { double, i32 } %result, 0
598   ret double %result.0
601 define i32 @test_frexp_f64_i32_only_use_exp(double %a) {
602 ; X64-LABEL: test_frexp_f64_i32_only_use_exp:
603 ; X64:       # %bb.0:
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
611 ; X64-NEXT:    retq
613 ; WIN32-LABEL: test_frexp_f64_i32_only_use_exp:
614 ; WIN32:       # %bb.0:
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
624 ; WIN32-NEXT:    retl
625   %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
626   %result.0 = extractvalue { double, i32 } %result, 1
627   ret i32 %result.0
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
634 ; }
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
640 ; }
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
646 ; }
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) }