ARM / x86_64 varargs: Don't save regparms in prologue without va_start
[oota-llvm.git] / test / CodeGen / ARM / thumb1_return_sequence.ll
1 ; RUN: llc -mtriple=thumbv4t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V4T
2 ; RUN: llc -mtriple=thumbv5t-none--eabi < %s | FileCheck %s --check-prefix=CHECK-V5T
3
4 ; CHECK-V4T-LABEL: clobberframe
5 ; CHECK-V5T-LABEL: clobberframe
6 define <4 x i32> @clobberframe() #0 {
7 entry:
8 ; Prologue
9 ; --------
10 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
11 ; CHECK-V4T:    sub sp,
12 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
13
14   %b = alloca <4 x i32>, align 16
15   %a = alloca <4 x i32>, align 16
16   store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
17   store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
18   %0 = load <4 x i32>* %a, align 16
19   ret <4 x i32> %0
20
21 ; Epilogue
22 ; --------
23 ; CHECK-V4T:         add sp,
24 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
25 ; CHECK-V4T-NEXT:    mov r12, r3
26 ; CHECK-V4T-NEXT:    pop {r3}
27 ; CHECK-V4T-NEXT:    mov lr, r3
28 ; CHECK-V4T-NEXT:    mov r3, r12
29 ; CHECK-V4T:         bx  lr
30 ; CHECK-V5T:         pop {[[SAVED]], pc}
31 }
32
33 ; CHECK-V4T-LABEL: clobbervariadicframe
34 ; CHECK-V5T-LABEL: clobbervariadicframe
35 define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 {
36 entry:
37 ; Prologue
38 ; --------
39 ; CHECK-V4T:    sub sp,
40 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
41 ; CHECK-V5T:    sub sp,
42 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
43
44   %b = alloca <4 x i32>, align 16
45   %a = alloca <4 x i32>, align 16
46   store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
47   store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
48   %0 = load <4 x i32>* %a, align 16
49   call void @llvm.va_start(i8* null)
50   ret <4 x i32> %0
51
52 ; Epilogue
53 ; --------
54 ; CHECK-V4T:         pop {[[SAVED]]}
55 ; CHECK-V4T-NEXT:    mov r12, r3
56 ; CHECK-V4T-NEXT:    pop {r3}
57 ; CHECK-V4T-NEXT:    add sp,
58 ; CHECK-V4T-NEXT:    mov lr, r3
59 ; CHECK-V4T-NEXT:    mov r3, r12
60 ; CHECK-V4T:         bx  lr
61 ; CHECK-V5T:         add sp,
62 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
63 ; CHECK-V5T-NEXT:    mov r12, r3
64 ; CHECK-V5T-NEXT:    pop {r3}
65 ; CHECK-V5T-NEXT:    add sp,
66 ; CHECK-V5T-NEXT:    mov lr, r3
67 ; CHECK-V5T-NEXT:    mov r3, r12
68 ; CHECK-V5T-NEXT:    bx lr
69 }
70
71 ; CHECK-V4T-LABEL: simpleframe
72 ; CHECK-V5T-LABEL: simpleframe
73 define i32 @simpleframe() #0 {
74 entry:
75 ; Prologue
76 ; --------
77 ; CHECK-V4T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
78 ; CHECK-V5T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
79
80   %a = alloca i32, align 4
81   %b = alloca i32, align 4
82   %c = alloca i32, align 4
83   %d = alloca i32, align 4
84   store i32 1, i32* %a, align 4
85   store i32 2, i32* %b, align 4
86   store i32 3, i32* %c, align 4
87   store i32 4, i32* %d, align 4
88   %0 = load i32* %a, align 4
89   %inc = add nsw i32 %0, 1
90   store i32 %inc, i32* %a, align 4
91   %1 = load i32* %b, align 4
92   %inc1 = add nsw i32 %1, 1
93   store i32 %inc1, i32* %b, align 4
94   %2 = load i32* %c, align 4
95   %inc2 = add nsw i32 %2, 1
96   store i32 %inc2, i32* %c, align 4
97   %3 = load i32* %d, align 4
98   %inc3 = add nsw i32 %3, 1
99   store i32 %inc3, i32* %d, align 4
100   %4 = load i32* %a, align 4
101   %5 = load i32* %b, align 4
102   %add = add nsw i32 %4, %5
103   %6 = load i32* %c, align 4
104   %add4 = add nsw i32 %add, %6
105   %7 = load i32* %d, align 4
106   %add5 = add nsw i32 %add4, %7
107   ret i32 %add5
108
109 ; Epilogue
110 ; --------
111 ; CHECK-V4T:    pop {[[SAVED]]}
112 ; CHECK-V4T:    pop {r3}
113 ; CHECK-V4T:    bx r3
114 ; CHECK-V5T:    pop {[[SAVED]], pc}
115 }
116
117 ; CHECK-V4T-LABEL: simplevariadicframe
118 ; CHECK-V5T-LABEL: simplevariadicframe
119 define i32 @simplevariadicframe(i32 %i, ...) #0 {
120 entry:
121 ; Prologue
122 ; --------
123 ; CHECK-V4T:    sub sp,
124 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
125 ; CHECK-V4T:    sub sp,
126 ; CHECK-V5T:    sub sp,
127 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
128 ; CHECK-V5T:    sub sp,
129
130   %a = alloca i32, align 4
131   %b = alloca i32, align 4
132   %c = alloca i32, align 4
133   %d = alloca i32, align 4
134   store i32 1, i32* %a, align 4
135   store i32 2, i32* %b, align 4
136   store i32 3, i32* %c, align 4
137   store i32 4, i32* %d, align 4
138   %0 = load i32* %a, align 4
139   %inc = add nsw i32 %0, 1
140   store i32 %inc, i32* %a, align 4
141   %1 = load i32* %b, align 4
142   %inc1 = add nsw i32 %1, 1
143   store i32 %inc1, i32* %b, align 4
144   %2 = load i32* %c, align 4
145   %inc2 = add nsw i32 %2, 1
146   store i32 %inc2, i32* %c, align 4
147   %3 = load i32* %d, align 4
148   %inc3 = add nsw i32 %3, 1
149   store i32 %inc3, i32* %d, align 4
150   %4 = load i32* %a, align 4
151   %5 = load i32* %b, align 4
152   %add = add nsw i32 %4, %5
153   %6 = load i32* %c, align 4
154   %add4 = add nsw i32 %add, %6
155   %7 = load i32* %d, align 4
156   %add5 = add nsw i32 %add4, %7
157   %add6 = add nsw i32 %add5, %i
158   call void @llvm.va_start(i8* null)
159   ret i32 %add6
160
161 ; Epilogue
162 ; --------
163 ; CHECK-V4T:         add sp,
164 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
165 ; CHECK-V4T-NEXT:    pop {r3}
166 ; CHECK-V4T-NEXT:    add sp,
167 ; CHECK-V4T-NEXT:    bx r3
168 ; CHECK-V5T:         add sp,
169 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
170 ; CHECK-V5T-NEXT:    pop {r3}
171 ; CHECK-V5T-NEXT:    add sp,
172 ; CHECK-V5T-NEXT:    bx r3
173 }
174
175 ; CHECK-V4T-LABEL: noframe
176 ; CHECK-V5T-LABEL: noframe
177 define i32 @noframe() #0 {
178 entry:
179 ; Prologue
180 ; --------
181 ; CHECK-V4T-NOT: push
182 ; CHECK-V5T-NOT: push
183     ret i32 0;
184 ; Epilogue
185 ; --------
186 ; CHECK-V4T-NOT: pop
187 ; CHECK-V5T-NOT: pop
188 ; CHECK-V4T:    bx  lr
189 ; CHECK-V5T:    bx  lr
190 }
191
192 ; CHECK-V4T-LABEL: novariadicframe
193 ; CHECK-V5T-LABEL: novariadicframe
194 define i32 @novariadicframe(i32 %i, ...) #0 {
195 entry:
196 ; Prologue
197 ; --------
198 ; CHECK-V4T:    sub sp,
199 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
200 ; CHECK-V5T:    sub sp,
201 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
202
203   call void @llvm.va_start(i8* null)
204   ret i32 %i;
205 ; Epilogue
206 ; --------
207 ; CHECK-V4T:         pop {[[SAVED]]}
208 ; CHECK-V4T-NEXT:    pop {r3}
209 ; CHECK-V4T-NEXT:    add sp,
210 ; CHECK-V4T-NEXT:    bx r3
211 ; CHECK-V5T:         pop {[[SAVED]]}
212 ; CHECK-V5T-NEXT:    pop {r3}
213 ; CHECK-V5T-NEXT:    add sp,
214 ; CHECK-V5T-NEXT:    bx r3
215 }
216
217 declare void @llvm.va_start(i8*) nounwind