blob: d8bca89b7fad4a0466dc6d045bcd327bf665d5a3 [file] [log] [blame]
Tim Northoverb4ddc082014-05-30 10:09:59 +00001; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-atomic-cfg-tidy=0 -verify-machineinstrs -o - %s | FileCheck %s
Tilmann Scheller2d746bc2014-05-26 09:37:19 +00002
3; This file contains tests for the AArch64 load/store optimizer.
4
Tilmann Scheller112ada82014-05-26 12:15:51 +00005%padding = type { i8*, i8*, i8*, i8* }
6%s.word = type { i32, i32 }
7%s.doubleword = type { i64, i32 }
8%s.quadword = type { fp128, i32 }
9%s.float = type { float, i32 }
10%s.double = type { double, i32 }
11%struct.word = type { %padding, %s.word }
12%struct.doubleword = type { %padding, %s.doubleword }
13%struct.quadword = type { %padding, %s.quadword }
14%struct.float = type { %padding, %s.float }
15%struct.double = type { %padding, %s.double }
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000016
17; Check the following transform:
18;
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000019; (ldr|str) X, [x0, #32]
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000020; ...
21; add x0, x0, #32
22; ->
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000023; (ldr|str) X, [x0, #32]!
Tilmann Scheller112ada82014-05-26 12:15:51 +000024;
25; with X being either w1, x1, s0, d0 or q0.
Tilmann Scheller968d5992014-05-26 09:40:40 +000026
Tilmann Scheller112ada82014-05-26 12:15:51 +000027declare void @bar_word(%s.word*, i32)
28
29define void @load-pre-indexed-word(%struct.word* %ptr) nounwind {
30; CHECK-LABEL: load-pre-indexed-word
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000031; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
32entry:
David Blaikie79e6c742015-02-27 19:29:02 +000033 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000034 %add = load i32* %a, align 4
35 br label %bar
36bar:
David Blaikie79e6c742015-02-27 19:29:02 +000037 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +000038 tail call void @bar_word(%s.word* %c, i32 %add)
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000039 ret void
40}
41
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000042define void @store-pre-indexed-word(%struct.word* %ptr, i32 %val) nounwind {
43; CHECK-LABEL: store-pre-indexed-word
44; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
45entry:
David Blaikie79e6c742015-02-27 19:29:02 +000046 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000047 store i32 %val, i32* %a, align 4
48 br label %bar
49bar:
David Blaikie79e6c742015-02-27 19:29:02 +000050 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000051 tail call void @bar_word(%s.word* %c, i32 %val)
52 ret void
53}
54
Tilmann Scheller112ada82014-05-26 12:15:51 +000055declare void @bar_doubleword(%s.doubleword*, i64)
56
57define void @load-pre-indexed-doubleword(%struct.doubleword* %ptr) nounwind {
58; CHECK-LABEL: load-pre-indexed-doubleword
59; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #32]!
60entry:
David Blaikie79e6c742015-02-27 19:29:02 +000061 %a = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1, i32 0
Tilmann Scheller112ada82014-05-26 12:15:51 +000062 %add = load i64* %a, align 4
63 br label %bar
64bar:
David Blaikie79e6c742015-02-27 19:29:02 +000065 %c = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +000066 tail call void @bar_doubleword(%s.doubleword* %c, i64 %add)
67 ret void
68}
69
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000070define void @store-pre-indexed-doubleword(%struct.doubleword* %ptr, i64 %val) nounwind {
71; CHECK-LABEL: store-pre-indexed-doubleword
72; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #32]!
73entry:
David Blaikie79e6c742015-02-27 19:29:02 +000074 %a = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000075 store i64 %val, i64* %a, align 4
76 br label %bar
77bar:
David Blaikie79e6c742015-02-27 19:29:02 +000078 %c = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000079 tail call void @bar_doubleword(%s.doubleword* %c, i64 %val)
80 ret void
81}
82
Tilmann Scheller112ada82014-05-26 12:15:51 +000083declare void @bar_quadword(%s.quadword*, fp128)
84
85define void @load-pre-indexed-quadword(%struct.quadword* %ptr) nounwind {
86; CHECK-LABEL: load-pre-indexed-quadword
87; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
88entry:
David Blaikie79e6c742015-02-27 19:29:02 +000089 %a = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1, i32 0
Tilmann Scheller112ada82014-05-26 12:15:51 +000090 %add = load fp128* %a, align 4
91 br label %bar
92bar:
David Blaikie79e6c742015-02-27 19:29:02 +000093 %c = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +000094 tail call void @bar_quadword(%s.quadword* %c, fp128 %add)
95 ret void
96}
97
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000098define void @store-pre-indexed-quadword(%struct.quadword* %ptr, fp128 %val) nounwind {
99; CHECK-LABEL: store-pre-indexed-quadword
100; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
101entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000102 %a = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000103 store fp128 %val, fp128* %a, align 4
104 br label %bar
105bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000106 %c = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000107 tail call void @bar_quadword(%s.quadword* %c, fp128 %val)
108 ret void
109}
110
Tilmann Scheller112ada82014-05-26 12:15:51 +0000111declare void @bar_float(%s.float*, float)
112
113define void @load-pre-indexed-float(%struct.float* %ptr) nounwind {
114; CHECK-LABEL: load-pre-indexed-float
115; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #32]!
116entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000117 %a = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1, i32 0
Tilmann Scheller112ada82014-05-26 12:15:51 +0000118 %add = load float* %a, align 4
119 br label %bar
120bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000121 %c = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000122 tail call void @bar_float(%s.float* %c, float %add)
123 ret void
124}
125
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000126define void @store-pre-indexed-float(%struct.float* %ptr, float %val) nounwind {
127; CHECK-LABEL: store-pre-indexed-float
128; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #32]!
129entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000130 %a = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000131 store float %val, float* %a, align 4
132 br label %bar
133bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000134 %c = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000135 tail call void @bar_float(%s.float* %c, float %val)
136 ret void
137}
138
Tilmann Scheller112ada82014-05-26 12:15:51 +0000139declare void @bar_double(%s.double*, double)
140
141define void @load-pre-indexed-double(%struct.double* %ptr) nounwind {
142; CHECK-LABEL: load-pre-indexed-double
143; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #32]!
144entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000145 %a = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1, i32 0
Tilmann Scheller112ada82014-05-26 12:15:51 +0000146 %add = load double* %a, align 4
147 br label %bar
148bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000149 %c = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000150 tail call void @bar_double(%s.double* %c, double %add)
151 ret void
152}
Tilmann Scheller2d746bc2014-05-26 09:37:19 +0000153
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000154define void @store-pre-indexed-double(%struct.double* %ptr, double %val) nounwind {
155; CHECK-LABEL: store-pre-indexed-double
156; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #32]!
157entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000158 %a = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000159 store double %val, double* %a, align 4
160 br label %bar
161bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000162 %c = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000163 tail call void @bar_double(%s.double* %c, double %val)
164 ret void
165}
Tilmann Scheller35e45142014-05-28 05:44:14 +0000166
167; Check the following transform:
168;
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000169; add x8, x8, #16
170; ...
171; ldr X, [x8]
172; ->
173; ldr X, [x8, #16]!
174;
175; with X being either w0, x0, s0, d0 or q0.
176
177%pre.struct.i32 = type { i32, i32, i32}
178%pre.struct.i64 = type { i32, i64, i64}
179%pre.struct.i128 = type { i32, <2 x i64>, <2 x i64>}
180%pre.struct.float = type { i32, float, float}
181%pre.struct.double = type { i32, double, double}
182
183define i32 @load-pre-indexed-word2(%pre.struct.i32** %this, i1 %cond,
184 %pre.struct.i32* %load2) nounwind {
185; CHECK-LABEL: load-pre-indexed-word2
186; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #4]!
187 br i1 %cond, label %if.then, label %if.end
188if.then:
189 %load1 = load %pre.struct.i32** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000190 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000191 br label %return
192if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000193 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000194 br label %return
195return:
196 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
197 %ret = load i32* %retptr
198 ret i32 %ret
199}
200
201define i64 @load-pre-indexed-doubleword2(%pre.struct.i64** %this, i1 %cond,
202 %pre.struct.i64* %load2) nounwind {
203; CHECK-LABEL: load-pre-indexed-doubleword2
204; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #8]!
205 br i1 %cond, label %if.then, label %if.end
206if.then:
207 %load1 = load %pre.struct.i64** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000208 %gep1 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000209 br label %return
210if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000211 %gep2 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000212 br label %return
213return:
214 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
215 %ret = load i64* %retptr
216 ret i64 %ret
217}
218
219define <2 x i64> @load-pre-indexed-quadword2(%pre.struct.i128** %this, i1 %cond,
220 %pre.struct.i128* %load2) nounwind {
221; CHECK-LABEL: load-pre-indexed-quadword2
222; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #16]!
223 br i1 %cond, label %if.then, label %if.end
224if.then:
225 %load1 = load %pre.struct.i128** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000226 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000227 br label %return
228if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000229 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000230 br label %return
231return:
232 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
233 %ret = load <2 x i64>* %retptr
234 ret <2 x i64> %ret
235}
236
237define float @load-pre-indexed-float2(%pre.struct.float** %this, i1 %cond,
238 %pre.struct.float* %load2) nounwind {
239; CHECK-LABEL: load-pre-indexed-float2
240; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #4]!
241 br i1 %cond, label %if.then, label %if.end
242if.then:
243 %load1 = load %pre.struct.float** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000244 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000245 br label %return
246if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000247 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000248 br label %return
249return:
250 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
251 %ret = load float* %retptr
252 ret float %ret
253}
254
255define double @load-pre-indexed-double2(%pre.struct.double** %this, i1 %cond,
256 %pre.struct.double* %load2) nounwind {
257; CHECK-LABEL: load-pre-indexed-double2
258; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #8]!
259 br i1 %cond, label %if.then, label %if.end
260if.then:
261 %load1 = load %pre.struct.double** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000262 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000263 br label %return
264if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000265 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000266 br label %return
267return:
268 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
269 %ret = load double* %retptr
270 ret double %ret
271}
272
273; Check the following transform:
274;
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000275; add x8, x8, #16
276; ...
277; str X, [x8]
278; ->
279; str X, [x8, #16]!
280;
281; with X being either w0, x0, s0, d0 or q0.
282
283define void @store-pre-indexed-word2(%pre.struct.i32** %this, i1 %cond,
284 %pre.struct.i32* %load2,
285 i32 %val) nounwind {
286; CHECK-LABEL: store-pre-indexed-word2
287; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #4]!
288 br i1 %cond, label %if.then, label %if.end
289if.then:
290 %load1 = load %pre.struct.i32** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000291 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000292 br label %return
293if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000294 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000295 br label %return
296return:
297 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
298 store i32 %val, i32* %retptr
299 ret void
300}
301
302define void @store-pre-indexed-doubleword2(%pre.struct.i64** %this, i1 %cond,
303 %pre.struct.i64* %load2,
304 i64 %val) nounwind {
305; CHECK-LABEL: store-pre-indexed-doubleword2
306; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #8]!
307 br i1 %cond, label %if.then, label %if.end
308if.then:
309 %load1 = load %pre.struct.i64** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000310 %gep1 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000311 br label %return
312if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000313 %gep2 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000314 br label %return
315return:
316 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
317 store i64 %val, i64* %retptr
318 ret void
319}
320
321define void @store-pre-indexed-quadword2(%pre.struct.i128** %this, i1 %cond,
322 %pre.struct.i128* %load2,
323 <2 x i64> %val) nounwind {
324; CHECK-LABEL: store-pre-indexed-quadword2
325; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #16]!
326 br i1 %cond, label %if.then, label %if.end
327if.then:
328 %load1 = load %pre.struct.i128** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000329 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000330 br label %return
331if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000332 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000333 br label %return
334return:
335 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
336 store <2 x i64> %val, <2 x i64>* %retptr
337 ret void
338}
339
340define void @store-pre-indexed-float2(%pre.struct.float** %this, i1 %cond,
341 %pre.struct.float* %load2,
342 float %val) nounwind {
343; CHECK-LABEL: store-pre-indexed-float2
344; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #4]!
345 br i1 %cond, label %if.then, label %if.end
346if.then:
347 %load1 = load %pre.struct.float** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000348 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000349 br label %return
350if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000351 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000352 br label %return
353return:
354 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
355 store float %val, float* %retptr
356 ret void
357}
358
359define void @store-pre-indexed-double2(%pre.struct.double** %this, i1 %cond,
360 %pre.struct.double* %load2,
361 double %val) nounwind {
362; CHECK-LABEL: store-pre-indexed-double2
363; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #8]!
364 br i1 %cond, label %if.then, label %if.end
365if.then:
366 %load1 = load %pre.struct.double** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000367 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000368 br label %return
369if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000370 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000371 br label %return
372return:
373 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
374 store double %val, double* %retptr
375 ret void
376}
377
378; Check the following transform:
379;
Tilmann Scheller35e45142014-05-28 05:44:14 +0000380; ldr X, [x20]
381; ...
382; add x20, x20, #32
383; ->
384; ldr X, [x20], #32
385;
386; with X being either w0, x0, s0, d0 or q0.
387
388define void @load-post-indexed-word(i32* %array, i64 %count) nounwind {
389; CHECK-LABEL: load-post-indexed-word
390; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #16
391entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000392 %gep1 = getelementptr i32, i32* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000393 br label %body
394
395body:
396 %iv2 = phi i32* [ %gep3, %body ], [ %gep1, %entry ]
397 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000398 %gep2 = getelementptr i32, i32* %iv2, i64 -1
Tilmann Scheller35e45142014-05-28 05:44:14 +0000399 %load = load i32* %gep2
400 call void @use-word(i32 %load)
401 %load2 = load i32* %iv2
402 call void @use-word(i32 %load2)
403 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000404 %gep3 = getelementptr i32, i32* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000405 %cond = icmp eq i64 %iv.next, 0
406 br i1 %cond, label %exit, label %body
407
408exit:
409 ret void
410}
411
412define void @load-post-indexed-doubleword(i64* %array, i64 %count) nounwind {
413; CHECK-LABEL: load-post-indexed-doubleword
414; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #32
415entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000416 %gep1 = getelementptr i64, i64* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000417 br label %body
418
419body:
420 %iv2 = phi i64* [ %gep3, %body ], [ %gep1, %entry ]
421 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000422 %gep2 = getelementptr i64, i64* %iv2, i64 -1
Tilmann Scheller35e45142014-05-28 05:44:14 +0000423 %load = load i64* %gep2
424 call void @use-doubleword(i64 %load)
425 %load2 = load i64* %iv2
426 call void @use-doubleword(i64 %load2)
427 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000428 %gep3 = getelementptr i64, i64* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000429 %cond = icmp eq i64 %iv.next, 0
430 br i1 %cond, label %exit, label %body
431
432exit:
433 ret void
434}
435
436define void @load-post-indexed-quadword(<2 x i64>* %array, i64 %count) nounwind {
437; CHECK-LABEL: load-post-indexed-quadword
438; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #64
439entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000440 %gep1 = getelementptr <2 x i64>, <2 x i64>* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000441 br label %body
442
443body:
444 %iv2 = phi <2 x i64>* [ %gep3, %body ], [ %gep1, %entry ]
445 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000446 %gep2 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 -1
Tilmann Scheller35e45142014-05-28 05:44:14 +0000447 %load = load <2 x i64>* %gep2
448 call void @use-quadword(<2 x i64> %load)
449 %load2 = load <2 x i64>* %iv2
450 call void @use-quadword(<2 x i64> %load2)
451 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000452 %gep3 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000453 %cond = icmp eq i64 %iv.next, 0
454 br i1 %cond, label %exit, label %body
455
456exit:
457 ret void
458}
459
460define void @load-post-indexed-float(float* %array, i64 %count) nounwind {
461; CHECK-LABEL: load-post-indexed-float
462; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #16
463entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000464 %gep1 = getelementptr float, float* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000465 br label %body
466
467body:
468 %iv2 = phi float* [ %gep3, %body ], [ %gep1, %entry ]
469 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000470 %gep2 = getelementptr float, float* %iv2, i64 -1
Tilmann Scheller35e45142014-05-28 05:44:14 +0000471 %load = load float* %gep2
472 call void @use-float(float %load)
473 %load2 = load float* %iv2
474 call void @use-float(float %load2)
475 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000476 %gep3 = getelementptr float, float* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000477 %cond = icmp eq i64 %iv.next, 0
478 br i1 %cond, label %exit, label %body
479
480exit:
481 ret void
482}
483
484define void @load-post-indexed-double(double* %array, i64 %count) nounwind {
485; CHECK-LABEL: load-post-indexed-double
486; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #32
487entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000488 %gep1 = getelementptr double, double* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000489 br label %body
490
491body:
492 %iv2 = phi double* [ %gep3, %body ], [ %gep1, %entry ]
493 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000494 %gep2 = getelementptr double, double* %iv2, i64 -1
Tilmann Scheller35e45142014-05-28 05:44:14 +0000495 %load = load double* %gep2
496 call void @use-double(double %load)
497 %load2 = load double* %iv2
498 call void @use-double(double %load2)
499 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000500 %gep3 = getelementptr double, double* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000501 %cond = icmp eq i64 %iv.next, 0
502 br i1 %cond, label %exit, label %body
503
504exit:
505 ret void
506}
507
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000508; Check the following transform:
509;
510; str X, [x20]
511; ...
512; add x20, x20, #32
513; ->
514; str X, [x20], #32
515;
516; with X being either w0, x0, s0, d0 or q0.
517
518define void @store-post-indexed-word(i32* %array, i64 %count, i32 %val) nounwind {
519; CHECK-LABEL: store-post-indexed-word
520; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #16
521entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000522 %gep1 = getelementptr i32, i32* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000523 br label %body
524
525body:
526 %iv2 = phi i32* [ %gep3, %body ], [ %gep1, %entry ]
527 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000528 %gep2 = getelementptr i32, i32* %iv2, i64 -1
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000529 %load = load i32* %gep2
530 call void @use-word(i32 %load)
531 store i32 %val, i32* %iv2
532 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000533 %gep3 = getelementptr i32, i32* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000534 %cond = icmp eq i64 %iv.next, 0
535 br i1 %cond, label %exit, label %body
536
537exit:
538 ret void
539}
540
541define void @store-post-indexed-doubleword(i64* %array, i64 %count, i64 %val) nounwind {
542; CHECK-LABEL: store-post-indexed-doubleword
543; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #32
544entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000545 %gep1 = getelementptr i64, i64* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000546 br label %body
547
548body:
549 %iv2 = phi i64* [ %gep3, %body ], [ %gep1, %entry ]
550 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000551 %gep2 = getelementptr i64, i64* %iv2, i64 -1
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000552 %load = load i64* %gep2
553 call void @use-doubleword(i64 %load)
554 store i64 %val, i64* %iv2
555 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000556 %gep3 = getelementptr i64, i64* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000557 %cond = icmp eq i64 %iv.next, 0
558 br i1 %cond, label %exit, label %body
559
560exit:
561 ret void
562}
563
564define void @store-post-indexed-quadword(<2 x i64>* %array, i64 %count, <2 x i64> %val) nounwind {
565; CHECK-LABEL: store-post-indexed-quadword
566; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #64
567entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000568 %gep1 = getelementptr <2 x i64>, <2 x i64>* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000569 br label %body
570
571body:
572 %iv2 = phi <2 x i64>* [ %gep3, %body ], [ %gep1, %entry ]
573 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000574 %gep2 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 -1
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000575 %load = load <2 x i64>* %gep2
576 call void @use-quadword(<2 x i64> %load)
577 store <2 x i64> %val, <2 x i64>* %iv2
578 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000579 %gep3 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000580 %cond = icmp eq i64 %iv.next, 0
581 br i1 %cond, label %exit, label %body
582
583exit:
584 ret void
585}
586
587define void @store-post-indexed-float(float* %array, i64 %count, float %val) nounwind {
588; CHECK-LABEL: store-post-indexed-float
589; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #16
590entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000591 %gep1 = getelementptr float, float* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000592 br label %body
593
594body:
595 %iv2 = phi float* [ %gep3, %body ], [ %gep1, %entry ]
596 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000597 %gep2 = getelementptr float, float* %iv2, i64 -1
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000598 %load = load float* %gep2
599 call void @use-float(float %load)
600 store float %val, float* %iv2
601 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000602 %gep3 = getelementptr float, float* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000603 %cond = icmp eq i64 %iv.next, 0
604 br i1 %cond, label %exit, label %body
605
606exit:
607 ret void
608}
609
610define void @store-post-indexed-double(double* %array, i64 %count, double %val) nounwind {
611; CHECK-LABEL: store-post-indexed-double
612; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #32
613entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000614 %gep1 = getelementptr double, double* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000615 br label %body
616
617body:
618 %iv2 = phi double* [ %gep3, %body ], [ %gep1, %entry ]
619 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000620 %gep2 = getelementptr double, double* %iv2, i64 -1
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000621 %load = load double* %gep2
622 call void @use-double(double %load)
623 store double %val, double* %iv2
624 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000625 %gep3 = getelementptr double, double* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000626 %cond = icmp eq i64 %iv.next, 0
627 br i1 %cond, label %exit, label %body
628
629exit:
630 ret void
631}
632
Tilmann Scheller35e45142014-05-28 05:44:14 +0000633declare void @use-word(i32)
634declare void @use-doubleword(i64)
635declare void @use-quadword(<2 x i64>)
636declare void @use-float(float)
637declare void @use-double(double)
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000638
639; Check the following transform:
640;
641; (ldr|str) X, [x20]
642; ...
643; sub x20, x20, #16
644; ->
645; (ldr|str) X, [x20], #-16
646;
647; with X being either w0, x0, s0, d0 or q0.
648
649define void @post-indexed-sub-word(i32* %a, i32* %b, i64 %count) nounwind {
650; CHECK-LABEL: post-indexed-sub-word
651; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #-8
652; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #-8
653 br label %for.body
654for.body:
655 %phi1 = phi i32* [ %gep4, %for.body ], [ %b, %0 ]
656 %phi2 = phi i32* [ %gep3, %for.body ], [ %a, %0 ]
657 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +0000658 %gep1 = getelementptr i32, i32* %phi1, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000659 %load1 = load i32* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +0000660 %gep2 = getelementptr i32, i32* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000661 store i32 %load1, i32* %gep2
662 %load2 = load i32* %phi1
663 store i32 %load2, i32* %phi2
664 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +0000665 %gep3 = getelementptr i32, i32* %phi2, i64 -2
666 %gep4 = getelementptr i32, i32* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000667 %cond = icmp sgt i64 %dec.i, 0
668 br i1 %cond, label %for.body, label %end
669end:
670 ret void
671}
672
673define void @post-indexed-sub-doubleword(i64* %a, i64* %b, i64 %count) nounwind {
674; CHECK-LABEL: post-indexed-sub-doubleword
675; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-16
676; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-16
677 br label %for.body
678for.body:
679 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
680 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
681 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +0000682 %gep1 = getelementptr i64, i64* %phi1, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000683 %load1 = load i64* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +0000684 %gep2 = getelementptr i64, i64* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000685 store i64 %load1, i64* %gep2
686 %load2 = load i64* %phi1
687 store i64 %load2, i64* %phi2
688 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +0000689 %gep3 = getelementptr i64, i64* %phi2, i64 -2
690 %gep4 = getelementptr i64, i64* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000691 %cond = icmp sgt i64 %dec.i, 0
692 br i1 %cond, label %for.body, label %end
693end:
694 ret void
695}
696
697define void @post-indexed-sub-quadword(<2 x i64>* %a, <2 x i64>* %b, i64 %count) nounwind {
698; CHECK-LABEL: post-indexed-sub-quadword
699; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #-32
700; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #-32
701 br label %for.body
702for.body:
703 %phi1 = phi <2 x i64>* [ %gep4, %for.body ], [ %b, %0 ]
704 %phi2 = phi <2 x i64>* [ %gep3, %for.body ], [ %a, %0 ]
705 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +0000706 %gep1 = getelementptr <2 x i64>, <2 x i64>* %phi1, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000707 %load1 = load <2 x i64>* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +0000708 %gep2 = getelementptr <2 x i64>, <2 x i64>* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000709 store <2 x i64> %load1, <2 x i64>* %gep2
710 %load2 = load <2 x i64>* %phi1
711 store <2 x i64> %load2, <2 x i64>* %phi2
712 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +0000713 %gep3 = getelementptr <2 x i64>, <2 x i64>* %phi2, i64 -2
714 %gep4 = getelementptr <2 x i64>, <2 x i64>* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000715 %cond = icmp sgt i64 %dec.i, 0
716 br i1 %cond, label %for.body, label %end
717end:
718 ret void
719}
720
721define void @post-indexed-sub-float(float* %a, float* %b, i64 %count) nounwind {
722; CHECK-LABEL: post-indexed-sub-float
723; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #-8
724; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #-8
725 br label %for.body
726for.body:
727 %phi1 = phi float* [ %gep4, %for.body ], [ %b, %0 ]
728 %phi2 = phi float* [ %gep3, %for.body ], [ %a, %0 ]
729 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +0000730 %gep1 = getelementptr float, float* %phi1, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000731 %load1 = load float* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +0000732 %gep2 = getelementptr float, float* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000733 store float %load1, float* %gep2
734 %load2 = load float* %phi1
735 store float %load2, float* %phi2
736 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +0000737 %gep3 = getelementptr float, float* %phi2, i64 -2
738 %gep4 = getelementptr float, float* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000739 %cond = icmp sgt i64 %dec.i, 0
740 br i1 %cond, label %for.body, label %end
741end:
742 ret void
743}
744
745define void @post-indexed-sub-double(double* %a, double* %b, i64 %count) nounwind {
746; CHECK-LABEL: post-indexed-sub-double
747; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #-16
748; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #-16
749 br label %for.body
750for.body:
751 %phi1 = phi double* [ %gep4, %for.body ], [ %b, %0 ]
752 %phi2 = phi double* [ %gep3, %for.body ], [ %a, %0 ]
753 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +0000754 %gep1 = getelementptr double, double* %phi1, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000755 %load1 = load double* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +0000756 %gep2 = getelementptr double, double* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000757 store double %load1, double* %gep2
758 %load2 = load double* %phi1
759 store double %load2, double* %phi2
760 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +0000761 %gep3 = getelementptr double, double* %phi2, i64 -2
762 %gep4 = getelementptr double, double* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +0000763 %cond = icmp sgt i64 %dec.i, 0
764 br i1 %cond, label %for.body, label %end
765end:
766 ret void
767}