xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/arm64-abi-varargs.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -march=arm64 -mcpu=cyclone -enable-misched=false | FileCheck %s
2*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-apple-ios7.0.0"
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; rdar://13625505
5*9880d681SAndroid Build Coastguard Worker; Here we have 9 fixed integer arguments the 9th argument in on stack, the
6*9880d681SAndroid Build Coastguard Worker; varargs start right after at 8-byte alignment.
7*9880d681SAndroid Build Coastguard Workerdefine void @fn9(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8, i32 %a9, ...) nounwind noinline ssp {
8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fn9:
9*9880d681SAndroid Build Coastguard Worker; 9th fixed argument
10*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [sp, #64]
11*9880d681SAndroid Build Coastguard Worker; CHECK: add [[ARGS:x[0-9]+]], sp, #72
12*9880d681SAndroid Build Coastguard Worker; CHECK: add {{x[0-9]+}}, [[ARGS]], #8
13*9880d681SAndroid Build Coastguard Worker; First vararg
14*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [sp, #72]
15*9880d681SAndroid Build Coastguard Worker; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #8
16*9880d681SAndroid Build Coastguard Worker; Second vararg
17*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}]
18*9880d681SAndroid Build Coastguard Worker; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #8
19*9880d681SAndroid Build Coastguard Worker; Third vararg
20*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}]
21*9880d681SAndroid Build Coastguard Worker  %1 = alloca i32, align 4
22*9880d681SAndroid Build Coastguard Worker  %2 = alloca i32, align 4
23*9880d681SAndroid Build Coastguard Worker  %3 = alloca i32, align 4
24*9880d681SAndroid Build Coastguard Worker  %4 = alloca i32, align 4
25*9880d681SAndroid Build Coastguard Worker  %5 = alloca i32, align 4
26*9880d681SAndroid Build Coastguard Worker  %6 = alloca i32, align 4
27*9880d681SAndroid Build Coastguard Worker  %7 = alloca i32, align 4
28*9880d681SAndroid Build Coastguard Worker  %8 = alloca i32, align 4
29*9880d681SAndroid Build Coastguard Worker  %9 = alloca i32, align 4
30*9880d681SAndroid Build Coastguard Worker  %args = alloca i8*, align 8
31*9880d681SAndroid Build Coastguard Worker  %a10 = alloca i32, align 4
32*9880d681SAndroid Build Coastguard Worker  %a11 = alloca i32, align 4
33*9880d681SAndroid Build Coastguard Worker  %a12 = alloca i32, align 4
34*9880d681SAndroid Build Coastguard Worker  store i32 %a1, i32* %1, align 4
35*9880d681SAndroid Build Coastguard Worker  store i32 %a2, i32* %2, align 4
36*9880d681SAndroid Build Coastguard Worker  store i32 %a3, i32* %3, align 4
37*9880d681SAndroid Build Coastguard Worker  store i32 %a4, i32* %4, align 4
38*9880d681SAndroid Build Coastguard Worker  store i32 %a5, i32* %5, align 4
39*9880d681SAndroid Build Coastguard Worker  store i32 %a6, i32* %6, align 4
40*9880d681SAndroid Build Coastguard Worker  store i32 %a7, i32* %7, align 4
41*9880d681SAndroid Build Coastguard Worker  store i32 %a8, i32* %8, align 4
42*9880d681SAndroid Build Coastguard Worker  store i32 %a9, i32* %9, align 4
43*9880d681SAndroid Build Coastguard Worker  %10 = bitcast i8** %args to i8*
44*9880d681SAndroid Build Coastguard Worker  call void @llvm.va_start(i8* %10)
45*9880d681SAndroid Build Coastguard Worker  %11 = va_arg i8** %args, i32
46*9880d681SAndroid Build Coastguard Worker  store i32 %11, i32* %a10, align 4
47*9880d681SAndroid Build Coastguard Worker  %12 = va_arg i8** %args, i32
48*9880d681SAndroid Build Coastguard Worker  store i32 %12, i32* %a11, align 4
49*9880d681SAndroid Build Coastguard Worker  %13 = va_arg i8** %args, i32
50*9880d681SAndroid Build Coastguard Worker  store i32 %13, i32* %a12, align 4
51*9880d681SAndroid Build Coastguard Worker  ret void
52*9880d681SAndroid Build Coastguard Worker}
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) nounwind
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Workerdefine i32 @main() nounwind ssp {
57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: main:
58*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
59*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp, #8]
60*9880d681SAndroid Build Coastguard Worker; CHECK: str {{w[0-9]+}}, [sp]
61*9880d681SAndroid Build Coastguard Worker  %a1 = alloca i32, align 4
62*9880d681SAndroid Build Coastguard Worker  %a2 = alloca i32, align 4
63*9880d681SAndroid Build Coastguard Worker  %a3 = alloca i32, align 4
64*9880d681SAndroid Build Coastguard Worker  %a4 = alloca i32, align 4
65*9880d681SAndroid Build Coastguard Worker  %a5 = alloca i32, align 4
66*9880d681SAndroid Build Coastguard Worker  %a6 = alloca i32, align 4
67*9880d681SAndroid Build Coastguard Worker  %a7 = alloca i32, align 4
68*9880d681SAndroid Build Coastguard Worker  %a8 = alloca i32, align 4
69*9880d681SAndroid Build Coastguard Worker  %a9 = alloca i32, align 4
70*9880d681SAndroid Build Coastguard Worker  %a10 = alloca i32, align 4
71*9880d681SAndroid Build Coastguard Worker  %a11 = alloca i32, align 4
72*9880d681SAndroid Build Coastguard Worker  %a12 = alloca i32, align 4
73*9880d681SAndroid Build Coastguard Worker  store i32 1, i32* %a1, align 4
74*9880d681SAndroid Build Coastguard Worker  store i32 2, i32* %a2, align 4
75*9880d681SAndroid Build Coastguard Worker  store i32 3, i32* %a3, align 4
76*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %a4, align 4
77*9880d681SAndroid Build Coastguard Worker  store i32 5, i32* %a5, align 4
78*9880d681SAndroid Build Coastguard Worker  store i32 6, i32* %a6, align 4
79*9880d681SAndroid Build Coastguard Worker  store i32 7, i32* %a7, align 4
80*9880d681SAndroid Build Coastguard Worker  store i32 8, i32* %a8, align 4
81*9880d681SAndroid Build Coastguard Worker  store i32 9, i32* %a9, align 4
82*9880d681SAndroid Build Coastguard Worker  store i32 10, i32* %a10, align 4
83*9880d681SAndroid Build Coastguard Worker  store i32 11, i32* %a11, align 4
84*9880d681SAndroid Build Coastguard Worker  store i32 12, i32* %a12, align 4
85*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %a1, align 4
86*9880d681SAndroid Build Coastguard Worker  %2 = load i32, i32* %a2, align 4
87*9880d681SAndroid Build Coastguard Worker  %3 = load i32, i32* %a3, align 4
88*9880d681SAndroid Build Coastguard Worker  %4 = load i32, i32* %a4, align 4
89*9880d681SAndroid Build Coastguard Worker  %5 = load i32, i32* %a5, align 4
90*9880d681SAndroid Build Coastguard Worker  %6 = load i32, i32* %a6, align 4
91*9880d681SAndroid Build Coastguard Worker  %7 = load i32, i32* %a7, align 4
92*9880d681SAndroid Build Coastguard Worker  %8 = load i32, i32* %a8, align 4
93*9880d681SAndroid Build Coastguard Worker  %9 = load i32, i32* %a9, align 4
94*9880d681SAndroid Build Coastguard Worker  %10 = load i32, i32* %a10, align 4
95*9880d681SAndroid Build Coastguard Worker  %11 = load i32, i32* %a11, align 4
96*9880d681SAndroid Build Coastguard Worker  %12 = load i32, i32* %a12, align 4
97*9880d681SAndroid Build Coastguard Worker  call void (i32, i32, i32, i32, i32, i32, i32, i32, i32, ...) @fn9(i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9, i32 %10, i32 %11, i32 %12)
98*9880d681SAndroid Build Coastguard Worker  ret i32 0
99*9880d681SAndroid Build Coastguard Worker}
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker;rdar://13668483
102*9880d681SAndroid Build Coastguard Worker@.str = private unnamed_addr constant [4 x i8] c"fmt\00", align 1
103*9880d681SAndroid Build Coastguard Workerdefine void @foo(i8* %fmt, ...) nounwind {
104*9880d681SAndroid Build Coastguard Workerentry:
105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo:
106*9880d681SAndroid Build Coastguard Worker; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0x8
107*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [sp, #48]
108*9880d681SAndroid Build Coastguard Worker; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #15
109*9880d681SAndroid Build Coastguard Worker; CHECK: and x[[ADDR:[0-9]+]], {{x[0-9]+}}, #0xfffffffffffffff0
110*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{q[0-9]+}}, [x[[ADDR]]]
111*9880d681SAndroid Build Coastguard Worker  %fmt.addr = alloca i8*, align 8
112*9880d681SAndroid Build Coastguard Worker  %args = alloca i8*, align 8
113*9880d681SAndroid Build Coastguard Worker  %vc = alloca i32, align 4
114*9880d681SAndroid Build Coastguard Worker  %vv = alloca <4 x i32>, align 16
115*9880d681SAndroid Build Coastguard Worker  store i8* %fmt, i8** %fmt.addr, align 8
116*9880d681SAndroid Build Coastguard Worker  %args1 = bitcast i8** %args to i8*
117*9880d681SAndroid Build Coastguard Worker  call void @llvm.va_start(i8* %args1)
118*9880d681SAndroid Build Coastguard Worker  %0 = va_arg i8** %args, i32
119*9880d681SAndroid Build Coastguard Worker  store i32 %0, i32* %vc, align 4
120*9880d681SAndroid Build Coastguard Worker  %1 = va_arg i8** %args, <4 x i32>
121*9880d681SAndroid Build Coastguard Worker  store <4 x i32> %1, <4 x i32>* %vv, align 16
122*9880d681SAndroid Build Coastguard Worker  ret void
123*9880d681SAndroid Build Coastguard Worker}
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Workerdefine void @bar(i32 %x, <4 x i32> %y) nounwind {
126*9880d681SAndroid Build Coastguard Workerentry:
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bar:
128*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{q[0-9]+}}, {{q[0-9]+}}, [sp, #16]
129*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp]
130*9880d681SAndroid Build Coastguard Worker  %x.addr = alloca i32, align 4
131*9880d681SAndroid Build Coastguard Worker  %y.addr = alloca <4 x i32>, align 16
132*9880d681SAndroid Build Coastguard Worker  store i32 %x, i32* %x.addr, align 4
133*9880d681SAndroid Build Coastguard Worker  store <4 x i32> %y, <4 x i32>* %y.addr, align 16
134*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %x.addr, align 4
135*9880d681SAndroid Build Coastguard Worker  %1 = load <4 x i32>, <4 x i32>* %y.addr, align 16
136*9880d681SAndroid Build Coastguard Worker  call void (i8*, ...) @foo(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %0, <4 x i32> %1)
137*9880d681SAndroid Build Coastguard Worker  ret void
138*9880d681SAndroid Build Coastguard Worker}
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker; rdar://13668927
141*9880d681SAndroid Build Coastguard Worker; When passing 16-byte aligned small structs as vararg, make sure the caller
142*9880d681SAndroid Build Coastguard Worker; side is 16-byte aligned on stack.
143*9880d681SAndroid Build Coastguard Worker%struct.s41 = type { i32, i16, i32, i16 }
144*9880d681SAndroid Build Coastguard Workerdefine void @foo2(i8* %fmt, ...) nounwind {
145*9880d681SAndroid Build Coastguard Workerentry:
146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo2:
147*9880d681SAndroid Build Coastguard Worker; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0x8
148*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{w[0-9]+}}, [sp, #48]
149*9880d681SAndroid Build Coastguard Worker; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #15
150*9880d681SAndroid Build Coastguard Worker; CHECK: and x[[ADDR:[0-9]+]], {{x[0-9]+}}, #0xfffffffffffffff0
151*9880d681SAndroid Build Coastguard Worker; CHECK: ldr {{q[0-9]+}}, [x[[ADDR]]]
152*9880d681SAndroid Build Coastguard Worker  %fmt.addr = alloca i8*, align 8
153*9880d681SAndroid Build Coastguard Worker  %args = alloca i8*, align 8
154*9880d681SAndroid Build Coastguard Worker  %vc = alloca i32, align 4
155*9880d681SAndroid Build Coastguard Worker  %vs = alloca %struct.s41, align 16
156*9880d681SAndroid Build Coastguard Worker  store i8* %fmt, i8** %fmt.addr, align 8
157*9880d681SAndroid Build Coastguard Worker  %args1 = bitcast i8** %args to i8*
158*9880d681SAndroid Build Coastguard Worker  call void @llvm.va_start(i8* %args1)
159*9880d681SAndroid Build Coastguard Worker  %0 = va_arg i8** %args, i32
160*9880d681SAndroid Build Coastguard Worker  store i32 %0, i32* %vc, align 4
161*9880d681SAndroid Build Coastguard Worker  %ap.cur = load i8*, i8** %args
162*9880d681SAndroid Build Coastguard Worker  %1 = getelementptr i8, i8* %ap.cur, i32 15
163*9880d681SAndroid Build Coastguard Worker  %2 = ptrtoint i8* %1 to i64
164*9880d681SAndroid Build Coastguard Worker  %3 = and i64 %2, -16
165*9880d681SAndroid Build Coastguard Worker  %ap.align = inttoptr i64 %3 to i8*
166*9880d681SAndroid Build Coastguard Worker  %ap.next = getelementptr i8, i8* %ap.align, i32 16
167*9880d681SAndroid Build Coastguard Worker  store i8* %ap.next, i8** %args
168*9880d681SAndroid Build Coastguard Worker  %4 = bitcast i8* %ap.align to %struct.s41*
169*9880d681SAndroid Build Coastguard Worker  %5 = bitcast %struct.s41* %vs to i8*
170*9880d681SAndroid Build Coastguard Worker  %6 = bitcast %struct.s41* %4 to i8*
171*9880d681SAndroid Build Coastguard Worker  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %5, i8* %6, i64 16, i32 16, i1 false)
172*9880d681SAndroid Build Coastguard Worker  ret void
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Workerdefine void @bar2(i32 %x, i128 %s41.coerce) nounwind {
177*9880d681SAndroid Build Coastguard Workerentry:
178*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bar2:
179*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
180*9880d681SAndroid Build Coastguard Worker; CHECK: str {{x[0-9]+}}, [sp]
181*9880d681SAndroid Build Coastguard Worker  %x.addr = alloca i32, align 4
182*9880d681SAndroid Build Coastguard Worker  %s41 = alloca %struct.s41, align 16
183*9880d681SAndroid Build Coastguard Worker  store i32 %x, i32* %x.addr, align 4
184*9880d681SAndroid Build Coastguard Worker  %0 = bitcast %struct.s41* %s41 to i128*
185*9880d681SAndroid Build Coastguard Worker  store i128 %s41.coerce, i128* %0, align 1
186*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %x.addr, align 4
187*9880d681SAndroid Build Coastguard Worker  %2 = bitcast %struct.s41* %s41 to i128*
188*9880d681SAndroid Build Coastguard Worker  %3 = load i128, i128* %2, align 1
189*9880d681SAndroid Build Coastguard Worker  call void (i8*, ...) @foo2(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %1, i128 %3)
190*9880d681SAndroid Build Coastguard Worker  ret void
191*9880d681SAndroid Build Coastguard Worker}
192