1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
3 ; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s
5 define { half, i32 } @test_frexp_f16_i32(half %a) {
6 ; CHECK-LABEL: test_frexp_f16_i32:
9 ; CHECK-NEXT: stdu r1, -48(r1)
10 ; CHECK-NEXT: std r0, 64(r1)
11 ; CHECK-NEXT: .cfi_def_cfa_offset 48
12 ; CHECK-NEXT: .cfi_offset lr, 16
13 ; CHECK-NEXT: xscvdphp f0, f1
14 ; CHECK-NEXT: addi r4, r1, 44
15 ; CHECK-NEXT: mffprwz r3, f0
16 ; CHECK-NEXT: clrlwi r3, r3, 16
17 ; CHECK-NEXT: mtfprwz f0, r3
18 ; CHECK-NEXT: xscvhpdp f1, f0
19 ; CHECK-NEXT: bl frexpf
21 ; CHECK-NEXT: lwz r3, 44(r1)
22 ; CHECK-NEXT: addi r1, r1, 48
23 ; CHECK-NEXT: ld r0, 16(r1)
26 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
27 ret { half, i32 } %result
30 define half @test_frexp_f16_i32_only_use_fract(half %a) {
31 ; CHECK-LABEL: test_frexp_f16_i32_only_use_fract:
34 ; CHECK-NEXT: stdu r1, -48(r1)
35 ; CHECK-NEXT: std r0, 64(r1)
36 ; CHECK-NEXT: .cfi_def_cfa_offset 48
37 ; CHECK-NEXT: .cfi_offset lr, 16
38 ; CHECK-NEXT: xscvdphp f0, f1
39 ; CHECK-NEXT: addi r4, r1, 44
40 ; CHECK-NEXT: mffprwz r3, f0
41 ; CHECK-NEXT: clrlwi r3, r3, 16
42 ; CHECK-NEXT: mtfprwz f0, r3
43 ; CHECK-NEXT: xscvhpdp f1, f0
44 ; CHECK-NEXT: bl frexpf
46 ; CHECK-NEXT: addi r1, r1, 48
47 ; CHECK-NEXT: ld r0, 16(r1)
50 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
51 %result.0 = extractvalue { half, i32 } %result, 0
55 define i32 @test_frexp_f16_i32_only_use_exp(half %a) {
56 ; CHECK-LABEL: test_frexp_f16_i32_only_use_exp:
59 ; CHECK-NEXT: stdu r1, -48(r1)
60 ; CHECK-NEXT: std r0, 64(r1)
61 ; CHECK-NEXT: .cfi_def_cfa_offset 48
62 ; CHECK-NEXT: .cfi_offset lr, 16
63 ; CHECK-NEXT: xscvdphp f0, f1
64 ; CHECK-NEXT: addi r4, r1, 44
65 ; CHECK-NEXT: mffprwz r3, f0
66 ; CHECK-NEXT: clrlwi r3, r3, 16
67 ; CHECK-NEXT: mtfprwz f0, r3
68 ; CHECK-NEXT: xscvhpdp f1, f0
69 ; CHECK-NEXT: bl frexpf
71 ; CHECK-NEXT: lwz r3, 44(r1)
72 ; CHECK-NEXT: addi r1, r1, 48
73 ; CHECK-NEXT: ld r0, 16(r1)
76 %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
77 %result.0 = extractvalue { half, i32 } %result, 1
81 define { <2 x half>, <2 x i32> } @test_frexp_v2f16_v2i32(<2 x half> %a) {
82 ; CHECK-LABEL: test_frexp_v2f16_v2i32:
85 ; CHECK-NEXT: .cfi_def_cfa_offset 80
86 ; CHECK-NEXT: .cfi_offset lr, 16
87 ; CHECK-NEXT: .cfi_offset r29, -40
88 ; CHECK-NEXT: .cfi_offset r30, -32
89 ; CHECK-NEXT: .cfi_offset f30, -16
90 ; CHECK-NEXT: .cfi_offset f31, -8
91 ; CHECK-NEXT: std r29, -40(r1) # 8-byte Folded Spill
92 ; CHECK-NEXT: std r30, -32(r1) # 8-byte Folded Spill
93 ; CHECK-NEXT: stfd f30, -16(r1) # 8-byte Folded Spill
94 ; CHECK-NEXT: stfd f31, -8(r1) # 8-byte Folded Spill
95 ; CHECK-NEXT: stdu r1, -80(r1)
96 ; CHECK-NEXT: std r0, 96(r1)
97 ; CHECK-NEXT: xscvdphp f0, f2
98 ; CHECK-NEXT: addi r30, r1, 32
99 ; CHECK-NEXT: mr r4, r30
100 ; CHECK-NEXT: mffprwz r3, f0
101 ; CHECK-NEXT: clrlwi r3, r3, 16
102 ; CHECK-NEXT: mtfprwz f0, r3
103 ; CHECK-NEXT: xscvhpdp f31, f0
104 ; CHECK-NEXT: xscvdphp f0, f1
105 ; CHECK-NEXT: mffprwz r3, f0
106 ; CHECK-NEXT: clrlwi r3, r3, 16
107 ; CHECK-NEXT: mtfprwz f0, r3
108 ; CHECK-NEXT: xscvhpdp f1, f0
109 ; CHECK-NEXT: bl frexpf
111 ; CHECK-NEXT: addi r29, r1, 36
112 ; CHECK-NEXT: fmr f30, f1
113 ; CHECK-NEXT: fmr f1, f31
114 ; CHECK-NEXT: mr r4, r29
115 ; CHECK-NEXT: bl frexpf
117 ; CHECK-NEXT: fmr f2, f1
118 ; CHECK-NEXT: lfiwzx f0, 0, r30
119 ; CHECK-NEXT: lfiwzx f1, 0, r29
120 ; CHECK-NEXT: xxmrghw v2, vs1, vs0
121 ; CHECK-NEXT: fmr f1, f30
122 ; CHECK-NEXT: addi r1, r1, 80
123 ; CHECK-NEXT: ld r0, 16(r1)
124 ; CHECK-NEXT: lfd f31, -8(r1) # 8-byte Folded Reload
125 ; CHECK-NEXT: lfd f30, -16(r1) # 8-byte Folded Reload
126 ; CHECK-NEXT: ld r30, -32(r1) # 8-byte Folded Reload
127 ; CHECK-NEXT: ld r29, -40(r1) # 8-byte Folded Reload
128 ; CHECK-NEXT: mtlr r0
130 %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
131 ret { <2 x half>, <2 x i32> } %result
134 define <2 x half> @test_frexp_v2f16_v2i32_only_use_fract(<2 x half> %a) {
135 ; CHECK-LABEL: test_frexp_v2f16_v2i32_only_use_fract:
137 ; CHECK-NEXT: mflr r0
138 ; CHECK-NEXT: .cfi_def_cfa_offset 64
139 ; CHECK-NEXT: .cfi_offset lr, 16
140 ; CHECK-NEXT: .cfi_offset f30, -16
141 ; CHECK-NEXT: .cfi_offset f31, -8
142 ; CHECK-NEXT: stfd f30, -16(r1) # 8-byte Folded Spill
143 ; CHECK-NEXT: stfd f31, -8(r1) # 8-byte Folded Spill
144 ; CHECK-NEXT: stdu r1, -64(r1)
145 ; CHECK-NEXT: std r0, 80(r1)
146 ; CHECK-NEXT: xscvdphp f0, f2
147 ; CHECK-NEXT: addi r4, r1, 40
148 ; CHECK-NEXT: mffprwz r3, f0
149 ; CHECK-NEXT: clrlwi r3, r3, 16
150 ; CHECK-NEXT: mtfprwz f0, r3
151 ; CHECK-NEXT: xscvhpdp f31, f0
152 ; CHECK-NEXT: xscvdphp f0, f1
153 ; CHECK-NEXT: mffprwz r3, f0
154 ; CHECK-NEXT: clrlwi r3, r3, 16
155 ; CHECK-NEXT: mtfprwz f0, r3
156 ; CHECK-NEXT: xscvhpdp f1, f0
157 ; CHECK-NEXT: bl frexpf
159 ; CHECK-NEXT: addi r4, r1, 44
160 ; CHECK-NEXT: fmr f30, f1
161 ; CHECK-NEXT: fmr f1, f31
162 ; CHECK-NEXT: bl frexpf
164 ; CHECK-NEXT: fmr f2, f1
165 ; CHECK-NEXT: fmr f1, f30
166 ; CHECK-NEXT: addi r1, r1, 64
167 ; CHECK-NEXT: ld r0, 16(r1)
168 ; CHECK-NEXT: lfd f31, -8(r1) # 8-byte Folded Reload
169 ; CHECK-NEXT: lfd f30, -16(r1) # 8-byte Folded Reload
170 ; CHECK-NEXT: mtlr r0
172 %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
173 %result.0 = extractvalue { <2 x half>, <2 x i32> } %result, 0
174 ret <2 x half> %result.0
177 define <2 x i32> @test_frexp_v2f16_v2i32_only_use_exp(<2 x half> %a) {
178 ; CHECK-LABEL: test_frexp_v2f16_v2i32_only_use_exp:
180 ; CHECK-NEXT: mflr r0
181 ; CHECK-NEXT: .cfi_def_cfa_offset 80
182 ; CHECK-NEXT: .cfi_offset lr, 16
183 ; CHECK-NEXT: .cfi_offset r29, -32
184 ; CHECK-NEXT: .cfi_offset r30, -24
185 ; CHECK-NEXT: .cfi_offset f31, -8
186 ; CHECK-NEXT: std r29, -32(r1) # 8-byte Folded Spill
187 ; CHECK-NEXT: std r30, -24(r1) # 8-byte Folded Spill
188 ; CHECK-NEXT: stfd f31, -8(r1) # 8-byte Folded Spill
189 ; CHECK-NEXT: stdu r1, -80(r1)
190 ; CHECK-NEXT: std r0, 96(r1)
191 ; CHECK-NEXT: xscvdphp f0, f2
192 ; CHECK-NEXT: addi r30, r1, 40
193 ; CHECK-NEXT: mr r4, r30
194 ; CHECK-NEXT: mffprwz r3, f0
195 ; CHECK-NEXT: clrlwi r3, r3, 16
196 ; CHECK-NEXT: mtfprwz f0, r3
197 ; CHECK-NEXT: xscvhpdp f31, f0
198 ; CHECK-NEXT: xscvdphp f0, f1
199 ; CHECK-NEXT: mffprwz r3, f0
200 ; CHECK-NEXT: clrlwi r3, r3, 16
201 ; CHECK-NEXT: mtfprwz f0, r3
202 ; CHECK-NEXT: xscvhpdp f1, f0
203 ; CHECK-NEXT: bl frexpf
205 ; CHECK-NEXT: addi r29, r1, 44
206 ; CHECK-NEXT: fmr f1, f31
207 ; CHECK-NEXT: mr r4, r29
208 ; CHECK-NEXT: bl frexpf
210 ; CHECK-NEXT: lfiwzx f0, 0, r30
211 ; CHECK-NEXT: lfiwzx f1, 0, r29
212 ; CHECK-NEXT: xxmrghw v2, vs1, vs0
213 ; CHECK-NEXT: addi r1, r1, 80
214 ; CHECK-NEXT: ld r0, 16(r1)
215 ; CHECK-NEXT: lfd f31, -8(r1) # 8-byte Folded Reload
216 ; CHECK-NEXT: ld r30, -24(r1) # 8-byte Folded Reload
217 ; CHECK-NEXT: ld r29, -32(r1) # 8-byte Folded Reload
218 ; CHECK-NEXT: mtlr r0
220 %result = call { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half> %a)
221 %result.1 = extractvalue { <2 x half>, <2 x i32> } %result, 1
222 ret <2 x i32> %result.1
225 define { float, i32 } @test_frexp_f32_i32(float %a) {
226 ; CHECK-LABEL: test_frexp_f32_i32:
228 ; CHECK-NEXT: mflr r0
229 ; CHECK-NEXT: stdu r1, -48(r1)
230 ; CHECK-NEXT: std r0, 64(r1)
231 ; CHECK-NEXT: .cfi_def_cfa_offset 48
232 ; CHECK-NEXT: .cfi_offset lr, 16
233 ; CHECK-NEXT: addi r4, r1, 44
234 ; CHECK-NEXT: bl frexpf
236 ; CHECK-NEXT: lwz r3, 44(r1)
237 ; CHECK-NEXT: addi r1, r1, 48
238 ; CHECK-NEXT: ld r0, 16(r1)
239 ; CHECK-NEXT: mtlr r0
241 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
242 ret { float, i32 } %result
245 define float @test_frexp_f32_i32_only_use_fract(float %a) {
246 ; CHECK-LABEL: test_frexp_f32_i32_only_use_fract:
248 ; CHECK-NEXT: mflr r0
249 ; CHECK-NEXT: stdu r1, -48(r1)
250 ; CHECK-NEXT: std r0, 64(r1)
251 ; CHECK-NEXT: .cfi_def_cfa_offset 48
252 ; CHECK-NEXT: .cfi_offset lr, 16
253 ; CHECK-NEXT: addi r4, r1, 44
254 ; CHECK-NEXT: bl frexpf
256 ; CHECK-NEXT: addi r1, r1, 48
257 ; CHECK-NEXT: ld r0, 16(r1)
258 ; CHECK-NEXT: mtlr r0
260 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
261 %result.0 = extractvalue { float, i32 } %result, 0
265 define i32 @test_frexp_f32_i32_only_use_exp(float %a) {
266 ; CHECK-LABEL: test_frexp_f32_i32_only_use_exp:
268 ; CHECK-NEXT: mflr r0
269 ; CHECK-NEXT: stdu r1, -48(r1)
270 ; CHECK-NEXT: std r0, 64(r1)
271 ; CHECK-NEXT: .cfi_def_cfa_offset 48
272 ; CHECK-NEXT: .cfi_offset lr, 16
273 ; CHECK-NEXT: addi r4, r1, 44
274 ; CHECK-NEXT: bl frexpf
276 ; CHECK-NEXT: lwz r3, 44(r1)
277 ; CHECK-NEXT: addi r1, r1, 48
278 ; CHECK-NEXT: ld r0, 16(r1)
279 ; CHECK-NEXT: mtlr r0
281 %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
282 %result.0 = extractvalue { float, i32 } %result, 1
287 ; define { <2 x float>, <2 x i32> } @test_frexp_v2f32_v2i32(<2 x float> %a) {
288 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
289 ; ret { <2 x float>, <2 x i32> } %result
292 ; define <2 x float> @test_frexp_v2f32_v2i32_only_use_fract(<2 x float> %a) {
293 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
294 ; %result.0 = extractvalue { <2 x float>, <2 x i32> } %result, 0
295 ; ret <2 x float> %result.0
298 ; define <2 x i32> @test_frexp_v2f32_v2i32_only_use_exp(<2 x float> %a) {
299 ; %result = call { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float> %a)
300 ; %result.1 = extractvalue { <2 x float>, <2 x i32> } %result, 1
301 ; ret <2 x i32> %result.1
304 define { double, i32 } @test_frexp_f64_i32(double %a) {
305 ; CHECK-LABEL: test_frexp_f64_i32:
307 ; CHECK-NEXT: mflr r0
308 ; CHECK-NEXT: stdu r1, -48(r1)
309 ; CHECK-NEXT: std r0, 64(r1)
310 ; CHECK-NEXT: .cfi_def_cfa_offset 48
311 ; CHECK-NEXT: .cfi_offset lr, 16
312 ; CHECK-NEXT: addi r4, r1, 44
313 ; CHECK-NEXT: bl frexp
315 ; CHECK-NEXT: lwz r3, 44(r1)
316 ; CHECK-NEXT: addi r1, r1, 48
317 ; CHECK-NEXT: ld r0, 16(r1)
318 ; CHECK-NEXT: mtlr r0
320 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
321 ret { double, i32 } %result
324 define double @test_frexp_f64_i32_only_use_fract(double %a) {
325 ; CHECK-LABEL: test_frexp_f64_i32_only_use_fract:
327 ; CHECK-NEXT: mflr r0
328 ; CHECK-NEXT: stdu r1, -48(r1)
329 ; CHECK-NEXT: std r0, 64(r1)
330 ; CHECK-NEXT: .cfi_def_cfa_offset 48
331 ; CHECK-NEXT: .cfi_offset lr, 16
332 ; CHECK-NEXT: addi r4, r1, 44
333 ; CHECK-NEXT: bl frexp
335 ; CHECK-NEXT: addi r1, r1, 48
336 ; CHECK-NEXT: ld r0, 16(r1)
337 ; CHECK-NEXT: mtlr r0
339 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
340 %result.0 = extractvalue { double, i32 } %result, 0
344 define i32 @test_frexp_f64_i32_only_use_exp(double %a) {
345 ; CHECK-LABEL: test_frexp_f64_i32_only_use_exp:
347 ; CHECK-NEXT: mflr r0
348 ; CHECK-NEXT: stdu r1, -48(r1)
349 ; CHECK-NEXT: std r0, 64(r1)
350 ; CHECK-NEXT: .cfi_def_cfa_offset 48
351 ; CHECK-NEXT: .cfi_offset lr, 16
352 ; CHECK-NEXT: addi r4, r1, 44
353 ; CHECK-NEXT: bl frexp
355 ; CHECK-NEXT: lwz r3, 44(r1)
356 ; CHECK-NEXT: addi r1, r1, 48
357 ; CHECK-NEXT: ld r0, 16(r1)
358 ; CHECK-NEXT: mtlr r0
360 %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
361 %result.0 = extractvalue { double, i32 } %result, 1
365 ; FIXME: Widen vector result
366 ; define { <2 x double>, <2 x i32> } @test_frexp_v2f64_v2i32(<2 x double> %a) {
367 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
368 ; ret { <2 x double>, <2 x i32> } %result
371 ; define <2 x double> @test_frexp_v2f64_v2i32_only_use_fract(<2 x double> %a) {
372 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
373 ; %result.0 = extractvalue { <2 x double>, <2 x i32> } %result, 0
374 ; ret <2 x double> %result.0
377 ; define <2 x i32> @test_frexp_v2f64_v2i32_only_use_exp(<2 x double> %a) {
378 ; %result = call { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double> %a)
379 ; %result.1 = extractvalue { <2 x double>, <2 x i32> } %result, 1
380 ; ret <2 x i32> %result.1
383 ; FIXME: f128 ExpandFloatResult
384 ; define { ppc_fp128, i32 } @test_frexp_f128_i32(ppc_fp128 %a) {
385 ; %result = call { ppc_fp128, i32 } @llvm.frexp.f128.i32(ppc_fp128 %a)
386 ; ret { ppc_fp128, i32 } %result
389 ; define ppc_fp128 @test_frexp_f128_i32_only_use_fract(ppc_fp128 %a) {
390 ; %result = call { ppc_fp128, i32 } @llvm.frexp.f128.i32(ppc_fp128 %a)
391 ; %result.0 = extractvalue { ppc_fp128, i32 } %result, 0
392 ; ret ppc_fp128 %result.0
395 ; define i32 @test_frexp_f128_i32_only_use_exp(ppc_fp128 %a) {
396 ; %result = call { ppc_fp128, i32 } @llvm.frexp.f128.i32(ppc_fp128 %a)
397 ; %result.0 = extractvalue { ppc_fp128, i32 } %result, 1
401 declare { float, i32 } @llvm.frexp.f32.i32(float) #0
402 declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0
404 declare { half, i32 } @llvm.frexp.f16.i32(half) #0
405 declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0
407 declare { double, i32 } @llvm.frexp.f64.i32(double) #0
408 declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0
410 declare { half, i16 } @llvm.frexp.f16.i16(half) #0
411 declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0
413 declare { ppc_fp128, i32 } @llvm.frexp.f128.i32(ppc_fp128) #0
415 attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }