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 -verify-machineinstrs < %s | FileCheck -check-prefixes=X64 %s
3 ; RUN: llc -mtriple=x86_64-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefixes=WIN64 %s
4 ; RUN: llc -mtriple=i386-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefix=WIN32 %s
6 define float @ldexp_f32(i8 zeroext %x) {
7 ; X64-LABEL: ldexp_f32:
9 ; X64-NEXT: movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
10 ; X64-NEXT: jmp ldexpf@PLT # TAILCALL
12 ; WIN64-LABEL: ldexp_f32:
14 ; WIN64-NEXT: subq $40, %rsp
15 ; WIN64-NEXT: .seh_stackalloc 40
16 ; WIN64-NEXT: .seh_endprologue
17 ; WIN64-NEXT: movzbl %cl, %edx
18 ; WIN64-NEXT: movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
19 ; WIN64-NEXT: callq ldexp
20 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm0
21 ; WIN64-NEXT: addq $40, %rsp
23 ; WIN64-NEXT: .seh_endproc
25 ; WIN32-LABEL: ldexp_f32:
27 ; WIN32-NEXT: subl $16, %esp
28 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
29 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
31 ; WIN32-NEXT: fstpl (%esp)
32 ; WIN32-NEXT: calll _ldexp
33 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
34 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
35 ; WIN32-NEXT: addl $16, %esp
37 %zext = zext i8 %x to i32
38 %ldexp = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 %zext)
42 define double @ldexp_f64(i8 zeroext %x) {
43 ; X64-LABEL: ldexp_f64:
45 ; X64-NEXT: movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
46 ; X64-NEXT: jmp ldexp@PLT # TAILCALL
48 ; WIN64-LABEL: ldexp_f64:
50 ; WIN64-NEXT: movzbl %cl, %edx
51 ; WIN64-NEXT: movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
52 ; WIN64-NEXT: jmp ldexp # TAILCALL
54 ; WIN32-LABEL: ldexp_f64:
56 ; WIN32-NEXT: subl $12, %esp
57 ; WIN32-NEXT: movzbl {{[0-9]+}}(%esp), %eax
58 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
60 ; WIN32-NEXT: fstpl (%esp)
61 ; WIN32-NEXT: calll _ldexp
62 ; WIN32-NEXT: addl $12, %esp
64 %zext = zext i8 %x to i32
65 %ldexp = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 %zext)
69 define <2 x float> @ldexp_v2f32(<2 x float> %val, <2 x i32> %exp) {
70 ; X64-LABEL: ldexp_v2f32:
72 ; X64-NEXT: subq $56, %rsp
73 ; X64-NEXT: .cfi_def_cfa_offset 64
74 ; X64-NEXT: movdqa %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
75 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
76 ; X64-NEXT: movd %xmm1, %edi
77 ; X64-NEXT: callq ldexpf@PLT
78 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
79 ; X64-NEXT: movaps (%rsp), %xmm0 # 16-byte Reload
80 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
81 ; X64-NEXT: pshufd $85, {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
82 ; X64-NEXT: # xmm1 = mem[1,1,1,1]
83 ; X64-NEXT: movd %xmm1, %edi
84 ; X64-NEXT: callq ldexpf@PLT
85 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
86 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
87 ; X64-NEXT: movaps %xmm1, %xmm0
88 ; X64-NEXT: addq $56, %rsp
89 ; X64-NEXT: .cfi_def_cfa_offset 8
92 ; WIN64-LABEL: ldexp_v2f32:
94 ; WIN64-NEXT: pushq %rsi
95 ; WIN64-NEXT: .seh_pushreg %rsi
96 ; WIN64-NEXT: subq $80, %rsp
97 ; WIN64-NEXT: .seh_stackalloc 80
98 ; WIN64-NEXT: movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
99 ; WIN64-NEXT: .seh_savexmm %xmm8, 64
100 ; WIN64-NEXT: movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
101 ; WIN64-NEXT: .seh_savexmm %xmm7, 48
102 ; WIN64-NEXT: movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
103 ; WIN64-NEXT: .seh_savexmm %xmm6, 32
104 ; WIN64-NEXT: .seh_endprologue
105 ; WIN64-NEXT: movq %rdx, %rsi
106 ; WIN64-NEXT: movaps (%rcx), %xmm7
107 ; WIN64-NEXT: movl 12(%rdx), %edx
108 ; WIN64-NEXT: movaps %xmm7, %xmm0
109 ; WIN64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3],xmm7[3,3]
110 ; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
111 ; WIN64-NEXT: callq ldexp
112 ; WIN64-NEXT: xorps %xmm6, %xmm6
113 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm6
114 ; WIN64-NEXT: movl 8(%rsi), %edx
115 ; WIN64-NEXT: movaps %xmm7, %xmm0
116 ; WIN64-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm7[1]
117 ; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
118 ; WIN64-NEXT: callq ldexp
119 ; WIN64-NEXT: xorps %xmm8, %xmm8
120 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm8
121 ; WIN64-NEXT: unpcklps {{.*#+}} xmm8 = xmm8[0],xmm6[0],xmm8[1],xmm6[1]
122 ; WIN64-NEXT: movl (%rsi), %edx
123 ; WIN64-NEXT: movl 4(%rsi), %esi
124 ; WIN64-NEXT: xorps %xmm0, %xmm0
125 ; WIN64-NEXT: cvtss2sd %xmm7, %xmm0
126 ; WIN64-NEXT: callq ldexp
127 ; WIN64-NEXT: xorps %xmm6, %xmm6
128 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm6
129 ; WIN64-NEXT: shufps {{.*#+}} xmm7 = xmm7[1,1,1,1]
130 ; WIN64-NEXT: xorps %xmm0, %xmm0
131 ; WIN64-NEXT: cvtss2sd %xmm7, %xmm0
132 ; WIN64-NEXT: movl %esi, %edx
133 ; WIN64-NEXT: callq ldexp
134 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm0
135 ; WIN64-NEXT: unpcklps {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1]
136 ; WIN64-NEXT: movlhps {{.*#+}} xmm6 = xmm6[0],xmm8[0]
137 ; WIN64-NEXT: movaps %xmm6, %xmm0
138 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
139 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
140 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
141 ; WIN64-NEXT: addq $80, %rsp
142 ; WIN64-NEXT: popq %rsi
144 ; WIN64-NEXT: .seh_endproc
146 ; WIN32-LABEL: ldexp_v2f32:
148 ; WIN32-NEXT: pushl %esi
149 ; WIN32-NEXT: subl $20, %esp
150 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
151 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
152 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
153 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
154 ; WIN32-NEXT: fstpl (%esp)
155 ; WIN32-NEXT: calll _ldexp
156 ; WIN32-NEXT: movl %esi, {{[0-9]+}}(%esp)
157 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
158 ; WIN32-NEXT: fstpl (%esp)
159 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
160 ; WIN32-NEXT: calll _ldexp
161 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
162 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
163 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
164 ; WIN32-NEXT: addl $20, %esp
165 ; WIN32-NEXT: popl %esi
167 %1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp)
171 define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) {
172 ; X64-LABEL: ldexp_v4f32:
174 ; X64-NEXT: subq $72, %rsp
175 ; X64-NEXT: .cfi_def_cfa_offset 80
176 ; X64-NEXT: movdqa %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
177 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
178 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
179 ; X64-NEXT: pshufd {{.*#+}} xmm2 = xmm1[3,3,3,3]
180 ; X64-NEXT: movd %xmm2, %edi
181 ; X64-NEXT: callq ldexpf@PLT
182 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
183 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
184 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
185 ; X64-NEXT: pshufd $238, {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
186 ; X64-NEXT: # xmm1 = mem[2,3,2,3]
187 ; X64-NEXT: movd %xmm1, %edi
188 ; X64-NEXT: callq ldexpf@PLT
189 ; X64-NEXT: unpcklps (%rsp), %xmm0 # 16-byte Folded Reload
190 ; X64-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
191 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
192 ; X64-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
193 ; X64-NEXT: movd %xmm0, %edi
194 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
195 ; X64-NEXT: callq ldexpf@PLT
196 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
197 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
198 ; X64-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
199 ; X64-NEXT: pshufd $85, {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
200 ; X64-NEXT: # xmm1 = mem[1,1,1,1]
201 ; X64-NEXT: movd %xmm1, %edi
202 ; X64-NEXT: callq ldexpf@PLT
203 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
204 ; X64-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
205 ; X64-NEXT: unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload
206 ; X64-NEXT: # xmm1 = xmm1[0],mem[0]
207 ; X64-NEXT: movaps %xmm1, %xmm0
208 ; X64-NEXT: addq $72, %rsp
209 ; X64-NEXT: .cfi_def_cfa_offset 8
212 ; WIN64-LABEL: ldexp_v4f32:
214 ; WIN64-NEXT: pushq %rsi
215 ; WIN64-NEXT: .seh_pushreg %rsi
216 ; WIN64-NEXT: subq $80, %rsp
217 ; WIN64-NEXT: .seh_stackalloc 80
218 ; WIN64-NEXT: movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
219 ; WIN64-NEXT: .seh_savexmm %xmm8, 64
220 ; WIN64-NEXT: movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
221 ; WIN64-NEXT: .seh_savexmm %xmm7, 48
222 ; WIN64-NEXT: movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
223 ; WIN64-NEXT: .seh_savexmm %xmm6, 32
224 ; WIN64-NEXT: .seh_endprologue
225 ; WIN64-NEXT: movq %rdx, %rsi
226 ; WIN64-NEXT: movaps (%rcx), %xmm7
227 ; WIN64-NEXT: movl 12(%rdx), %edx
228 ; WIN64-NEXT: movaps %xmm7, %xmm0
229 ; WIN64-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,3],xmm7[3,3]
230 ; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
231 ; WIN64-NEXT: callq ldexp
232 ; WIN64-NEXT: xorps %xmm6, %xmm6
233 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm6
234 ; WIN64-NEXT: movl 8(%rsi), %edx
235 ; WIN64-NEXT: movaps %xmm7, %xmm0
236 ; WIN64-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm7[1]
237 ; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
238 ; WIN64-NEXT: callq ldexp
239 ; WIN64-NEXT: xorps %xmm8, %xmm8
240 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm8
241 ; WIN64-NEXT: unpcklps {{.*#+}} xmm8 = xmm8[0],xmm6[0],xmm8[1],xmm6[1]
242 ; WIN64-NEXT: movl (%rsi), %edx
243 ; WIN64-NEXT: movl 4(%rsi), %esi
244 ; WIN64-NEXT: xorps %xmm0, %xmm0
245 ; WIN64-NEXT: cvtss2sd %xmm7, %xmm0
246 ; WIN64-NEXT: callq ldexp
247 ; WIN64-NEXT: xorps %xmm6, %xmm6
248 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm6
249 ; WIN64-NEXT: shufps {{.*#+}} xmm7 = xmm7[1,1,1,1]
250 ; WIN64-NEXT: xorps %xmm0, %xmm0
251 ; WIN64-NEXT: cvtss2sd %xmm7, %xmm0
252 ; WIN64-NEXT: movl %esi, %edx
253 ; WIN64-NEXT: callq ldexp
254 ; WIN64-NEXT: cvtsd2ss %xmm0, %xmm0
255 ; WIN64-NEXT: unpcklps {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1]
256 ; WIN64-NEXT: movlhps {{.*#+}} xmm6 = xmm6[0],xmm8[0]
257 ; WIN64-NEXT: movaps %xmm6, %xmm0
258 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
259 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
260 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
261 ; WIN64-NEXT: addq $80, %rsp
262 ; WIN64-NEXT: popq %rsi
264 ; WIN64-NEXT: .seh_endproc
266 ; WIN32-LABEL: ldexp_v4f32:
268 ; WIN32-NEXT: pushl %ebp
269 ; WIN32-NEXT: pushl %ebx
270 ; WIN32-NEXT: pushl %edi
271 ; WIN32-NEXT: pushl %esi
272 ; WIN32-NEXT: subl $44, %esp
273 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
274 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
275 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx
276 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
277 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
278 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
279 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
280 ; WIN32-NEXT: fstpl (%esp)
281 ; WIN32-NEXT: calll _ldexp
282 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
283 ; WIN32-NEXT: movl %ebp, {{[0-9]+}}(%esp)
284 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
285 ; WIN32-NEXT: fstpl (%esp)
286 ; WIN32-NEXT: calll _ldexp
287 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
288 ; WIN32-NEXT: movl %ebx, {{[0-9]+}}(%esp)
289 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
290 ; WIN32-NEXT: fstpl (%esp)
291 ; WIN32-NEXT: calll _ldexp
292 ; WIN32-NEXT: movl %edi, {{[0-9]+}}(%esp)
293 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
294 ; WIN32-NEXT: fstpl (%esp)
295 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
296 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
297 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
298 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
299 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
300 ; WIN32-NEXT: calll _ldexp
301 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
302 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
303 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
304 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
305 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
306 ; WIN32-NEXT: fstps 12(%esi)
307 ; WIN32-NEXT: fstps 8(%esi)
308 ; WIN32-NEXT: fstps 4(%esi)
309 ; WIN32-NEXT: fstps (%esi)
310 ; WIN32-NEXT: movl %esi, %eax
311 ; WIN32-NEXT: addl $44, %esp
312 ; WIN32-NEXT: popl %esi
313 ; WIN32-NEXT: popl %edi
314 ; WIN32-NEXT: popl %ebx
315 ; WIN32-NEXT: popl %ebp
317 %1 = call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> %val, <4 x i32> %exp)
321 define <2 x double> @ldexp_v2f64(<2 x double> %val, <2 x i32> %exp) {
322 ; X64-LABEL: ldexp_v2f64:
324 ; X64-NEXT: subq $56, %rsp
325 ; X64-NEXT: .cfi_def_cfa_offset 64
326 ; X64-NEXT: movdqa %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
327 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
328 ; X64-NEXT: movd %xmm1, %edi
329 ; X64-NEXT: callq ldexp@PLT
330 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
331 ; X64-NEXT: movaps (%rsp), %xmm0 # 16-byte Reload
332 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
333 ; X64-NEXT: pshufd $85, {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
334 ; X64-NEXT: # xmm1 = mem[1,1,1,1]
335 ; X64-NEXT: movd %xmm1, %edi
336 ; X64-NEXT: callq ldexp@PLT
337 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
338 ; X64-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
339 ; X64-NEXT: movaps %xmm1, %xmm0
340 ; X64-NEXT: addq $56, %rsp
341 ; X64-NEXT: .cfi_def_cfa_offset 8
344 ; WIN64-LABEL: ldexp_v2f64:
346 ; WIN64-NEXT: pushq %rsi
347 ; WIN64-NEXT: .seh_pushreg %rsi
348 ; WIN64-NEXT: subq $64, %rsp
349 ; WIN64-NEXT: .seh_stackalloc 64
350 ; WIN64-NEXT: movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
351 ; WIN64-NEXT: .seh_savexmm %xmm7, 48
352 ; WIN64-NEXT: movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
353 ; WIN64-NEXT: .seh_savexmm %xmm6, 32
354 ; WIN64-NEXT: .seh_endprologue
355 ; WIN64-NEXT: movaps (%rcx), %xmm6
356 ; WIN64-NEXT: movl (%rdx), %eax
357 ; WIN64-NEXT: movl 4(%rdx), %esi
358 ; WIN64-NEXT: movaps %xmm6, %xmm0
359 ; WIN64-NEXT: movl %eax, %edx
360 ; WIN64-NEXT: callq ldexp
361 ; WIN64-NEXT: movaps %xmm0, %xmm7
362 ; WIN64-NEXT: movhlps {{.*#+}} xmm6 = xmm6[1,1]
363 ; WIN64-NEXT: movaps %xmm6, %xmm0
364 ; WIN64-NEXT: movl %esi, %edx
365 ; WIN64-NEXT: callq ldexp
366 ; WIN64-NEXT: movlhps {{.*#+}} xmm7 = xmm7[0],xmm0[0]
367 ; WIN64-NEXT: movaps %xmm7, %xmm0
368 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
369 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
370 ; WIN64-NEXT: addq $64, %rsp
371 ; WIN64-NEXT: popq %rsi
373 ; WIN64-NEXT: .seh_endproc
375 ; WIN32-LABEL: ldexp_v2f64:
377 ; WIN32-NEXT: pushl %esi
378 ; WIN32-NEXT: subl $28, %esp
379 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
380 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
381 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
382 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
383 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
384 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
385 ; WIN32-NEXT: fstpl (%esp)
386 ; WIN32-NEXT: calll _ldexp
387 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
388 ; WIN32-NEXT: movl %esi, {{[0-9]+}}(%esp)
389 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
390 ; WIN32-NEXT: fstpl (%esp)
391 ; WIN32-NEXT: calll _ldexp
392 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
393 ; WIN32-NEXT: fxch %st(1)
394 ; WIN32-NEXT: addl $28, %esp
395 ; WIN32-NEXT: popl %esi
397 %1 = call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> %val, <2 x i32> %exp)
401 define <4 x double> @ldexp_v4f64(<4 x double> %val, <4 x i32> %exp) {
402 ; X64-LABEL: ldexp_v4f64:
404 ; X64-NEXT: pushq %rbp
405 ; X64-NEXT: .cfi_def_cfa_offset 16
406 ; X64-NEXT: pushq %rbx
407 ; X64-NEXT: .cfi_def_cfa_offset 24
408 ; X64-NEXT: subq $72, %rsp
409 ; X64-NEXT: .cfi_def_cfa_offset 96
410 ; X64-NEXT: .cfi_offset %rbx, -24
411 ; X64-NEXT: .cfi_offset %rbp, -16
412 ; X64-NEXT: movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
413 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
414 ; X64-NEXT: movdqa %xmm2, (%rsp) # 16-byte Spill
415 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm2[2,3,2,3]
416 ; X64-NEXT: movd %xmm1, %ebx
417 ; X64-NEXT: pshufd {{.*#+}} xmm1 = xmm2[3,3,3,3]
418 ; X64-NEXT: movd %xmm1, %ebp
419 ; X64-NEXT: movd %xmm2, %edi
420 ; X64-NEXT: callq ldexp@PLT
421 ; X64-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
422 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
423 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
424 ; X64-NEXT: pshufd $85, (%rsp), %xmm1 # 16-byte Folded Reload
425 ; X64-NEXT: # xmm1 = mem[1,1,1,1]
426 ; X64-NEXT: movd %xmm1, %edi
427 ; X64-NEXT: callq ldexp@PLT
428 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
429 ; X64-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
430 ; X64-NEXT: movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
431 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
432 ; X64-NEXT: movhlps {{.*#+}} xmm0 = xmm0[1,1]
433 ; X64-NEXT: movl %ebp, %edi
434 ; X64-NEXT: callq ldexp@PLT
435 ; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
436 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
437 ; X64-NEXT: movl %ebx, %edi
438 ; X64-NEXT: callq ldexp@PLT
439 ; X64-NEXT: movaps %xmm0, %xmm1
440 ; X64-NEXT: unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload
441 ; X64-NEXT: # xmm1 = xmm1[0],mem[0]
442 ; X64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
443 ; X64-NEXT: addq $72, %rsp
444 ; X64-NEXT: .cfi_def_cfa_offset 24
445 ; X64-NEXT: popq %rbx
446 ; X64-NEXT: .cfi_def_cfa_offset 16
447 ; X64-NEXT: popq %rbp
448 ; X64-NEXT: .cfi_def_cfa_offset 8
451 ; WIN64-LABEL: ldexp_v4f64:
453 ; WIN64-NEXT: pushq %rsi
454 ; WIN64-NEXT: .seh_pushreg %rsi
455 ; WIN64-NEXT: pushq %rdi
456 ; WIN64-NEXT: .seh_pushreg %rdi
457 ; WIN64-NEXT: pushq %rbx
458 ; WIN64-NEXT: .seh_pushreg %rbx
459 ; WIN64-NEXT: subq $80, %rsp
460 ; WIN64-NEXT: .seh_stackalloc 80
461 ; WIN64-NEXT: movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
462 ; WIN64-NEXT: .seh_savexmm %xmm8, 64
463 ; WIN64-NEXT: movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
464 ; WIN64-NEXT: .seh_savexmm %xmm7, 48
465 ; WIN64-NEXT: movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
466 ; WIN64-NEXT: .seh_savexmm %xmm6, 32
467 ; WIN64-NEXT: .seh_endprologue
468 ; WIN64-NEXT: movl 12(%r8), %esi
469 ; WIN64-NEXT: movl 8(%r8), %edi
470 ; WIN64-NEXT: movaps (%rdx), %xmm6
471 ; WIN64-NEXT: movaps (%rcx), %xmm7
472 ; WIN64-NEXT: movl (%r8), %edx
473 ; WIN64-NEXT: movl 4(%r8), %ebx
474 ; WIN64-NEXT: movaps %xmm7, %xmm0
475 ; WIN64-NEXT: callq ldexp
476 ; WIN64-NEXT: movaps %xmm0, %xmm8
477 ; WIN64-NEXT: movhlps {{.*#+}} xmm7 = xmm7[1,1]
478 ; WIN64-NEXT: movaps %xmm7, %xmm0
479 ; WIN64-NEXT: movl %ebx, %edx
480 ; WIN64-NEXT: callq ldexp
481 ; WIN64-NEXT: movlhps {{.*#+}} xmm8 = xmm8[0],xmm0[0]
482 ; WIN64-NEXT: movaps %xmm6, %xmm0
483 ; WIN64-NEXT: movl %edi, %edx
484 ; WIN64-NEXT: callq ldexp
485 ; WIN64-NEXT: movaps %xmm0, %xmm7
486 ; WIN64-NEXT: movhlps {{.*#+}} xmm6 = xmm6[1,1]
487 ; WIN64-NEXT: movaps %xmm6, %xmm0
488 ; WIN64-NEXT: movl %esi, %edx
489 ; WIN64-NEXT: callq ldexp
490 ; WIN64-NEXT: movlhps {{.*#+}} xmm7 = xmm7[0],xmm0[0]
491 ; WIN64-NEXT: movaps %xmm8, %xmm0
492 ; WIN64-NEXT: movaps %xmm7, %xmm1
493 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
494 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
495 ; WIN64-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
496 ; WIN64-NEXT: addq $80, %rsp
497 ; WIN64-NEXT: popq %rbx
498 ; WIN64-NEXT: popq %rdi
499 ; WIN64-NEXT: popq %rsi
501 ; WIN64-NEXT: .seh_endproc
503 ; WIN32-LABEL: ldexp_v4f64:
505 ; WIN32-NEXT: pushl %ebp
506 ; WIN32-NEXT: pushl %ebx
507 ; WIN32-NEXT: pushl %edi
508 ; WIN32-NEXT: pushl %esi
509 ; WIN32-NEXT: subl $44, %esp
510 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
511 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
512 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
513 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %edi
514 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
515 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
516 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebx
517 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
518 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
519 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %ebp
520 ; WIN32-NEXT: fldl {{[0-9]+}}(%esp)
521 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %eax
522 ; WIN32-NEXT: movl %eax, {{[0-9]+}}(%esp)
523 ; WIN32-NEXT: fstpl (%esp)
524 ; WIN32-NEXT: calll _ldexp
525 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
526 ; WIN32-NEXT: movl %ebp, {{[0-9]+}}(%esp)
527 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
528 ; WIN32-NEXT: fstpl (%esp)
529 ; WIN32-NEXT: calll _ldexp
530 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
531 ; WIN32-NEXT: movl %ebx, {{[0-9]+}}(%esp)
532 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
533 ; WIN32-NEXT: fstpl (%esp)
534 ; WIN32-NEXT: calll _ldexp
535 ; WIN32-NEXT: fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
536 ; WIN32-NEXT: movl %edi, {{[0-9]+}}(%esp)
537 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
538 ; WIN32-NEXT: fstpl (%esp)
539 ; WIN32-NEXT: calll _ldexp
540 ; WIN32-NEXT: fstpl 24(%esi)
541 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
542 ; WIN32-NEXT: fstpl 16(%esi)
543 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
544 ; WIN32-NEXT: fstpl 8(%esi)
545 ; WIN32-NEXT: fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
546 ; WIN32-NEXT: fstpl (%esi)
547 ; WIN32-NEXT: movl %esi, %eax
548 ; WIN32-NEXT: addl $44, %esp
549 ; WIN32-NEXT: popl %esi
550 ; WIN32-NEXT: popl %edi
551 ; WIN32-NEXT: popl %ebx
552 ; WIN32-NEXT: popl %ebp
554 %1 = call <4 x double> @llvm.ldexp.v4f64.v4i32(<4 x double> %val, <4 x i32> %exp)
558 define half @ldexp_f16(half %arg0, i32 %arg1) {
559 ; X64-LABEL: ldexp_f16:
561 ; X64-NEXT: pushq %rbx
562 ; X64-NEXT: .cfi_def_cfa_offset 16
563 ; X64-NEXT: .cfi_offset %rbx, -16
564 ; X64-NEXT: movl %edi, %ebx
565 ; X64-NEXT: callq __extendhfsf2@PLT
566 ; X64-NEXT: movl %ebx, %edi
567 ; X64-NEXT: callq ldexpf@PLT
568 ; X64-NEXT: callq __truncsfhf2@PLT
569 ; X64-NEXT: popq %rbx
570 ; X64-NEXT: .cfi_def_cfa_offset 8
573 ; WIN64-LABEL: ldexp_f16:
575 ; WIN64-NEXT: pushq %rsi
576 ; WIN64-NEXT: .seh_pushreg %rsi
577 ; WIN64-NEXT: subq $32, %rsp
578 ; WIN64-NEXT: .seh_stackalloc 32
579 ; WIN64-NEXT: .seh_endprologue
580 ; WIN64-NEXT: movl %edx, %esi
581 ; WIN64-NEXT: callq __extendhfsf2
582 ; WIN64-NEXT: cvtss2sd %xmm0, %xmm0
583 ; WIN64-NEXT: movl %esi, %edx
584 ; WIN64-NEXT: callq ldexp
585 ; WIN64-NEXT: callq __truncdfhf2
587 ; WIN64-NEXT: addq $32, %rsp
588 ; WIN64-NEXT: popq %rsi
590 ; WIN64-NEXT: .seh_endproc
592 ; WIN32-LABEL: ldexp_f16:
594 ; WIN32-NEXT: pushl %esi
595 ; WIN32-NEXT: subl $16, %esp
596 ; WIN32-NEXT: movl {{[0-9]+}}(%esp), %esi
597 ; WIN32-NEXT: movzwl {{[0-9]+}}(%esp), %eax
598 ; WIN32-NEXT: movl %eax, (%esp)
599 ; WIN32-NEXT: calll ___gnu_h2f_ieee
600 ; WIN32-NEXT: movl %esi, {{[0-9]+}}(%esp)
601 ; WIN32-NEXT: fstpl (%esp)
602 ; WIN32-NEXT: calll _ldexp
603 ; WIN32-NEXT: fstps {{[0-9]+}}(%esp)
604 ; WIN32-NEXT: flds {{[0-9]+}}(%esp)
605 ; WIN32-NEXT: fstps (%esp)
606 ; WIN32-NEXT: calll ___gnu_f2h_ieee
607 ; WIN32-NEXT: addl $16, %esp
608 ; WIN32-NEXT: popl %esi
610 %ldexp = call half @llvm.ldexp.f16.i32(half %arg0, i32 %arg1)
614 declare double @llvm.ldexp.f64.i32(double, i32) #0
615 declare float @llvm.ldexp.f32.i32(float, i32) #0
616 declare <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float>, <2 x i32>) #0
617 declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>) #0
618 declare <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double>, <2 x i32>) #0
619 declare <4 x double> @llvm.ldexp.v4f64.v4i32(<4 x double>, <4 x i32>) #0
620 declare half @llvm.ldexp.f16.i32(half, i32) #0
622 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
623 attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }