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