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
4 ; CHECK-V4T-LABEL: clobberframe
5 ; CHECK-V5T-LABEL: clobberframe
6 define <4 x i32> @clobberframe(<6 x i32>* %p) #0 {
10 ; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr}
12 ; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
14 %b = alloca <6 x i32>, align 16
15 %a = alloca <4 x i32>, align 16
16 %stuff = load <6 x i32>, <6 x i32>* %p, align 16
17 store <6 x i32> %stuff, <6 x i32>* %b, align 16
18 store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
19 %0 = load <4 x i32>, <4 x i32>* %a, align 16
25 ; CHECK-V4T-NEXT: pop {[[SAVED]]}
26 ; CHECK-V4T-NEXT: mov r12, r3
27 ; CHECK-V4T-NEXT: pop {r3}
28 ; CHECK-V4T-NEXT: mov lr, r3
29 ; CHECK-V4T-NEXT: mov r3, r12
31 ; CHECK-V5T: pop {[[SAVED]], pc}
34 ; CHECK-V4T-LABEL: clobbervariadicframe
35 ; CHECK-V5T-LABEL: clobbervariadicframe
36 define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 {
41 ; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr}
43 ; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
45 %b = alloca <4 x i32>, align 16
46 %a = alloca <4 x i32>, align 16
47 store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
48 store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
49 %0 = load <4 x i32>, <4 x i32>* %a, align 16
50 call void @llvm.va_start(i8* null)
55 ; CHECK-V4T: pop {[[SAVED]]}
56 ; CHECK-V4T-NEXT: mov r12, r3
57 ; CHECK-V4T-NEXT: pop {r3}
58 ; CHECK-V4T-NEXT: add sp,
59 ; CHECK-V4T-NEXT: mov lr, r3
60 ; CHECK-V4T-NEXT: mov r3, r12
63 ; CHECK-V5T-NEXT: pop {[[SAVED]]}
64 ; CHECK-V5T-NEXT: mov r12, r3
65 ; CHECK-V5T-NEXT: pop {r3}
66 ; CHECK-V5T-NEXT: add sp,
67 ; CHECK-V5T-NEXT: mov lr, r3
68 ; CHECK-V5T-NEXT: mov r3, r12
69 ; CHECK-V5T-NEXT: bx lr
72 ; CHECK-V4T-LABEL: simpleframe
73 ; CHECK-V5T-LABEL: simpleframe
74 define i32 @simpleframe(<6 x i32>* %p) #0 {
78 ; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr}
79 ; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
81 %0 = load <6 x i32>, <6 x i32>* %p, align 16
82 %1 = extractelement <6 x i32> %0, i32 0
83 %2 = extractelement <6 x i32> %0, i32 1
84 %3 = extractelement <6 x i32> %0, i32 2
85 %4 = extractelement <6 x i32> %0, i32 3
86 %5 = extractelement <6 x i32> %0, i32 4
87 %6 = extractelement <6 x i32> %0, i32 5
88 %add1 = add nsw i32 %1, %2
89 %add2 = add nsw i32 %add1, %3
90 %add3 = add nsw i32 %add2, %4
91 %add4 = add nsw i32 %add3, %5
92 %add5 = add nsw i32 %add4, %6
97 ; CHECK-V4T: pop {[[SAVED]]}
100 ; CHECK-V5T: pop {[[SAVED]], pc}
103 ; CHECK-V4T-LABEL: simplevariadicframe
104 ; CHECK-V5T-LABEL: simplevariadicframe
105 define i32 @simplevariadicframe(i32 %i, ...) #0 {
110 ; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr}
113 ; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
116 %a = alloca i32, align 4
117 %b = alloca i32, align 4
118 %c = alloca i32, align 4
119 %d = alloca i32, align 4
120 store i32 1, i32* %a, align 4
121 store i32 2, i32* %b, align 4
122 store i32 3, i32* %c, align 4
123 store i32 4, i32* %d, align 4
124 %0 = load i32, i32* %a, align 4
125 %inc = add nsw i32 %0, 1
126 store i32 %inc, i32* %a, align 4
127 %1 = load i32, i32* %b, align 4
128 %inc1 = add nsw i32 %1, 1
129 store i32 %inc1, i32* %b, align 4
130 %2 = load i32, i32* %c, align 4
131 %inc2 = add nsw i32 %2, 1
132 store i32 %inc2, i32* %c, align 4
133 %3 = load i32, i32* %d, align 4
134 %inc3 = add nsw i32 %3, 1
135 store i32 %inc3, i32* %d, align 4
136 %4 = load i32, i32* %a, align 4
137 %5 = load i32, i32* %b, align 4
138 %add = add nsw i32 %4, %5
139 %6 = load i32, i32* %c, align 4
140 %add4 = add nsw i32 %add, %6
141 %7 = load i32, i32* %d, align 4
142 %add5 = add nsw i32 %add4, %7
143 %add6 = add nsw i32 %add5, %i
144 call void @llvm.va_start(i8* null)
150 ; CHECK-V4T-NEXT: pop {[[SAVED]]}
151 ; CHECK-V4T-NEXT: pop {r3}
152 ; CHECK-V4T-NEXT: add sp,
153 ; CHECK-V4T-NEXT: bx r3
155 ; CHECK-V5T-NEXT: pop {[[SAVED]]}
156 ; CHECK-V5T-NEXT: pop {r3}
157 ; CHECK-V5T-NEXT: add sp,
158 ; CHECK-V5T-NEXT: bx r3
161 ; CHECK-V4T-LABEL: noframe
162 ; CHECK-V5T-LABEL: noframe
163 define i32 @noframe() #0 {
167 ; CHECK-V4T-NOT: push
168 ; CHECK-V5T-NOT: push
178 ; CHECK-V4T-LABEL: novariadicframe
179 ; CHECK-V5T-LABEL: novariadicframe
180 define i32 @novariadicframe(i32 %i, ...) #0 {
185 ; CHECK-V4T: push {[[SAVED:(r[4567](, )?)+]], lr}
187 ; CHECK-V5T: push {[[SAVED:(r[4567](, )?)+]], lr}
189 call void @llvm.va_start(i8* null)
193 ; CHECK-V4T: pop {[[SAVED]]}
194 ; CHECK-V4T-NEXT: pop {r3}
195 ; CHECK-V4T-NEXT: add sp,
196 ; CHECK-V4T-NEXT: bx r3
197 ; CHECK-V5T: pop {[[SAVED]]}
198 ; CHECK-V5T-NEXT: pop {r3}
199 ; CHECK-V5T-NEXT: add sp,
200 ; CHECK-V5T-NEXT: bx r3
203 declare void @llvm.va_start(i8*) nounwind