xref: /llvm-project/llvm/test/CodeGen/PowerPC/llvm.frexp.ll (revision 003b58f65bdd5d9c7d0c1b355566c9ef430c0e7d)
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
4
5define { half, i32 } @test_frexp_f16_i32(half %a) {
6; CHECK-LABEL: test_frexp_f16_i32:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    mflr r0
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
20; CHECK-NEXT:    nop
21; CHECK-NEXT:    lwz r3, 44(r1)
22; CHECK-NEXT:    addi r1, r1, 48
23; CHECK-NEXT:    ld r0, 16(r1)
24; CHECK-NEXT:    mtlr r0
25; CHECK-NEXT:    blr
26  %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
27  ret { half, i32 } %result
28}
29
30define half @test_frexp_f16_i32_only_use_fract(half %a) {
31; CHECK-LABEL: test_frexp_f16_i32_only_use_fract:
32; CHECK:       # %bb.0:
33; CHECK-NEXT:    mflr r0
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
45; CHECK-NEXT:    nop
46; CHECK-NEXT:    addi r1, r1, 48
47; CHECK-NEXT:    ld r0, 16(r1)
48; CHECK-NEXT:    mtlr r0
49; CHECK-NEXT:    blr
50  %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
51  %result.0 = extractvalue { half, i32 } %result, 0
52  ret half %result.0
53}
54
55define i32 @test_frexp_f16_i32_only_use_exp(half %a) {
56; CHECK-LABEL: test_frexp_f16_i32_only_use_exp:
57; CHECK:       # %bb.0:
58; CHECK-NEXT:    mflr r0
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
70; CHECK-NEXT:    nop
71; CHECK-NEXT:    lwz r3, 44(r1)
72; CHECK-NEXT:    addi r1, r1, 48
73; CHECK-NEXT:    ld r0, 16(r1)
74; CHECK-NEXT:    mtlr r0
75; CHECK-NEXT:    blr
76  %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
77  %result.0 = extractvalue { half, i32 } %result, 1
78  ret i32 %result.0
79}
80
81define { <2 x half>, <2 x i32> } @test_frexp_v2f16_v2i32(<2 x half> %a) {
82; CHECK-LABEL: test_frexp_v2f16_v2i32:
83; CHECK:       # %bb.0:
84; CHECK-NEXT:    mflr r0
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
110; CHECK-NEXT:    nop
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
116; CHECK-NEXT:    nop
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
129; CHECK-NEXT:    blr
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
132}
133
134define <2 x half> @test_frexp_v2f16_v2i32_only_use_fract(<2 x half> %a) {
135; CHECK-LABEL: test_frexp_v2f16_v2i32_only_use_fract:
136; CHECK:       # %bb.0:
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
158; CHECK-NEXT:    nop
159; CHECK-NEXT:    addi r4, r1, 44
160; CHECK-NEXT:    fmr f30, f1
161; CHECK-NEXT:    fmr f1, f31
162; CHECK-NEXT:    bl frexpf
163; CHECK-NEXT:    nop
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
171; CHECK-NEXT:    blr
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
175}
176
177define <2 x i32> @test_frexp_v2f16_v2i32_only_use_exp(<2 x half> %a) {
178; CHECK-LABEL: test_frexp_v2f16_v2i32_only_use_exp:
179; CHECK:       # %bb.0:
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
204; CHECK-NEXT:    nop
205; CHECK-NEXT:    addi r29, r1, 44
206; CHECK-NEXT:    fmr f1, f31
207; CHECK-NEXT:    mr r4, r29
208; CHECK-NEXT:    bl frexpf
209; CHECK-NEXT:    nop
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
219; CHECK-NEXT:    blr
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
223}
224
225define { float, i32 } @test_frexp_f32_i32(float %a) {
226; CHECK-LABEL: test_frexp_f32_i32:
227; CHECK:       # %bb.0:
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
235; CHECK-NEXT:    nop
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
240; CHECK-NEXT:    blr
241  %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
242  ret { float, i32 } %result
243}
244
245define float @test_frexp_f32_i32_only_use_fract(float %a) {
246; CHECK-LABEL: test_frexp_f32_i32_only_use_fract:
247; CHECK:       # %bb.0:
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
255; CHECK-NEXT:    nop
256; CHECK-NEXT:    addi r1, r1, 48
257; CHECK-NEXT:    ld r0, 16(r1)
258; CHECK-NEXT:    mtlr r0
259; CHECK-NEXT:    blr
260  %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
261  %result.0 = extractvalue { float, i32 } %result, 0
262  ret float %result.0
263}
264
265define i32 @test_frexp_f32_i32_only_use_exp(float %a) {
266; CHECK-LABEL: test_frexp_f32_i32_only_use_exp:
267; CHECK:       # %bb.0:
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
275; CHECK-NEXT:    nop
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
280; CHECK-NEXT:    blr
281  %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
282  %result.0 = extractvalue { float, i32 } %result, 1
283  ret i32 %result.0
284}
285
286; FIXME
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
290; }
291
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
296; }
297
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
302; }
303
304define { double, i32 } @test_frexp_f64_i32(double %a) {
305; CHECK-LABEL: test_frexp_f64_i32:
306; CHECK:       # %bb.0:
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
314; CHECK-NEXT:    nop
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
319; CHECK-NEXT:    blr
320  %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
321  ret { double, i32 } %result
322}
323
324define double @test_frexp_f64_i32_only_use_fract(double %a) {
325; CHECK-LABEL: test_frexp_f64_i32_only_use_fract:
326; CHECK:       # %bb.0:
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
334; CHECK-NEXT:    nop
335; CHECK-NEXT:    addi r1, r1, 48
336; CHECK-NEXT:    ld r0, 16(r1)
337; CHECK-NEXT:    mtlr r0
338; CHECK-NEXT:    blr
339  %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
340  %result.0 = extractvalue { double, i32 } %result, 0
341  ret double %result.0
342}
343
344define i32 @test_frexp_f64_i32_only_use_exp(double %a) {
345; CHECK-LABEL: test_frexp_f64_i32_only_use_exp:
346; CHECK:       # %bb.0:
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
354; CHECK-NEXT:    nop
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
359; CHECK-NEXT:    blr
360  %result = call { double, i32 } @llvm.frexp.f64.i32(double %a)
361  %result.0 = extractvalue { double, i32 } %result, 1
362  ret i32 %result.0
363}
364
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
369; }
370
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
375; }
376
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
381; }
382
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
387; }
388
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
393; }
394
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
398;   ret i32 %result.0
399; }
400
401declare { float, i32 } @llvm.frexp.f32.i32(float) #0
402declare { <2 x float>, <2 x i32> } @llvm.frexp.v2f32.v2i32(<2 x float>) #0
403
404declare { half, i32 } @llvm.frexp.f16.i32(half) #0
405declare { <2 x half>, <2 x i32> } @llvm.frexp.v2f16.v2i32(<2 x half>) #0
406
407declare { double, i32 } @llvm.frexp.f64.i32(double) #0
408declare { <2 x double>, <2 x i32> } @llvm.frexp.v2f64.v2i32(<2 x double>) #0
409
410declare { half, i16 } @llvm.frexp.f16.i16(half) #0
411declare { <2 x half>, <2 x i16> } @llvm.frexp.v2f16.v2i16(<2 x half>) #0
412
413declare { ppc_fp128, i32 } @llvm.frexp.f128.i32(ppc_fp128) #0
414
415attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
416