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