[MIPS GlobalISel] Select MSA vector generic and builtin add
[llvm-complete.git] / test / CodeGen / ARM / thumb1_return_sequence.ll
bloba7f78c74f7f3abd70332c8346371d5dc296eab35
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 {
7 entry:
8 ; Prologue
9 ; --------
10 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
11 ; CHECK-V4T:    sub sp,
12 ; Stack is realigned because of the <6 x i32> type
13 ; CHECK-V4T:    mov sp, r4
14 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
16   %b = alloca <6 x i32>, align 16
17   %a = alloca <4 x i32>, align 16
18   %stuff = load <6 x i32>, <6 x i32>* %p, align 16
19   store <6 x i32> %stuff, <6 x i32>* %b, align 16
20   store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
21   %0 = load <4 x i32>, <4 x i32>* %a, align 16
22   ret <4 x i32> %0
24 ; Epilogue
25 ; --------
26 ; Stack realignment means sp is restored from frame pointer
27 ; CHECK-V4T:         mov sp
28 ; CHECK-V4T-NEXT:    ldr [[POP:r[4567]]], [sp, #16]
29 ; CHECK-V4T-NEXT:    mov lr, [[POP]]
30 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
31 ; CHECK-V4T-NEXT     add sp, sp, #4
32 ; The ISA for v4 does not support pop pc, so make sure we do not emit
33 ; one even when we do not need to update SP.
34 ; CHECK-V4T-NOT:     pop {pc}
35 ; CHECK-V4T:         bx lr
36 ; CHECK-V5T:         pop {[[SAVED]], pc}
39 ; CHECK-V4T-LABEL: clobbervariadicframe
40 ; CHECK-V5T-LABEL: clobbervariadicframe
41 define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 {
42 entry:
43 ; Prologue
44 ; --------
45 ; CHECK-V4T:    sub sp,
46 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
47 ; CHECK-V5T:    sub sp,
48 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
50   %b = alloca <4 x i32>, align 16
51   %a = alloca <4 x i32>, align 16
52   store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
53   store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
54   %0 = load <4 x i32>, <4 x i32>* %a, align 16
55   call void @llvm.va_start(i8* null)
56   ret <4 x i32> %0
58 ; Epilogue
59 ; --------
60 ; CHECK-V4T:         ldr [[POP:r[4567]]], [sp, #16]
61 ; CHECK-V4T-NEXT:    mov lr, [[POP]]
62 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
63 ; CHECK-V4T-NEXT:    add sp, #16
64 ; CHECK-V4T-NEXT:    bx  lr
65 ; CHECK-V5T:         lsls r4
66 ; CHECK-V5T-NEXT:    mov sp, r4
67 ; CHECK-V5T:         ldr [[POP:r[4567]]], [sp, #16]
68 ; CHECK-V5T-NEXT:    mov lr, [[POP]]
69 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
70 ; CHECK-V5T-NEXT:    add sp, #16
71 ; CHECK-V5T-NEXT:    bx  lr
74 ; CHECK-V4T-LABEL: simpleframe
75 ; CHECK-V5T-LABEL: simpleframe
76 define i32 @simpleframe(<6 x i32>* %p) #0 {
77 entry:
78 ; Prologue
79 ; --------
80 ; CHECK-V4T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
81 ; CHECK-V5T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
83   %0 = load <6 x i32>, <6 x i32>* %p, align 16
84   %1 = extractelement <6 x i32> %0, i32 0
85   %2 = extractelement <6 x i32> %0, i32 1
86   %3 = extractelement <6 x i32> %0, i32 2
87   %4 = extractelement <6 x i32> %0, i32 3
88   %5 = extractelement <6 x i32> %0, i32 4
89   %6 = extractelement <6 x i32> %0, i32 5
90   %add1 = add nsw i32 %1, %2
91   %add2 = add nsw i32 %add1, %3
92   %add3 = add nsw i32 %add2, %4
93   %add4 = add nsw i32 %add3, %5
94   %add5 = add nsw i32 %add4, %6
95   ret i32 %add5
97 ; Epilogue
98 ; --------
99 ; CHECK-V4T:    pop {[[SAVED]]}
100 ; The ISA for v4 does not support pop pc, so make sure we do not emit
101 ; one even when we do not need to update SP.
102 ; CHECK-V4T-NOT:     pop {pc}
103 ; Pop the value of LR into a scratch lo register other than r0 (it is
104 ; used for the return value).
105 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
106 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
107 ; CHECK-V5T:    pop {[[SAVED]], pc}
110 ; CHECK-V4T-LABEL: simplevariadicframe
111 ; CHECK-V5T-LABEL: simplevariadicframe
112 define i32 @simplevariadicframe(i32 %i, ...) #0 {
113 entry:
114 ; Prologue
115 ; --------
116 ; CHECK-V4T:    sub sp,
117 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
118 ; CHECK-V4T:    sub sp,
119 ; CHECK-V5T:    sub sp,
120 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
121 ; CHECK-V5T:    sub sp,
123   %a = alloca i32, align 4
124   %b = alloca i32, align 4
125   %c = alloca i32, align 4
126   %d = alloca i32, align 4
127   store i32 1, i32* %a, align 4
128   store i32 2, i32* %b, align 4
129   store i32 3, i32* %c, align 4
130   store i32 4, i32* %d, align 4
131   %0 = load i32, i32* %a, align 4
132   %inc = add nsw i32 %0, 1
133   store i32 %inc, i32* %a, align 4
134   %1 = load i32, i32* %b, align 4
135   %inc1 = add nsw i32 %1, 1
136   store i32 %inc1, i32* %b, align 4
137   %2 = load i32, i32* %c, align 4
138   %inc2 = add nsw i32 %2, 1
139   store i32 %inc2, i32* %c, align 4
140   %3 = load i32, i32* %d, align 4
141   %inc3 = add nsw i32 %3, 1
142   store i32 %inc3, i32* %d, align 4
143   %4 = load i32, i32* %a, align 4
144   %5 = load i32, i32* %b, align 4
145   %add = add nsw i32 %4, %5
146   %6 = load i32, i32* %c, align 4
147   %add4 = add nsw i32 %add, %6
148   %7 = load i32, i32* %d, align 4
149   %add5 = add nsw i32 %add4, %7
150   %add6 = add nsw i32 %add5, %i
151   call void @llvm.va_start(i8* null)
152   ret i32 %add6
154 ; Epilogue
155 ; --------
156 ; CHECK-V4T:         add sp,
157 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
158 ; Only r1 to r3 are available to pop LR.
159 ; r0 is used for the return value.
160 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
161 ; CHECK-V4T-NEXT:    add sp,
162 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
163 ; CHECK-V5T:         add sp,
164 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
165 ; Only r1 to r3 are available to pop LR.
166 ; r0 is used for the return value.
167 ; CHECK-V5T-NEXT:    pop {[[POP_REG:r[1-3]]]}
168 ; CHECK-V5T-NEXT:    add sp,
169 ; CHECK-V5T-NEXT:    bx [[POP_REG]]
172 ; CHECK-V4T-LABEL: noframe
173 ; CHECK-V5T-LABEL: noframe
174 define i32 @noframe() #0 {
175 entry:
176 ; Prologue
177 ; --------
178 ; CHECK-V4T-NOT: push
179 ; CHECK-V5T-NOT: push
180     ret i32 0;
181 ; Epilogue
182 ; --------
183 ; CHECK-V4T-NOT: pop
184 ; CHECK-V5T-NOT: pop
185 ; CHECK-V4T:    bx  lr
186 ; CHECK-V5T:    bx  lr
189 ; CHECK-V4T-LABEL: novariadicframe
190 ; CHECK-V5T-LABEL: novariadicframe
191 define i32 @novariadicframe(i32 %i, ...) #0 {
192 entry:
193 ; Prologue
194 ; --------
195 ; CHECK-V4T:    sub sp,
196 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
197 ; CHECK-V5T:    sub sp,
198 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
200   call void @llvm.va_start(i8* null)
201   ret i32 %i;
202 ; Epilogue
203 ; --------
204 ; CHECK-V4T:         pop {[[SAVED]]}
205 ; Only r1 to r3 are available to pop LR.
206 ; r0 is used for the return value.
207 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
208 ; CHECK-V4T-NEXT:    add sp,
209 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
210 ; CHECK-V5T:         pop {[[SAVED]]}
211 ; Only r1 to r3 are available to pop LR.
212 ; r0 is used for the return value.
213 ; CHECK-V5T-NEXT:    pop {[[POP_REG:r[1-3]]]}
214 ; CHECK-V5T-NEXT:    add sp,
215 ; CHECK-V5T-NEXT:    bx [[POP_REG]]
218 declare void @llvm.va_start(i8*) nounwind