xref: /llvm-project/llvm/test/CodeGen/AArch64/ldexp.ll (revision 39a0aa5876c20ef245fc4065b9f512008fac91a6)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2; RUN: llc -mtriple=aarch64 -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVELINUX %s
3; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVEWINDOWS %s
4; RUN: llc -mtriple=aarch64-windows-msvc < %s -o - | FileCheck -check-prefixes=WINDOWS %s
5
6define double @testExp(double %val, i32 %a) {
7; SVE-LABEL: testExp:
8; SVE:       // %bb.0: // %entry
9; SVE-NEXT:    // kill: def $w0 killed $w0 def $x0
10; SVE-NEXT:    sxtw x8, w0
11; SVE-NEXT:    ptrue p0.d
12; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
13; SVE-NEXT:    fmov d1, x8
14; SVE-NEXT:    fscale z0.d, p0/m, z0.d, z1.d
15; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
16; SVE-NEXT:    ret
17;
18; WINDOWS-LABEL: testExp:
19; WINDOWS:       // %bb.0: // %entry
20; WINDOWS-NEXT:    b ldexp
21entry:
22  %call = tail call fast double @ldexp(double %val, i32 %a)
23  ret double %call
24}
25
26declare double @ldexp(double, i32) memory(none)
27
28define double @testExpIntrinsic(double %val, i32 %a) {
29; SVE-LABEL: testExpIntrinsic:
30; SVE:       // %bb.0: // %entry
31; SVE-NEXT:    // kill: def $w0 killed $w0 def $x0
32; SVE-NEXT:    sxtw x8, w0
33; SVE-NEXT:    ptrue p0.d
34; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
35; SVE-NEXT:    fmov d1, x8
36; SVE-NEXT:    fscale z0.d, p0/m, z0.d, z1.d
37; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
38; SVE-NEXT:    ret
39;
40; WINDOWS-LABEL: testExpIntrinsic:
41; WINDOWS:       // %bb.0: // %entry
42; WINDOWS-NEXT:    b ldexp
43entry:
44  %call = tail call fast double @llvm.ldexp.f64(double %val, i32 %a)
45  ret double %call
46}
47
48define float @testExpf(float %val, i32 %a) {
49; SVELINUX-LABEL: testExpf:
50; SVELINUX:       // %bb.0: // %entry
51; SVELINUX-NEXT:    fmov s1, w0
52; SVELINUX-NEXT:    ptrue p0.s
53; SVELINUX-NEXT:    // kill: def $s0 killed $s0 def $z0
54; SVELINUX-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
55; SVELINUX-NEXT:    // kill: def $s0 killed $s0 killed $z0
56; SVELINUX-NEXT:    ret
57;
58; SVEWINDOWS-LABEL: testExpf:
59; SVEWINDOWS:       // %bb.0: // %entry
60; SVEWINDOWS-NEXT:    b ldexpf
61;
62; WINDOWS-LABEL: testExpf:
63; WINDOWS:       // %bb.0: // %entry
64; WINDOWS-NEXT:    b ldexpf
65entry:
66  %call = tail call fast float @ldexpf(float %val, i32 %a)
67  ret float %call
68}
69
70define float @testExpfIntrinsic(float %val, i32 %a) {
71; SVE-LABEL: testExpfIntrinsic:
72; SVE:       // %bb.0: // %entry
73; SVE-NEXT:    fmov s1, w0
74; SVE-NEXT:    ptrue p0.s
75; SVE-NEXT:    // kill: def $s0 killed $s0 def $z0
76; SVE-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
77; SVE-NEXT:    // kill: def $s0 killed $s0 killed $z0
78; SVE-NEXT:    ret
79;
80; WINDOWS-LABEL: testExpfIntrinsic:
81; WINDOWS:       .seh_proc testExpfIntrinsic
82; WINDOWS-NEXT:  // %bb.0: // %entry
83; WINDOWS-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
84; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
85; WINDOWS-NEXT:    .seh_endprologue
86; WINDOWS-NEXT:    fcvt d0, s0
87; WINDOWS-NEXT:    bl ldexp
88; WINDOWS-NEXT:    fcvt s0, d0
89; WINDOWS-NEXT:    .seh_startepilogue
90; WINDOWS-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
91; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
92; WINDOWS-NEXT:    .seh_endepilogue
93; WINDOWS-NEXT:    ret
94; WINDOWS-NEXT:    .seh_endfunclet
95; WINDOWS-NEXT:    .seh_endproc
96entry:
97  %call = tail call fast float @llvm.ldexp.f32(float %val, i32 %a)
98  ret float %call
99}
100
101
102declare float @ldexpf(float, i32) memory(none)
103
104define fp128 @testExpl(fp128 %val, i32 %a) {
105; SVE-LABEL: testExpl:
106; SVE:       // %bb.0: // %entry
107; SVE-NEXT:    b ldexpl
108;
109; WINDOWS-LABEL: testExpl:
110; WINDOWS:       // %bb.0: // %entry
111; WINDOWS-NEXT:    b ldexpl
112entry:
113  %call = tail call fast fp128 @ldexpl(fp128 %val, i32 %a)
114  ret fp128 %call
115}
116
117declare fp128 @ldexpl(fp128, i32) memory(none)
118
119define half @testExpf16(half %val, i32 %a) {
120; SVE-LABEL: testExpf16:
121; SVE:       // %bb.0: // %entry
122; SVE-NEXT:    fcvt s0, h0
123; SVE-NEXT:    fmov s1, w0
124; SVE-NEXT:    ptrue p0.s
125; SVE-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
126; SVE-NEXT:    fcvt h0, s0
127; SVE-NEXT:    ret
128;
129; WINDOWS-LABEL: testExpf16:
130; WINDOWS:       .seh_proc testExpf16
131; WINDOWS-NEXT:  // %bb.0: // %entry
132; WINDOWS-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
133; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
134; WINDOWS-NEXT:    .seh_endprologue
135; WINDOWS-NEXT:    fcvt d0, h0
136; WINDOWS-NEXT:    bl ldexp
137; WINDOWS-NEXT:    fcvt h0, d0
138; WINDOWS-NEXT:    .seh_startepilogue
139; WINDOWS-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
140; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
141; WINDOWS-NEXT:    .seh_endepilogue
142; WINDOWS-NEXT:    ret
143; WINDOWS-NEXT:    .seh_endfunclet
144; WINDOWS-NEXT:    .seh_endproc
145entry:
146  %0 = tail call fast half @llvm.ldexp.f16.i32(half %val, i32 %a)
147  ret half %0
148}
149
150declare half @llvm.ldexp.f16.i32(half, i32) memory(none)
151