Fix return sequence on armv4 thumb
[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 {r4, r5, r7, lr}
11 ; CHECK-V4T:    sub sp,
12 ; CHECK-V5T:    push {r4, r5, r7, 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 {r4, r5, r7}
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 {r4, r5, r7, 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 {r4, r5, r7, lr}
41 ; CHECK-V5T:    sub sp,
42 ; CHECK-V5T:    push {r4, r5, r7, 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   ret <4 x i32> %0
50
51 ; Epilogue
52 ; --------
53 ; CHECK-V4T:         pop {r4, r5, r7}
54 ; CHECK-V4T-NEXT:    mov r12, r3
55 ; CHECK-V4T-NEXT:    pop {r3}
56 ; CHECK-V4T-NEXT:    add sp,
57 ; CHECK-V4T-NEXT:    mov lr, r3
58 ; CHECK-V4T-NEXT:    mov r3, r12
59 ; CHECK-V4T:         bx  lr
60 ; CHECK-V5T:         add sp,
61 ; CHECK-V5T-NEXT:    pop {r4, r5, r7}
62 ; CHECK-V5T-NEXT:    mov r12, r3
63 ; CHECK-V5T-NEXT:    pop {r3}
64 ; CHECK-V5T-NEXT:    add sp,
65 ; CHECK-V5T-NEXT:    mov lr, r3
66 ; CHECK-V5T-NEXT:    mov r3, r12
67 ; CHECK-V5T-NEXT:    bx lr
68 }
69
70 ; CHECK-V4T-LABEL: simpleframe
71 ; CHECK-V5T-LABEL: simpleframe
72 define i32 @simpleframe() #0 {
73 entry:
74 ; Prologue
75 ; --------
76 ; CHECK-V4T:    push    {r4, lr}
77 ; CHECK-V5T:    push    {r4, lr}
78
79   %a = alloca i32, align 4
80   %b = alloca i32, align 4
81   %c = alloca i32, align 4
82   %d = alloca i32, align 4
83   store i32 1, i32* %a, align 4
84   store i32 2, i32* %b, align 4
85   store i32 3, i32* %c, align 4
86   store i32 4, i32* %d, align 4
87   %0 = load i32* %a, align 4
88   %inc = add nsw i32 %0, 1
89   store i32 %inc, i32* %a, align 4
90   %1 = load i32* %b, align 4
91   %inc1 = add nsw i32 %1, 1
92   store i32 %inc1, i32* %b, align 4
93   %2 = load i32* %c, align 4
94   %inc2 = add nsw i32 %2, 1
95   store i32 %inc2, i32* %c, align 4
96   %3 = load i32* %d, align 4
97   %inc3 = add nsw i32 %3, 1
98   store i32 %inc3, i32* %d, align 4
99   %4 = load i32* %a, align 4
100   %5 = load i32* %b, align 4
101   %add = add nsw i32 %4, %5
102   %6 = load i32* %c, align 4
103   %add4 = add nsw i32 %add, %6
104   %7 = load i32* %d, align 4
105   %add5 = add nsw i32 %add4, %7
106   ret i32 %add5
107
108 ; Epilogue
109 ; --------
110 ; CHECK-V4T:    pop {r4}
111 ; CHECK-V4T:    pop {r3}
112 ; CHECK-V4T:    bx r3
113 ; CHECK-V5T:    pop {r4, pc}
114 }
115
116 ; CHECK-V4T-LABEL: simplevariadicframe
117 ; CHECK-V5T-LABEL: simplevariadicframe
118 define i32 @simplevariadicframe(i32 %i, ...) #0 {
119 entry:
120 ; Prologue
121 ; --------
122 ; CHECK-V4T:    sub sp,
123 ; CHECK-V4T:    push {r4, r5, r7, lr}
124 ; CHECK-V4T:    sub sp,
125 ; CHECK-V5T:    sub sp,
126 ; CHECK-V5T:    push {r4, r5, r7, lr}
127 ; CHECK-V5T:    sub sp,
128
129   %a = alloca i32, align 4
130   %b = alloca i32, align 4
131   %c = alloca i32, align 4
132   %d = alloca i32, align 4
133   store i32 1, i32* %a, align 4
134   store i32 2, i32* %b, align 4
135   store i32 3, i32* %c, align 4
136   store i32 4, i32* %d, align 4
137   %0 = load i32* %a, align 4
138   %inc = add nsw i32 %0, 1
139   store i32 %inc, i32* %a, align 4
140   %1 = load i32* %b, align 4
141   %inc1 = add nsw i32 %1, 1
142   store i32 %inc1, i32* %b, align 4
143   %2 = load i32* %c, align 4
144   %inc2 = add nsw i32 %2, 1
145   store i32 %inc2, i32* %c, align 4
146   %3 = load i32* %d, align 4
147   %inc3 = add nsw i32 %3, 1
148   store i32 %inc3, i32* %d, align 4
149   %4 = load i32* %a, align 4
150   %5 = load i32* %b, align 4
151   %add = add nsw i32 %4, %5
152   %6 = load i32* %c, align 4
153   %add4 = add nsw i32 %add, %6
154   %7 = load i32* %d, align 4
155   %add5 = add nsw i32 %add4, %7
156   %add6 = add nsw i32 %add5, %i
157   ret i32 %add6
158
159 ; Epilogue
160 ; --------
161 ; CHECK-V4T:         add sp,
162 ; CHECK-V4T-NEXT:    pop {r4, r5, r7}
163 ; CHECK-V4T-NEXT:    pop {r3}
164 ; CHECK-V4T-NEXT:    add sp,
165 ; CHECK-V4T-NEXT:    bx r3
166 ; CHECK-V5T:         add sp,
167 ; CHECK-V5T-NEXT:    pop {r4, r5, r7}
168 ; CHECK-V5T-NEXT:    pop {r3}
169 ; CHECK-V5T-NEXT:    add sp,
170 ; CHECK-V5T-NEXT:    bx r3
171 }
172
173 ; CHECK-V4T-LABEL: noframe
174 ; CHECK-V5T-LABEL: noframe
175 define i32 @noframe() #0 {
176 entry:
177 ; Prologue
178 ; --------
179 ; CHECK-V4T-NOT: push
180 ; CHECK-V5T-NOT: push
181     ret i32 0;
182 ; Epilogue
183 ; --------
184 ; CHECK-V4T-NOT: pop
185 ; CHECK-V5T-NOT: pop
186 ; CHECK-V4T:    bx  lr
187 ; CHECK-V5T:    bx  lr
188 }
189
190 ; CHECK-V4T-LABEL: novariadicframe
191 ; CHECK-V5T-LABEL: novariadicframe
192 define i32 @novariadicframe(i32 %i) #0 {
193 entry:
194 ; Prologue
195 ; --------
196 ; CHECK-V4T-NOT: push
197 ; CHECK-V5T-NOT: push
198     ret i32 %i;
199 ; Epilogue
200 ; --------
201 ; CHECK-V4T-NOT: pop
202 ; CHECK-V5T-NOT: pop
203 ; CHECK-V4T:    bx  lr
204 ; CHECK-V5T:    bx  lr
205 }