xref: /llvm-project/llvm/test/CodeGen/AArch64/win64_vararg_float.ll (revision db158c7c830807caeeb0691739c41f1d522029e9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs | FileCheck %s --check-prefixes=DAGISEL
3; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs -O0 -fast-isel | FileCheck %s --check-prefixes=O0,FASTISEL
4; RUN: llc < %s -mtriple=aarch64-windows -verify-machineinstrs -O0 -global-isel | FileCheck %s --check-prefixes=O0,GISEL
5
6define void @float_va_fn(float %a, i32 %b, ...) nounwind {
7; DAGISEL-LABEL: float_va_fn:
8; DAGISEL:       // %bb.0: // %entry
9; DAGISEL-NEXT:    str x30, [sp, #-64]! // 8-byte Folded Spill
10; DAGISEL-NEXT:    fmov s0, w0
11; DAGISEL-NEXT:    add x8, sp, #16
12; DAGISEL-NEXT:    add x0, sp, #16
13; DAGISEL-NEXT:    stp x2, x3, [sp, #16]
14; DAGISEL-NEXT:    stp x4, x5, [sp, #32]
15; DAGISEL-NEXT:    stp x6, x7, [sp, #48]
16; DAGISEL-NEXT:    str x8, [sp, #8]
17; DAGISEL-NEXT:    bl f_va_list
18; DAGISEL-NEXT:    ldr x30, [sp], #64 // 8-byte Folded Reload
19; DAGISEL-NEXT:    ret
20;
21; O0-LABEL: float_va_fn:
22; O0:       // %bb.0: // %entry
23; O0-NEXT:    sub sp, sp, #80
24; O0-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
25; O0-NEXT:    str x7, [sp, #72]
26; O0-NEXT:    str x6, [sp, #64]
27; O0-NEXT:    str x5, [sp, #56]
28; O0-NEXT:    str x4, [sp, #48]
29; O0-NEXT:    str x3, [sp, #40]
30; O0-NEXT:    str x2, [sp, #32]
31; O0-NEXT:    fmov s0, w0
32; O0-NEXT:    add x8, sp, #32
33; O0-NEXT:    str x8, [sp, #8]
34; O0-NEXT:    ldr x0, [sp, #8]
35; O0-NEXT:    bl f_va_list
36; O0-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
37; O0-NEXT:    add sp, sp, #80
38; O0-NEXT:    ret
39entry:
40  %ap = alloca ptr, align 8
41  call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %ap)
42  call void @llvm.va_start(ptr nonnull %ap)
43  %0 = load ptr, ptr %ap, align 8
44  call void @f_va_list(float %a, ptr %0)
45  call void @llvm.va_end(ptr nonnull %ap)
46  call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %ap)
47  ret void
48}
49
50declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
51declare void @llvm.va_start(ptr)
52declare void @f_va_list(float, ptr)
53declare void @llvm.va_end(ptr)
54declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
55
56define void @double_va_fn(double %a, i32 %b, ...) nounwind {
57; DAGISEL-LABEL: double_va_fn:
58; DAGISEL:       // %bb.0: // %entry
59; DAGISEL-NEXT:    str x30, [sp, #-64]! // 8-byte Folded Spill
60; DAGISEL-NEXT:    fmov d0, x0
61; DAGISEL-NEXT:    add x8, sp, #16
62; DAGISEL-NEXT:    add x0, sp, #16
63; DAGISEL-NEXT:    stp x2, x3, [sp, #16]
64; DAGISEL-NEXT:    stp x4, x5, [sp, #32]
65; DAGISEL-NEXT:    stp x6, x7, [sp, #48]
66; DAGISEL-NEXT:    str x8, [sp, #8]
67; DAGISEL-NEXT:    bl d_va_list
68; DAGISEL-NEXT:    ldr x30, [sp], #64 // 8-byte Folded Reload
69; DAGISEL-NEXT:    ret
70;
71; O0-LABEL: double_va_fn:
72; O0:       // %bb.0: // %entry
73; O0-NEXT:    sub sp, sp, #80
74; O0-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
75; O0-NEXT:    str x7, [sp, #72]
76; O0-NEXT:    str x6, [sp, #64]
77; O0-NEXT:    str x5, [sp, #56]
78; O0-NEXT:    str x4, [sp, #48]
79; O0-NEXT:    str x3, [sp, #40]
80; O0-NEXT:    str x2, [sp, #32]
81; O0-NEXT:    fmov d0, x0
82; O0-NEXT:    add x8, sp, #32
83; O0-NEXT:    str x8, [sp, #8]
84; O0-NEXT:    ldr x0, [sp, #8]
85; O0-NEXT:    bl d_va_list
86; O0-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
87; O0-NEXT:    add sp, sp, #80
88; O0-NEXT:    ret
89entry:
90  %ap = alloca ptr, align 8
91  call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %ap)
92  call void @llvm.va_start(ptr nonnull %ap)
93  %0 = load ptr, ptr %ap, align 8
94  call void @d_va_list(double %a, ptr %0)
95  call void @llvm.va_end(ptr nonnull %ap)
96  call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %ap)
97  ret void
98}
99
100declare void @d_va_list(double, ptr)
101
102define void @call_f_va() nounwind {
103; DAGISEL-LABEL: call_f_va:
104; DAGISEL:       // %bb.0: // %entry
105; DAGISEL-NEXT:    mov w0, #1065353216 // =0x3f800000
106; DAGISEL-NEXT:    mov w1, #2 // =0x2
107; DAGISEL-NEXT:    mov x2, #4613937818241073152 // =0x4008000000000000
108; DAGISEL-NEXT:    mov w3, #4 // =0x4
109; DAGISEL-NEXT:    b other_f_va_fn
110;
111; FASTISEL-LABEL: call_f_va:
112; FASTISEL:       // %bb.0: // %entry
113; FASTISEL-NEXT:    mov w0, #1065353216 // =0x3f800000
114; FASTISEL-NEXT:    mov w1, #2 // =0x2
115; FASTISEL-NEXT:    mov x2, #4613937818241073152 // =0x4008000000000000
116; FASTISEL-NEXT:    mov w3, #4 // =0x4
117; FASTISEL-NEXT:    b other_f_va_fn
118;
119; GISEL-LABEL: call_f_va:
120; GISEL:       // %bb.0: // %entry
121; GISEL-NEXT:    fmov s0, #1.00000000
122; GISEL-NEXT:    fmov w0, s0
123; GISEL-NEXT:    mov w1, #2 // =0x2
124; GISEL-NEXT:    fmov d0, #3.00000000
125; GISEL-NEXT:    fmov x2, d0
126; GISEL-NEXT:    mov w3, #4 // =0x4
127; GISEL-NEXT:    b other_f_va_fn
128entry:
129  tail call void (float, i32, ...) @other_f_va_fn(float 1.000000e+00, i32 2, double 3.000000e+00, i32 4)
130  ret void
131}
132
133declare void @other_f_va_fn(float, i32, ...)
134
135define void @call_d_va() nounwind {
136; DAGISEL-LABEL: call_d_va:
137; DAGISEL:       // %bb.0: // %entry
138; DAGISEL-NEXT:    mov x0, #4607182418800017408 // =0x3ff0000000000000
139; DAGISEL-NEXT:    mov w1, #2 // =0x2
140; DAGISEL-NEXT:    mov x2, #4613937818241073152 // =0x4008000000000000
141; DAGISEL-NEXT:    mov w3, #4 // =0x4
142; DAGISEL-NEXT:    b other_d_va_fn
143;
144; FASTISEL-LABEL: call_d_va:
145; FASTISEL:       // %bb.0: // %entry
146; FASTISEL-NEXT:    mov x0, #4607182418800017408 // =0x3ff0000000000000
147; FASTISEL-NEXT:    mov w1, #2 // =0x2
148; FASTISEL-NEXT:    mov x2, #4613937818241073152 // =0x4008000000000000
149; FASTISEL-NEXT:    mov w3, #4 // =0x4
150; FASTISEL-NEXT:    b other_d_va_fn
151;
152; GISEL-LABEL: call_d_va:
153; GISEL:       // %bb.0: // %entry
154; GISEL-NEXT:    fmov d0, #1.00000000
155; GISEL-NEXT:    fmov x0, d0
156; GISEL-NEXT:    mov w1, #2 // =0x2
157; GISEL-NEXT:    fmov d0, #3.00000000
158; GISEL-NEXT:    fmov x2, d0
159; GISEL-NEXT:    mov w3, #4 // =0x4
160; GISEL-NEXT:    b other_d_va_fn
161entry:
162  tail call void (double, i32, ...) @other_d_va_fn(double 1.000000e+00, i32 2, double 3.000000e+00, i32 4)
163  ret void
164}
165
166declare void @other_d_va_fn(double, i32, ...)
167
168define void @call_d_non_va() nounwind {
169; DAGISEL-LABEL: call_d_non_va:
170; DAGISEL:       // %bb.0: // %entry
171; DAGISEL-NEXT:    fmov d0, #1.00000000
172; DAGISEL-NEXT:    fmov d1, #3.00000000
173; DAGISEL-NEXT:    mov w0, #2 // =0x2
174; DAGISEL-NEXT:    mov w1, #4 // =0x4
175; DAGISEL-NEXT:    b other_d_non_va_fn
176;
177; O0-LABEL: call_d_non_va:
178; O0:       // %bb.0: // %entry
179; O0-NEXT:    fmov d0, #1.00000000
180; O0-NEXT:    mov w0, #2 // =0x2
181; O0-NEXT:    fmov d1, #3.00000000
182; O0-NEXT:    mov w1, #4 // =0x4
183; O0-NEXT:    b other_d_non_va_fn
184entry:
185  tail call void (double, i32, double, i32) @other_d_non_va_fn(double 1.000000e+00, i32 2, double 3.000000e+00, i32 4)
186  ret void
187}
188
189declare void @other_d_non_va_fn(double, i32, double, i32)
190