Taints the non-acquire RMW's store address with the load part
[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(<6 x i32>* %p) #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 <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
20   ret <4 x i32> %0
21
22 ; Epilogue
23 ; --------
24 ; CHECK-V4T:         add sp,
25 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
26 ; The ISA for v4 does not support pop pc, so make sure we do not emit
27 ; one even when we do not need to update SP.
28 ; CHECK-V4T-NOT:     pop {pc}
29 ; We may only use lo register to pop, but in that case, all the scratch
30 ; ones are used.
31 ; r12 is the only register we are allowed to clobber for AAPCS.
32 ; Use it to save a lo register.
33 ; CHECK-V4T-NEXT:    mov [[TEMP_REG:r12]], [[POP_REG:r[0-7]]]
34 ; Pop the value of LR.
35 ; CHECK-V4T-NEXT:    pop {[[POP_REG]]}
36 ; Copy the value of LR in the right register.
37 ; CHECK-V4T-NEXT:    mov lr, [[POP_REG]]
38 ; Restore the value that was in the register we used to pop the value of LR.
39 ; CHECK-V4T-NEXT:    mov [[POP_REG]], [[TEMP_REG]]
40 ; Return.
41 ; CHECK-V4T-NEXT:    bx lr
42 ; CHECK-V5T:         pop {[[SAVED]], pc}
43 }
44
45 ; CHECK-V4T-LABEL: clobbervariadicframe
46 ; CHECK-V5T-LABEL: clobbervariadicframe
47 define <4 x i32> @clobbervariadicframe(i32 %i, ...) #0 {
48 entry:
49 ; Prologue
50 ; --------
51 ; CHECK-V4T:    sub sp,
52 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
53 ; CHECK-V5T:    sub sp,
54 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
55
56   %b = alloca <4 x i32>, align 16
57   %a = alloca <4 x i32>, align 16
58   store <4 x i32> <i32 42, i32 42, i32 42, i32 42>, <4 x i32>* %b, align 16
59   store <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32>* %a, align 16
60   %0 = load <4 x i32>, <4 x i32>* %a, align 16
61   call void @llvm.va_start(i8* null)
62   ret <4 x i32> %0
63
64 ; Epilogue
65 ; --------
66 ; CHECK-V4T:         pop {[[SAVED]]}
67 ; CHECK-V4T-NEXT:    mov r12, [[POP_REG:r[0-7]]]
68 ; CHECK-V4T-NEXT:    pop {[[POP_REG]]}
69 ; CHECK-V4T-NEXT:    add sp,
70 ; CHECK-V4T-NEXT:    mov lr, [[POP_REG]]
71 ; CHECK-V4T-NEXT:    mov [[POP_REG]], r12
72 ; CHECK-V4T:         bx  lr
73 ; CHECK-V5T:         add sp,
74 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
75 ; CHECK-V5T-NEXT:    mov r12, [[POP_REG:r[0-7]]]
76 ; CHECK-V5T-NEXT:    pop {[[POP_REG]]}
77 ; CHECK-V5T-NEXT:    add sp,
78 ; CHECK-V5T-NEXT:    mov lr, [[POP_REG]]
79 ; CHECK-V5T-NEXT:    mov [[POP_REG]], r12
80 ; CHECK-V5T-NEXT:    bx lr
81 }
82
83 ; CHECK-V4T-LABEL: simpleframe
84 ; CHECK-V5T-LABEL: simpleframe
85 define i32 @simpleframe(<6 x i32>* %p) #0 {
86 entry:
87 ; Prologue
88 ; --------
89 ; CHECK-V4T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
90 ; CHECK-V5T:    push    {[[SAVED:(r[4567](, )?)+]], lr}
91
92   %0 = load <6 x i32>, <6 x i32>* %p, align 16
93   %1 = extractelement <6 x i32> %0, i32 0
94   %2 = extractelement <6 x i32> %0, i32 1
95   %3 = extractelement <6 x i32> %0, i32 2
96   %4 = extractelement <6 x i32> %0, i32 3
97   %5 = extractelement <6 x i32> %0, i32 4
98   %6 = extractelement <6 x i32> %0, i32 5
99   %add1 = add nsw i32 %1, %2
100   %add2 = add nsw i32 %add1, %3
101   %add3 = add nsw i32 %add2, %4
102   %add4 = add nsw i32 %add3, %5
103   %add5 = add nsw i32 %add4, %6
104   ret i32 %add5
105
106 ; Epilogue
107 ; --------
108 ; CHECK-V4T:    pop {[[SAVED]]}
109 ; The ISA for v4 does not support pop pc, so make sure we do not emit
110 ; one even when we do not need to update SP.
111 ; CHECK-V4T-NOT:     pop {pc}
112 ; Pop the value of LR into a scratch lo register other than r0 (it is
113 ; used for the return value).
114 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
115 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
116 ; CHECK-V5T:    pop {[[SAVED]], pc}
117 }
118
119 ; CHECK-V4T-LABEL: simplevariadicframe
120 ; CHECK-V5T-LABEL: simplevariadicframe
121 define i32 @simplevariadicframe(i32 %i, ...) #0 {
122 entry:
123 ; Prologue
124 ; --------
125 ; CHECK-V4T:    sub sp,
126 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
127 ; CHECK-V4T:    sub sp,
128 ; CHECK-V5T:    sub sp,
129 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
130 ; CHECK-V5T:    sub sp,
131
132   %a = alloca i32, align 4
133   %b = alloca i32, align 4
134   %c = alloca i32, align 4
135   %d = alloca i32, align 4
136   store i32 1, i32* %a, align 4
137   store i32 2, i32* %b, align 4
138   store i32 3, i32* %c, align 4
139   store i32 4, i32* %d, align 4
140   %0 = load i32, i32* %a, align 4
141   %inc = add nsw i32 %0, 1
142   store i32 %inc, i32* %a, align 4
143   %1 = load i32, i32* %b, align 4
144   %inc1 = add nsw i32 %1, 1
145   store i32 %inc1, i32* %b, align 4
146   %2 = load i32, i32* %c, align 4
147   %inc2 = add nsw i32 %2, 1
148   store i32 %inc2, i32* %c, align 4
149   %3 = load i32, i32* %d, align 4
150   %inc3 = add nsw i32 %3, 1
151   store i32 %inc3, i32* %d, align 4
152   %4 = load i32, i32* %a, align 4
153   %5 = load i32, i32* %b, align 4
154   %add = add nsw i32 %4, %5
155   %6 = load i32, i32* %c, align 4
156   %add4 = add nsw i32 %add, %6
157   %7 = load i32, i32* %d, align 4
158   %add5 = add nsw i32 %add4, %7
159   %add6 = add nsw i32 %add5, %i
160   call void @llvm.va_start(i8* null)
161   ret i32 %add6
162
163 ; Epilogue
164 ; --------
165 ; CHECK-V4T:         add sp,
166 ; CHECK-V4T-NEXT:    pop {[[SAVED]]}
167 ; Only r1 to r3 are available to pop LR.
168 ; r0 is used for the return value.
169 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
170 ; CHECK-V4T-NEXT:    add sp,
171 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
172 ; CHECK-V5T:         add sp,
173 ; CHECK-V5T-NEXT:    pop {[[SAVED]]}
174 ; Only r1 to r3 are available to pop LR.
175 ; r0 is used for the return value.
176 ; CHECK-V5T-NEXT:    pop {[[POP_REG:r[1-3]]]}
177 ; CHECK-V5T-NEXT:    add sp,
178 ; CHECK-V5T-NEXT:    bx [[POP_REG]]
179 }
180
181 ; CHECK-V4T-LABEL: noframe
182 ; CHECK-V5T-LABEL: noframe
183 define i32 @noframe() #0 {
184 entry:
185 ; Prologue
186 ; --------
187 ; CHECK-V4T-NOT: push
188 ; CHECK-V5T-NOT: push
189     ret i32 0;
190 ; Epilogue
191 ; --------
192 ; CHECK-V4T-NOT: pop
193 ; CHECK-V5T-NOT: pop
194 ; CHECK-V4T:    bx  lr
195 ; CHECK-V5T:    bx  lr
196 }
197
198 ; CHECK-V4T-LABEL: novariadicframe
199 ; CHECK-V5T-LABEL: novariadicframe
200 define i32 @novariadicframe(i32 %i, ...) #0 {
201 entry:
202 ; Prologue
203 ; --------
204 ; CHECK-V4T:    sub sp,
205 ; CHECK-V4T:    push {[[SAVED:(r[4567](, )?)+]], lr}
206 ; CHECK-V5T:    sub sp,
207 ; CHECK-V5T:    push {[[SAVED:(r[4567](, )?)+]], lr}
208
209   call void @llvm.va_start(i8* null)
210   ret i32 %i;
211 ; Epilogue
212 ; --------
213 ; CHECK-V4T:         pop {[[SAVED]]}
214 ; Only r1 to r3 are available to pop LR.
215 ; r0 is used for the return value.
216 ; CHECK-V4T-NEXT:    pop {[[POP_REG:r[1-3]]]}
217 ; CHECK-V4T-NEXT:    add sp,
218 ; CHECK-V4T-NEXT:    bx [[POP_REG]]
219 ; CHECK-V5T:         pop {[[SAVED]]}
220 ; Only r1 to r3 are available to pop LR.
221 ; r0 is used for the return value.
222 ; CHECK-V5T-NEXT:    pop {[[POP_REG:r[1-3]]]}
223 ; CHECK-V5T-NEXT:    add sp,
224 ; CHECK-V5T-NEXT:    bx [[POP_REG]]
225 }
226
227 declare void @llvm.va_start(i8*) nounwind