blob: 91b791da36f3068b7387406045a7902ade597fcb [file] [log] [blame]
Eli Friedman8585e9d2016-08-12 20:28:02 +00001; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 -disable-lsr -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* }
Chad Rosierdabe2532015-09-29 18:26:15 +00006%s.byte = type { i8, i8 }
7%s.halfword = type { i16, i16 }
Tilmann Scheller112ada82014-05-26 12:15:51 +00008%s.word = type { i32, i32 }
9%s.doubleword = type { i64, i32 }
10%s.quadword = type { fp128, i32 }
11%s.float = type { float, i32 }
12%s.double = type { double, i32 }
Chad Rosierdabe2532015-09-29 18:26:15 +000013%struct.byte = type { %padding, %s.byte }
14%struct.halfword = type { %padding, %s.halfword }
Tilmann Scheller112ada82014-05-26 12:15:51 +000015%struct.word = type { %padding, %s.word }
16%struct.doubleword = type { %padding, %s.doubleword }
17%struct.quadword = type { %padding, %s.quadword }
18%struct.float = type { %padding, %s.float }
19%struct.double = type { %padding, %s.double }
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000020
21; Check the following transform:
22;
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000023; (ldr|str) X, [x0, #32]
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000024; ...
25; add x0, x0, #32
26; ->
Tilmann Schellercc3ebc82014-05-26 13:36:47 +000027; (ldr|str) X, [x0, #32]!
Tilmann Scheller112ada82014-05-26 12:15:51 +000028;
29; with X being either w1, x1, s0, d0 or q0.
Tilmann Scheller968d5992014-05-26 09:40:40 +000030
Chad Rosierdabe2532015-09-29 18:26:15 +000031declare void @bar_byte(%s.byte*, i8)
32
33define void @load-pre-indexed-byte(%struct.byte* %ptr) nounwind {
34; CHECK-LABEL: load-pre-indexed-byte
35; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
36entry:
37 %a = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1, i32 0
38 %add = load i8, i8* %a, align 4
39 br label %bar
40bar:
41 %c = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1
42 tail call void @bar_byte(%s.byte* %c, i8 %add)
43 ret void
44}
45
46define void @store-pre-indexed-byte(%struct.byte* %ptr, i8 %val) nounwind {
47; CHECK-LABEL: store-pre-indexed-byte
48; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
49entry:
50 %a = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1, i32 0
51 store i8 %val, i8* %a, align 4
52 br label %bar
53bar:
54 %c = getelementptr inbounds %struct.byte, %struct.byte* %ptr, i64 0, i32 1
55 tail call void @bar_byte(%s.byte* %c, i8 %val)
56 ret void
57}
58
59declare void @bar_halfword(%s.halfword*, i16)
60
61define void @load-pre-indexed-halfword(%struct.halfword* %ptr) nounwind {
62; CHECK-LABEL: load-pre-indexed-halfword
63; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
64entry:
65 %a = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1, i32 0
66 %add = load i16, i16* %a, align 4
67 br label %bar
68bar:
69 %c = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1
70 tail call void @bar_halfword(%s.halfword* %c, i16 %add)
71 ret void
72}
73
74define void @store-pre-indexed-halfword(%struct.halfword* %ptr, i16 %val) nounwind {
75; CHECK-LABEL: store-pre-indexed-halfword
76; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
77entry:
78 %a = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1, i32 0
79 store i16 %val, i16* %a, align 4
80 br label %bar
81bar:
82 %c = getelementptr inbounds %struct.halfword, %struct.halfword* %ptr, i64 0, i32 1
83 tail call void @bar_halfword(%s.halfword* %c, i16 %val)
84 ret void
85}
86
Tilmann Scheller112ada82014-05-26 12:15:51 +000087declare void @bar_word(%s.word*, i32)
88
89define void @load-pre-indexed-word(%struct.word* %ptr) nounwind {
90; CHECK-LABEL: load-pre-indexed-word
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000091; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
92entry:
David Blaikie79e6c742015-02-27 19:29:02 +000093 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +000094 %add = load i32, i32* %a, align 4
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000095 br label %bar
96bar:
David Blaikie79e6c742015-02-27 19:29:02 +000097 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +000098 tail call void @bar_word(%s.word* %c, i32 %add)
Tilmann Scheller2d746bc2014-05-26 09:37:19 +000099 ret void
100}
101
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000102define void @store-pre-indexed-word(%struct.word* %ptr, i32 %val) nounwind {
103; CHECK-LABEL: store-pre-indexed-word
104; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #32]!
105entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000106 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000107 store i32 %val, i32* %a, align 4
108 br label %bar
109bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000110 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000111 tail call void @bar_word(%s.word* %c, i32 %val)
112 ret void
113}
114
Tilmann Scheller112ada82014-05-26 12:15:51 +0000115declare void @bar_doubleword(%s.doubleword*, i64)
116
117define void @load-pre-indexed-doubleword(%struct.doubleword* %ptr) nounwind {
118; CHECK-LABEL: load-pre-indexed-doubleword
119; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #32]!
120entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000121 %a = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000122 %add = load i64, i64* %a, align 4
Tilmann Scheller112ada82014-05-26 12:15:51 +0000123 br label %bar
124bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000125 %c = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000126 tail call void @bar_doubleword(%s.doubleword* %c, i64 %add)
127 ret void
128}
129
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000130define void @store-pre-indexed-doubleword(%struct.doubleword* %ptr, i64 %val) nounwind {
131; CHECK-LABEL: store-pre-indexed-doubleword
132; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #32]!
133entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000134 %a = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000135 store i64 %val, i64* %a, align 4
136 br label %bar
137bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000138 %c = getelementptr inbounds %struct.doubleword, %struct.doubleword* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000139 tail call void @bar_doubleword(%s.doubleword* %c, i64 %val)
140 ret void
141}
142
Tilmann Scheller112ada82014-05-26 12:15:51 +0000143declare void @bar_quadword(%s.quadword*, fp128)
144
145define void @load-pre-indexed-quadword(%struct.quadword* %ptr) nounwind {
146; CHECK-LABEL: load-pre-indexed-quadword
147; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
148entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000149 %a = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000150 %add = load fp128, fp128* %a, align 4
Tilmann Scheller112ada82014-05-26 12:15:51 +0000151 br label %bar
152bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000153 %c = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000154 tail call void @bar_quadword(%s.quadword* %c, fp128 %add)
155 ret void
156}
157
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000158define void @store-pre-indexed-quadword(%struct.quadword* %ptr, fp128 %val) nounwind {
159; CHECK-LABEL: store-pre-indexed-quadword
160; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
161entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000162 %a = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000163 store fp128 %val, fp128* %a, align 4
164 br label %bar
165bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000166 %c = getelementptr inbounds %struct.quadword, %struct.quadword* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000167 tail call void @bar_quadword(%s.quadword* %c, fp128 %val)
168 ret void
169}
170
Tilmann Scheller112ada82014-05-26 12:15:51 +0000171declare void @bar_float(%s.float*, float)
172
173define void @load-pre-indexed-float(%struct.float* %ptr) nounwind {
174; CHECK-LABEL: load-pre-indexed-float
175; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #32]!
176entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000177 %a = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000178 %add = load float, float* %a, align 4
Tilmann Scheller112ada82014-05-26 12:15:51 +0000179 br label %bar
180bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000181 %c = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000182 tail call void @bar_float(%s.float* %c, float %add)
183 ret void
184}
185
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000186define void @store-pre-indexed-float(%struct.float* %ptr, float %val) nounwind {
187; CHECK-LABEL: store-pre-indexed-float
188; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #32]!
189entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000190 %a = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000191 store float %val, float* %a, align 4
192 br label %bar
193bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000194 %c = getelementptr inbounds %struct.float, %struct.float* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000195 tail call void @bar_float(%s.float* %c, float %val)
196 ret void
197}
198
Tilmann Scheller112ada82014-05-26 12:15:51 +0000199declare void @bar_double(%s.double*, double)
200
201define void @load-pre-indexed-double(%struct.double* %ptr) nounwind {
202; CHECK-LABEL: load-pre-indexed-double
203; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #32]!
204entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000205 %a = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000206 %add = load double, double* %a, align 4
Tilmann Scheller112ada82014-05-26 12:15:51 +0000207 br label %bar
208bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000209 %c = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1
Tilmann Scheller112ada82014-05-26 12:15:51 +0000210 tail call void @bar_double(%s.double* %c, double %add)
211 ret void
212}
Tilmann Scheller2d746bc2014-05-26 09:37:19 +0000213
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000214define void @store-pre-indexed-double(%struct.double* %ptr, double %val) nounwind {
215; CHECK-LABEL: store-pre-indexed-double
216; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #32]!
217entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000218 %a = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1, i32 0
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000219 store double %val, double* %a, align 4
220 br label %bar
221bar:
David Blaikie79e6c742015-02-27 19:29:02 +0000222 %c = getelementptr inbounds %struct.double, %struct.double* %ptr, i64 0, i32 1
Tilmann Schellercc3ebc82014-05-26 13:36:47 +0000223 tail call void @bar_double(%s.double* %c, double %val)
224 ret void
225}
Tilmann Scheller35e45142014-05-28 05:44:14 +0000226
227; Check the following transform:
228;
Chad Rosier1bbd7fb2015-09-25 17:48:17 +0000229; (ldp|stp) w1, w2 [x0, #32]
230; ...
231; add x0, x0, #32
232; ->
233; (ldp|stp) w1, w2, [x0, #32]!
234;
235
236define void @load-pair-pre-indexed-word(%struct.word* %ptr) nounwind {
237; CHECK-LABEL: load-pair-pre-indexed-word
238; CHECK: ldp w{{[0-9]+}}, w{{[0-9]+}}, [x0, #32]!
239; CHECK-NOT: add x0, x0, #32
240entry:
241 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
242 %a1 = load i32, i32* %a, align 4
243 %b = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 1
244 %b1 = load i32, i32* %b, align 4
245 %add = add i32 %a1, %b1
246 br label %bar
247bar:
248 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
249 tail call void @bar_word(%s.word* %c, i32 %add)
250 ret void
251}
252
253define void @store-pair-pre-indexed-word(%struct.word* %ptr, i32 %val) nounwind {
254; CHECK-LABEL: store-pair-pre-indexed-word
255; CHECK: stp w{{[0-9]+}}, w{{[0-9]+}}, [x0, #32]!
256; CHECK-NOT: add x0, x0, #32
257entry:
258 %a = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 0
259 store i32 %val, i32* %a, align 4
260 %b = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1, i32 1
261 store i32 %val, i32* %b, align 4
262 br label %bar
263bar:
264 %c = getelementptr inbounds %struct.word, %struct.word* %ptr, i64 0, i32 1
265 tail call void @bar_word(%s.word* %c, i32 %val)
266 ret void
267}
268
269; Check the following transform:
270;
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000271; add x8, x8, #16
272; ...
273; ldr X, [x8]
274; ->
275; ldr X, [x8, #16]!
276;
277; with X being either w0, x0, s0, d0 or q0.
278
Chad Rosier11c825f2015-09-30 19:44:40 +0000279%pre.struct.i32 = type { i32, i32, i32, i32, i32}
280%pre.struct.i64 = type { i32, i64, i64, i64, i64}
281%pre.struct.i128 = type { i32, <2 x i64>, <2 x i64>, <2 x i64>}
282%pre.struct.float = type { i32, float, float, float}
283%pre.struct.double = type { i32, double, double, double}
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000284
285define i32 @load-pre-indexed-word2(%pre.struct.i32** %this, i1 %cond,
286 %pre.struct.i32* %load2) nounwind {
287; CHECK-LABEL: load-pre-indexed-word2
288; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #4]!
289 br i1 %cond, label %if.then, label %if.end
290if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000291 %load1 = load %pre.struct.i32*, %pre.struct.i32** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000292 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000293 br label %return
294if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000295 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000296 br label %return
297return:
298 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
David Blaikiea79ac142015-02-27 21:17:42 +0000299 %ret = load i32, i32* %retptr
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000300 ret i32 %ret
301}
302
303define i64 @load-pre-indexed-doubleword2(%pre.struct.i64** %this, i1 %cond,
304 %pre.struct.i64* %load2) nounwind {
305; CHECK-LABEL: load-pre-indexed-doubleword2
306; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #8]!
307 br i1 %cond, label %if.then, label %if.end
308if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000309 %load1 = load %pre.struct.i64*, %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 Schellercfbacc82014-06-02 11:57:09 +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 Schellercfbacc82014-06-02 11:57:09 +0000314 br label %return
315return:
316 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
David Blaikiea79ac142015-02-27 21:17:42 +0000317 %ret = load i64, i64* %retptr
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000318 ret i64 %ret
319}
320
321define <2 x i64> @load-pre-indexed-quadword2(%pre.struct.i128** %this, i1 %cond,
322 %pre.struct.i128* %load2) nounwind {
323; CHECK-LABEL: load-pre-indexed-quadword2
324; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #16]!
325 br i1 %cond, label %if.then, label %if.end
326if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000327 %load1 = load %pre.struct.i128*, %pre.struct.i128** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000328 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000329 br label %return
330if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000331 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000332 br label %return
333return:
334 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
David Blaikiea79ac142015-02-27 21:17:42 +0000335 %ret = load <2 x i64>, <2 x i64>* %retptr
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000336 ret <2 x i64> %ret
337}
338
339define float @load-pre-indexed-float2(%pre.struct.float** %this, i1 %cond,
340 %pre.struct.float* %load2) nounwind {
341; CHECK-LABEL: load-pre-indexed-float2
342; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #4]!
343 br i1 %cond, label %if.then, label %if.end
344if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000345 %load1 = load %pre.struct.float*, %pre.struct.float** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000346 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000347 br label %return
348if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000349 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000350 br label %return
351return:
352 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
David Blaikiea79ac142015-02-27 21:17:42 +0000353 %ret = load float, float* %retptr
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000354 ret float %ret
355}
356
357define double @load-pre-indexed-double2(%pre.struct.double** %this, i1 %cond,
358 %pre.struct.double* %load2) nounwind {
359; CHECK-LABEL: load-pre-indexed-double2
360; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #8]!
361 br i1 %cond, label %if.then, label %if.end
362if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000363 %load1 = load %pre.struct.double*, %pre.struct.double** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000364 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 1
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000365 br label %return
366if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000367 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 2
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000368 br label %return
369return:
370 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
David Blaikiea79ac142015-02-27 21:17:42 +0000371 %ret = load double, double* %retptr
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000372 ret double %ret
373}
374
Chad Rosier11c825f2015-09-30 19:44:40 +0000375define i32 @load-pre-indexed-word3(%pre.struct.i32** %this, i1 %cond,
376 %pre.struct.i32* %load2) nounwind {
377; CHECK-LABEL: load-pre-indexed-word3
378; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}, #12]!
379 br i1 %cond, label %if.then, label %if.end
380if.then:
381 %load1 = load %pre.struct.i32*, %pre.struct.i32** %this
382 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 3
383 br label %return
384if.end:
385 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 4
386 br label %return
387return:
388 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
389 %ret = load i32, i32* %retptr
390 ret i32 %ret
391}
392
393define i64 @load-pre-indexed-doubleword3(%pre.struct.i64** %this, i1 %cond,
394 %pre.struct.i64* %load2) nounwind {
395; CHECK-LABEL: load-pre-indexed-doubleword3
396; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}, #16]!
397 br i1 %cond, label %if.then, label %if.end
398if.then:
399 %load1 = load %pre.struct.i64*, %pre.struct.i64** %this
400 %gep1 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load1, i64 0, i32 2
401 br label %return
402if.end:
403 %gep2 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load2, i64 0, i32 3
404 br label %return
405return:
406 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
407 %ret = load i64, i64* %retptr
408 ret i64 %ret
409}
410
411define <2 x i64> @load-pre-indexed-quadword3(%pre.struct.i128** %this, i1 %cond,
412 %pre.struct.i128* %load2) nounwind {
413; CHECK-LABEL: load-pre-indexed-quadword3
414; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
415 br i1 %cond, label %if.then, label %if.end
416if.then:
417 %load1 = load %pre.struct.i128*, %pre.struct.i128** %this
418 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 2
419 br label %return
420if.end:
421 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 3
422 br label %return
423return:
424 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
425 %ret = load <2 x i64>, <2 x i64>* %retptr
426 ret <2 x i64> %ret
427}
428
429define float @load-pre-indexed-float3(%pre.struct.float** %this, i1 %cond,
430 %pre.struct.float* %load2) nounwind {
431; CHECK-LABEL: load-pre-indexed-float3
432; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}, #8]!
433 br i1 %cond, label %if.then, label %if.end
434if.then:
435 %load1 = load %pre.struct.float*, %pre.struct.float** %this
436 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 2
437 br label %return
438if.end:
439 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 3
440 br label %return
441return:
442 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
443 %ret = load float, float* %retptr
444 ret float %ret
445}
446
447define double @load-pre-indexed-double3(%pre.struct.double** %this, i1 %cond,
448 %pre.struct.double* %load2) nounwind {
449; CHECK-LABEL: load-pre-indexed-double3
450; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}, #16]!
451 br i1 %cond, label %if.then, label %if.end
452if.then:
453 %load1 = load %pre.struct.double*, %pre.struct.double** %this
454 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 2
455 br label %return
456if.end:
457 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 3
458 br label %return
459return:
460 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
461 %ret = load double, double* %retptr
462 ret double %ret
463}
464
Tilmann Schellercfbacc82014-06-02 11:57:09 +0000465; Check the following transform:
466;
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000467; add x8, x8, #16
468; ...
469; str X, [x8]
470; ->
471; str X, [x8, #16]!
472;
473; with X being either w0, x0, s0, d0 or q0.
474
475define void @store-pre-indexed-word2(%pre.struct.i32** %this, i1 %cond,
476 %pre.struct.i32* %load2,
477 i32 %val) nounwind {
478; CHECK-LABEL: store-pre-indexed-word2
479; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #4]!
480 br i1 %cond, label %if.then, label %if.end
481if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000482 %load1 = load %pre.struct.i32*, %pre.struct.i32** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000483 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000484 br label %return
485if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000486 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000487 br label %return
488return:
489 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
490 store i32 %val, i32* %retptr
491 ret void
492}
493
494define void @store-pre-indexed-doubleword2(%pre.struct.i64** %this, i1 %cond,
495 %pre.struct.i64* %load2,
496 i64 %val) nounwind {
497; CHECK-LABEL: store-pre-indexed-doubleword2
498; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #8]!
499 br i1 %cond, label %if.then, label %if.end
500if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000501 %load1 = load %pre.struct.i64*, %pre.struct.i64** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000502 %gep1 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000503 br label %return
504if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000505 %gep2 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000506 br label %return
507return:
508 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
509 store i64 %val, i64* %retptr
510 ret void
511}
512
513define void @store-pre-indexed-quadword2(%pre.struct.i128** %this, i1 %cond,
514 %pre.struct.i128* %load2,
515 <2 x i64> %val) nounwind {
516; CHECK-LABEL: store-pre-indexed-quadword2
517; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #16]!
518 br i1 %cond, label %if.then, label %if.end
519if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000520 %load1 = load %pre.struct.i128*, %pre.struct.i128** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000521 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000522 br label %return
523if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000524 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000525 br label %return
526return:
527 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
528 store <2 x i64> %val, <2 x i64>* %retptr
529 ret void
530}
531
532define void @store-pre-indexed-float2(%pre.struct.float** %this, i1 %cond,
533 %pre.struct.float* %load2,
534 float %val) nounwind {
535; CHECK-LABEL: store-pre-indexed-float2
536; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #4]!
537 br i1 %cond, label %if.then, label %if.end
538if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000539 %load1 = load %pre.struct.float*, %pre.struct.float** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000540 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000541 br label %return
542if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000543 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000544 br label %return
545return:
546 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
547 store float %val, float* %retptr
548 ret void
549}
550
551define void @store-pre-indexed-double2(%pre.struct.double** %this, i1 %cond,
552 %pre.struct.double* %load2,
553 double %val) nounwind {
554; CHECK-LABEL: store-pre-indexed-double2
555; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #8]!
556 br i1 %cond, label %if.then, label %if.end
557if.then:
David Blaikiea79ac142015-02-27 21:17:42 +0000558 %load1 = load %pre.struct.double*, %pre.struct.double** %this
David Blaikie79e6c742015-02-27 19:29:02 +0000559 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 1
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000560 br label %return
561if.end:
David Blaikie79e6c742015-02-27 19:29:02 +0000562 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 2
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000563 br label %return
564return:
565 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
566 store double %val, double* %retptr
567 ret void
568}
569
Chad Rosier11c825f2015-09-30 19:44:40 +0000570define void @store-pre-indexed-word3(%pre.struct.i32** %this, i1 %cond,
571 %pre.struct.i32* %load2,
572 i32 %val) nounwind {
573; CHECK-LABEL: store-pre-indexed-word3
574; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}, #12]!
575 br i1 %cond, label %if.then, label %if.end
576if.then:
577 %load1 = load %pre.struct.i32*, %pre.struct.i32** %this
578 %gep1 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load1, i64 0, i32 3
579 br label %return
580if.end:
581 %gep2 = getelementptr inbounds %pre.struct.i32, %pre.struct.i32* %load2, i64 0, i32 4
582 br label %return
583return:
584 %retptr = phi i32* [ %gep1, %if.then ], [ %gep2, %if.end ]
585 store i32 %val, i32* %retptr
586 ret void
587}
588
589define void @store-pre-indexed-doubleword3(%pre.struct.i64** %this, i1 %cond,
590 %pre.struct.i64* %load2,
591 i64 %val) nounwind {
592; CHECK-LABEL: store-pre-indexed-doubleword3
593; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}, #24]!
594 br i1 %cond, label %if.then, label %if.end
595if.then:
596 %load1 = load %pre.struct.i64*, %pre.struct.i64** %this
597 %gep1 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load1, i64 0, i32 3
598 br label %return
599if.end:
600 %gep2 = getelementptr inbounds %pre.struct.i64, %pre.struct.i64* %load2, i64 0, i32 4
601 br label %return
602return:
603 %retptr = phi i64* [ %gep1, %if.then ], [ %gep2, %if.end ]
604 store i64 %val, i64* %retptr
605 ret void
606}
607
608define void @store-pre-indexed-quadword3(%pre.struct.i128** %this, i1 %cond,
609 %pre.struct.i128* %load2,
610 <2 x i64> %val) nounwind {
611; CHECK-LABEL: store-pre-indexed-quadword3
612; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}, #32]!
613 br i1 %cond, label %if.then, label %if.end
614if.then:
615 %load1 = load %pre.struct.i128*, %pre.struct.i128** %this
616 %gep1 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load1, i64 0, i32 2
617 br label %return
618if.end:
619 %gep2 = getelementptr inbounds %pre.struct.i128, %pre.struct.i128* %load2, i64 0, i32 3
620 br label %return
621return:
622 %retptr = phi <2 x i64>* [ %gep1, %if.then ], [ %gep2, %if.end ]
623 store <2 x i64> %val, <2 x i64>* %retptr
624 ret void
625}
626
627define void @store-pre-indexed-float3(%pre.struct.float** %this, i1 %cond,
628 %pre.struct.float* %load2,
629 float %val) nounwind {
630; CHECK-LABEL: store-pre-indexed-float3
631; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}, #8]!
632 br i1 %cond, label %if.then, label %if.end
633if.then:
634 %load1 = load %pre.struct.float*, %pre.struct.float** %this
635 %gep1 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load1, i64 0, i32 2
636 br label %return
637if.end:
638 %gep2 = getelementptr inbounds %pre.struct.float, %pre.struct.float* %load2, i64 0, i32 3
639 br label %return
640return:
641 %retptr = phi float* [ %gep1, %if.then ], [ %gep2, %if.end ]
642 store float %val, float* %retptr
643 ret void
644}
645
646define void @store-pre-indexed-double3(%pre.struct.double** %this, i1 %cond,
647 %pre.struct.double* %load2,
648 double %val) nounwind {
649; CHECK-LABEL: store-pre-indexed-double3
650; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}, #16]!
651 br i1 %cond, label %if.then, label %if.end
652if.then:
653 %load1 = load %pre.struct.double*, %pre.struct.double** %this
654 %gep1 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load1, i64 0, i32 2
655 br label %return
656if.end:
657 %gep2 = getelementptr inbounds %pre.struct.double, %pre.struct.double* %load2, i64 0, i32 3
658 br label %return
659return:
660 %retptr = phi double* [ %gep1, %if.then ], [ %gep2, %if.end ]
661 store double %val, double* %retptr
662 ret void
663}
664
Tilmann Scheller75fa6e52014-06-02 12:33:33 +0000665; Check the following transform:
666;
Tilmann Scheller35e45142014-05-28 05:44:14 +0000667; ldr X, [x20]
668; ...
669; add x20, x20, #32
670; ->
671; ldr X, [x20], #32
672;
673; with X being either w0, x0, s0, d0 or q0.
674
Chad Rosierdabe2532015-09-29 18:26:15 +0000675define void @load-post-indexed-byte(i8* %array, i64 %count) nounwind {
676; CHECK-LABEL: load-post-indexed-byte
677; CHECK: ldrb w{{[0-9]+}}, [x{{[0-9]+}}], #4
678entry:
679 %gep1 = getelementptr i8, i8* %array, i64 2
680 br label %body
681
682body:
683 %iv2 = phi i8* [ %gep3, %body ], [ %gep1, %entry ]
684 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
685 %gep2 = getelementptr i8, i8* %iv2, i64 -1
686 %load = load i8, i8* %gep2
687 call void @use-byte(i8 %load)
688 %load2 = load i8, i8* %iv2
689 call void @use-byte(i8 %load2)
690 %iv.next = add i64 %iv, -4
691 %gep3 = getelementptr i8, i8* %iv2, i64 4
692 %cond = icmp eq i64 %iv.next, 0
693 br i1 %cond, label %exit, label %body
694
695exit:
696 ret void
697}
698
699define void @load-post-indexed-halfword(i16* %array, i64 %count) nounwind {
700; CHECK-LABEL: load-post-indexed-halfword
701; CHECK: ldrh w{{[0-9]+}}, [x{{[0-9]+}}], #8
702entry:
703 %gep1 = getelementptr i16, i16* %array, i64 2
704 br label %body
705
706body:
707 %iv2 = phi i16* [ %gep3, %body ], [ %gep1, %entry ]
708 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
709 %gep2 = getelementptr i16, i16* %iv2, i64 -1
710 %load = load i16, i16* %gep2
711 call void @use-halfword(i16 %load)
712 %load2 = load i16, i16* %iv2
713 call void @use-halfword(i16 %load2)
714 %iv.next = add i64 %iv, -4
715 %gep3 = getelementptr i16, i16* %iv2, i64 4
716 %cond = icmp eq i64 %iv.next, 0
717 br i1 %cond, label %exit, label %body
718
719exit:
720 ret void
721}
722
Tilmann Scheller35e45142014-05-28 05:44:14 +0000723define void @load-post-indexed-word(i32* %array, i64 %count) nounwind {
724; CHECK-LABEL: load-post-indexed-word
725; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #16
726entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000727 %gep1 = getelementptr i32, i32* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000728 br label %body
729
730body:
731 %iv2 = phi i32* [ %gep3, %body ], [ %gep1, %entry ]
732 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000733 %gep2 = getelementptr i32, i32* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000734 %load = load i32, i32* %gep2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000735 call void @use-word(i32 %load)
David Blaikiea79ac142015-02-27 21:17:42 +0000736 %load2 = load i32, i32* %iv2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000737 call void @use-word(i32 %load2)
738 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000739 %gep3 = getelementptr i32, i32* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000740 %cond = icmp eq i64 %iv.next, 0
741 br i1 %cond, label %exit, label %body
742
743exit:
744 ret void
745}
746
747define void @load-post-indexed-doubleword(i64* %array, i64 %count) nounwind {
748; CHECK-LABEL: load-post-indexed-doubleword
749; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #32
750entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000751 %gep1 = getelementptr i64, i64* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000752 br label %body
753
754body:
755 %iv2 = phi i64* [ %gep3, %body ], [ %gep1, %entry ]
756 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000757 %gep2 = getelementptr i64, i64* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000758 %load = load i64, i64* %gep2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000759 call void @use-doubleword(i64 %load)
David Blaikiea79ac142015-02-27 21:17:42 +0000760 %load2 = load i64, i64* %iv2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000761 call void @use-doubleword(i64 %load2)
762 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000763 %gep3 = getelementptr i64, i64* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000764 %cond = icmp eq i64 %iv.next, 0
765 br i1 %cond, label %exit, label %body
766
767exit:
768 ret void
769}
770
771define void @load-post-indexed-quadword(<2 x i64>* %array, i64 %count) nounwind {
772; CHECK-LABEL: load-post-indexed-quadword
773; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #64
774entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000775 %gep1 = getelementptr <2 x i64>, <2 x i64>* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000776 br label %body
777
778body:
779 %iv2 = phi <2 x i64>* [ %gep3, %body ], [ %gep1, %entry ]
780 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000781 %gep2 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000782 %load = load <2 x i64>, <2 x i64>* %gep2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000783 call void @use-quadword(<2 x i64> %load)
David Blaikiea79ac142015-02-27 21:17:42 +0000784 %load2 = load <2 x i64>, <2 x i64>* %iv2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000785 call void @use-quadword(<2 x i64> %load2)
786 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000787 %gep3 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000788 %cond = icmp eq i64 %iv.next, 0
789 br i1 %cond, label %exit, label %body
790
791exit:
792 ret void
793}
794
795define void @load-post-indexed-float(float* %array, i64 %count) nounwind {
796; CHECK-LABEL: load-post-indexed-float
797; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #16
798entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000799 %gep1 = getelementptr float, float* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000800 br label %body
801
802body:
803 %iv2 = phi float* [ %gep3, %body ], [ %gep1, %entry ]
804 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000805 %gep2 = getelementptr float, float* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000806 %load = load float, float* %gep2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000807 call void @use-float(float %load)
David Blaikiea79ac142015-02-27 21:17:42 +0000808 %load2 = load float, float* %iv2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000809 call void @use-float(float %load2)
810 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000811 %gep3 = getelementptr float, float* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000812 %cond = icmp eq i64 %iv.next, 0
813 br i1 %cond, label %exit, label %body
814
815exit:
816 ret void
817}
818
819define void @load-post-indexed-double(double* %array, i64 %count) nounwind {
820; CHECK-LABEL: load-post-indexed-double
821; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #32
822entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000823 %gep1 = getelementptr double, double* %array, i64 2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000824 br label %body
825
826body:
827 %iv2 = phi double* [ %gep3, %body ], [ %gep1, %entry ]
828 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000829 %gep2 = getelementptr double, double* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000830 %load = load double, double* %gep2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000831 call void @use-double(double %load)
David Blaikiea79ac142015-02-27 21:17:42 +0000832 %load2 = load double, double* %iv2
Tilmann Scheller35e45142014-05-28 05:44:14 +0000833 call void @use-double(double %load2)
834 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000835 %gep3 = getelementptr double, double* %iv2, i64 4
Tilmann Scheller35e45142014-05-28 05:44:14 +0000836 %cond = icmp eq i64 %iv.next, 0
837 br i1 %cond, label %exit, label %body
838
839exit:
840 ret void
841}
842
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000843; Check the following transform:
844;
845; str X, [x20]
846; ...
847; add x20, x20, #32
848; ->
849; str X, [x20], #32
850;
851; with X being either w0, x0, s0, d0 or q0.
852
Chad Rosierdabe2532015-09-29 18:26:15 +0000853define void @store-post-indexed-byte(i8* %array, i64 %count, i8 %val) nounwind {
854; CHECK-LABEL: store-post-indexed-byte
855; CHECK: strb w{{[0-9]+}}, [x{{[0-9]+}}], #4
856entry:
857 %gep1 = getelementptr i8, i8* %array, i64 2
858 br label %body
859
860body:
861 %iv2 = phi i8* [ %gep3, %body ], [ %gep1, %entry ]
862 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
863 %gep2 = getelementptr i8, i8* %iv2, i64 -1
864 %load = load i8, i8* %gep2
865 call void @use-byte(i8 %load)
866 store i8 %val, i8* %iv2
867 %iv.next = add i64 %iv, -4
868 %gep3 = getelementptr i8, i8* %iv2, i64 4
869 %cond = icmp eq i64 %iv.next, 0
870 br i1 %cond, label %exit, label %body
871
872exit:
873 ret void
874}
875
876define void @store-post-indexed-halfword(i16* %array, i64 %count, i16 %val) nounwind {
877; CHECK-LABEL: store-post-indexed-halfword
878; CHECK: strh w{{[0-9]+}}, [x{{[0-9]+}}], #8
879entry:
880 %gep1 = getelementptr i16, i16* %array, i64 2
881 br label %body
882
883body:
884 %iv2 = phi i16* [ %gep3, %body ], [ %gep1, %entry ]
885 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
886 %gep2 = getelementptr i16, i16* %iv2, i64 -1
887 %load = load i16, i16* %gep2
888 call void @use-halfword(i16 %load)
889 store i16 %val, i16* %iv2
890 %iv.next = add i64 %iv, -4
891 %gep3 = getelementptr i16, i16* %iv2, i64 4
892 %cond = icmp eq i64 %iv.next, 0
893 br i1 %cond, label %exit, label %body
894
895exit:
896 ret void
897}
898
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000899define void @store-post-indexed-word(i32* %array, i64 %count, i32 %val) nounwind {
900; CHECK-LABEL: store-post-indexed-word
901; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #16
902entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000903 %gep1 = getelementptr i32, i32* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000904 br label %body
905
906body:
907 %iv2 = phi i32* [ %gep3, %body ], [ %gep1, %entry ]
908 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000909 %gep2 = getelementptr i32, i32* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000910 %load = load i32, i32* %gep2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000911 call void @use-word(i32 %load)
912 store i32 %val, i32* %iv2
913 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000914 %gep3 = getelementptr i32, i32* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000915 %cond = icmp eq i64 %iv.next, 0
916 br i1 %cond, label %exit, label %body
917
918exit:
919 ret void
920}
921
922define void @store-post-indexed-doubleword(i64* %array, i64 %count, i64 %val) nounwind {
923; CHECK-LABEL: store-post-indexed-doubleword
924; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #32
925entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000926 %gep1 = getelementptr i64, i64* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000927 br label %body
928
929body:
930 %iv2 = phi i64* [ %gep3, %body ], [ %gep1, %entry ]
931 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000932 %gep2 = getelementptr i64, i64* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000933 %load = load i64, i64* %gep2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000934 call void @use-doubleword(i64 %load)
935 store i64 %val, i64* %iv2
936 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000937 %gep3 = getelementptr i64, i64* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000938 %cond = icmp eq i64 %iv.next, 0
939 br i1 %cond, label %exit, label %body
940
941exit:
942 ret void
943}
944
945define void @store-post-indexed-quadword(<2 x i64>* %array, i64 %count, <2 x i64> %val) nounwind {
946; CHECK-LABEL: store-post-indexed-quadword
947; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #64
948entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000949 %gep1 = getelementptr <2 x i64>, <2 x i64>* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000950 br label %body
951
952body:
953 %iv2 = phi <2 x i64>* [ %gep3, %body ], [ %gep1, %entry ]
954 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000955 %gep2 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000956 %load = load <2 x i64>, <2 x i64>* %gep2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000957 call void @use-quadword(<2 x i64> %load)
958 store <2 x i64> %val, <2 x i64>* %iv2
959 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000960 %gep3 = getelementptr <2 x i64>, <2 x i64>* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000961 %cond = icmp eq i64 %iv.next, 0
962 br i1 %cond, label %exit, label %body
963
964exit:
965 ret void
966}
967
968define void @store-post-indexed-float(float* %array, i64 %count, float %val) nounwind {
969; CHECK-LABEL: store-post-indexed-float
970; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #16
971entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000972 %gep1 = getelementptr float, float* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000973 br label %body
974
975body:
976 %iv2 = phi float* [ %gep3, %body ], [ %gep1, %entry ]
977 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +0000978 %gep2 = getelementptr float, float* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +0000979 %load = load float, float* %gep2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000980 call void @use-float(float %load)
981 store float %val, float* %iv2
982 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +0000983 %gep3 = getelementptr float, float* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000984 %cond = icmp eq i64 %iv.next, 0
985 br i1 %cond, label %exit, label %body
986
987exit:
988 ret void
989}
990
991define void @store-post-indexed-double(double* %array, i64 %count, double %val) nounwind {
992; CHECK-LABEL: store-post-indexed-double
993; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #32
994entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000995 %gep1 = getelementptr double, double* %array, i64 2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +0000996 br label %body
997
998body:
999 %iv2 = phi double* [ %gep3, %body ], [ %gep1, %entry ]
1000 %iv = phi i64 [ %iv.next, %body ], [ %count, %entry ]
David Blaikie79e6c742015-02-27 19:29:02 +00001001 %gep2 = getelementptr double, double* %iv2, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001002 %load = load double, double* %gep2
Tilmann Scheller7c747fc2014-05-28 06:43:00 +00001003 call void @use-double(double %load)
1004 store double %val, double* %iv2
1005 %iv.next = add i64 %iv, -4
David Blaikie79e6c742015-02-27 19:29:02 +00001006 %gep3 = getelementptr double, double* %iv2, i64 4
Tilmann Scheller7c747fc2014-05-28 06:43:00 +00001007 %cond = icmp eq i64 %iv.next, 0
1008 br i1 %cond, label %exit, label %body
1009
1010exit:
1011 ret void
1012}
1013
Chad Rosierdabe2532015-09-29 18:26:15 +00001014declare void @use-byte(i8)
1015declare void @use-halfword(i16)
Tilmann Scheller35e45142014-05-28 05:44:14 +00001016declare void @use-word(i32)
1017declare void @use-doubleword(i64)
1018declare void @use-quadword(<2 x i64>)
1019declare void @use-float(float)
1020declare void @use-double(double)
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001021
1022; Check the following transform:
1023;
Chad Rosier1bbd7fb2015-09-25 17:48:17 +00001024; stp w0, [x20]
1025; ...
1026; add x20, x20, #32
1027; ->
1028; stp w0, [x20], #32
1029
1030define void @store-pair-post-indexed-word() nounwind {
1031; CHECK-LABEL: store-pair-post-indexed-word
1032; CHECK: stp w{{[0-9]+}}, w{{[0-9]+}}, [sp], #16
1033; CHECK: ret
1034 %src = alloca { i32, i32 }, align 8
1035 %dst = alloca { i32, i32 }, align 8
1036
1037 %src.realp = getelementptr inbounds { i32, i32 }, { i32, i32 }* %src, i32 0, i32 0
1038 %src.real = load i32, i32* %src.realp
1039 %src.imagp = getelementptr inbounds { i32, i32 }, { i32, i32 }* %src, i32 0, i32 1
1040 %src.imag = load i32, i32* %src.imagp
1041
1042 %dst.realp = getelementptr inbounds { i32, i32 }, { i32, i32 }* %dst, i32 0, i32 0
1043 %dst.imagp = getelementptr inbounds { i32, i32 }, { i32, i32 }* %dst, i32 0, i32 1
1044 store i32 %src.real, i32* %dst.realp
1045 store i32 %src.imag, i32* %dst.imagp
1046 ret void
1047}
1048
1049define void @store-pair-post-indexed-doubleword() nounwind {
1050; CHECK-LABEL: store-pair-post-indexed-doubleword
1051; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [sp], #32
1052; CHECK: ret
1053 %src = alloca { i64, i64 }, align 8
1054 %dst = alloca { i64, i64 }, align 8
1055
1056 %src.realp = getelementptr inbounds { i64, i64 }, { i64, i64 }* %src, i32 0, i32 0
1057 %src.real = load i64, i64* %src.realp
1058 %src.imagp = getelementptr inbounds { i64, i64 }, { i64, i64 }* %src, i32 0, i32 1
1059 %src.imag = load i64, i64* %src.imagp
1060
1061 %dst.realp = getelementptr inbounds { i64, i64 }, { i64, i64 }* %dst, i32 0, i32 0
1062 %dst.imagp = getelementptr inbounds { i64, i64 }, { i64, i64 }* %dst, i32 0, i32 1
1063 store i64 %src.real, i64* %dst.realp
1064 store i64 %src.imag, i64* %dst.imagp
1065 ret void
1066}
1067
1068define void @store-pair-post-indexed-float() nounwind {
1069; CHECK-LABEL: store-pair-post-indexed-float
1070; CHECK: stp s{{[0-9]+}}, s{{[0-9]+}}, [sp], #16
1071; CHECK: ret
1072 %src = alloca { float, float }, align 8
1073 %dst = alloca { float, float }, align 8
1074
1075 %src.realp = getelementptr inbounds { float, float }, { float, float }* %src, i32 0, i32 0
1076 %src.real = load float, float* %src.realp
1077 %src.imagp = getelementptr inbounds { float, float }, { float, float }* %src, i32 0, i32 1
1078 %src.imag = load float, float* %src.imagp
1079
1080 %dst.realp = getelementptr inbounds { float, float }, { float, float }* %dst, i32 0, i32 0
1081 %dst.imagp = getelementptr inbounds { float, float }, { float, float }* %dst, i32 0, i32 1
1082 store float %src.real, float* %dst.realp
1083 store float %src.imag, float* %dst.imagp
1084 ret void
1085}
1086
1087define void @store-pair-post-indexed-double() nounwind {
1088; CHECK-LABEL: store-pair-post-indexed-double
1089; CHECK: stp d{{[0-9]+}}, d{{[0-9]+}}, [sp], #32
1090; CHECK: ret
1091 %src = alloca { double, double }, align 8
1092 %dst = alloca { double, double }, align 8
1093
1094 %src.realp = getelementptr inbounds { double, double }, { double, double }* %src, i32 0, i32 0
1095 %src.real = load double, double* %src.realp
1096 %src.imagp = getelementptr inbounds { double, double }, { double, double }* %src, i32 0, i32 1
1097 %src.imag = load double, double* %src.imagp
1098
1099 %dst.realp = getelementptr inbounds { double, double }, { double, double }* %dst, i32 0, i32 0
1100 %dst.imagp = getelementptr inbounds { double, double }, { double, double }* %dst, i32 0, i32 1
1101 store double %src.real, double* %dst.realp
1102 store double %src.imag, double* %dst.imagp
1103 ret void
1104}
1105
1106; Check the following transform:
1107;
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001108; (ldr|str) X, [x20]
1109; ...
1110; sub x20, x20, #16
1111; ->
1112; (ldr|str) X, [x20], #-16
1113;
1114; with X being either w0, x0, s0, d0 or q0.
1115
1116define void @post-indexed-sub-word(i32* %a, i32* %b, i64 %count) nounwind {
1117; CHECK-LABEL: post-indexed-sub-word
1118; CHECK: ldr w{{[0-9]+}}, [x{{[0-9]+}}], #-8
1119; CHECK: str w{{[0-9]+}}, [x{{[0-9]+}}], #-8
1120 br label %for.body
1121for.body:
1122 %phi1 = phi i32* [ %gep4, %for.body ], [ %b, %0 ]
1123 %phi2 = phi i32* [ %gep3, %for.body ], [ %a, %0 ]
1124 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +00001125 %gep1 = getelementptr i32, i32* %phi1, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001126 %load1 = load i32, i32* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +00001127 %gep2 = getelementptr i32, i32* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001128 store i32 %load1, i32* %gep2
David Blaikiea79ac142015-02-27 21:17:42 +00001129 %load2 = load i32, i32* %phi1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001130 store i32 %load2, i32* %phi2
1131 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +00001132 %gep3 = getelementptr i32, i32* %phi2, i64 -2
1133 %gep4 = getelementptr i32, i32* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001134 %cond = icmp sgt i64 %dec.i, 0
1135 br i1 %cond, label %for.body, label %end
1136end:
1137 ret void
1138}
1139
1140define void @post-indexed-sub-doubleword(i64* %a, i64* %b, i64 %count) nounwind {
1141; CHECK-LABEL: post-indexed-sub-doubleword
1142; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-16
1143; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-16
1144 br label %for.body
1145for.body:
1146 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
1147 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
1148 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +00001149 %gep1 = getelementptr i64, i64* %phi1, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001150 %load1 = load i64, i64* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +00001151 %gep2 = getelementptr i64, i64* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001152 store i64 %load1, i64* %gep2
David Blaikiea79ac142015-02-27 21:17:42 +00001153 %load2 = load i64, i64* %phi1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001154 store i64 %load2, i64* %phi2
1155 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +00001156 %gep3 = getelementptr i64, i64* %phi2, i64 -2
1157 %gep4 = getelementptr i64, i64* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001158 %cond = icmp sgt i64 %dec.i, 0
1159 br i1 %cond, label %for.body, label %end
1160end:
1161 ret void
1162}
1163
1164define void @post-indexed-sub-quadword(<2 x i64>* %a, <2 x i64>* %b, i64 %count) nounwind {
1165; CHECK-LABEL: post-indexed-sub-quadword
1166; CHECK: ldr q{{[0-9]+}}, [x{{[0-9]+}}], #-32
1167; CHECK: str q{{[0-9]+}}, [x{{[0-9]+}}], #-32
1168 br label %for.body
1169for.body:
1170 %phi1 = phi <2 x i64>* [ %gep4, %for.body ], [ %b, %0 ]
1171 %phi2 = phi <2 x i64>* [ %gep3, %for.body ], [ %a, %0 ]
1172 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +00001173 %gep1 = getelementptr <2 x i64>, <2 x i64>* %phi1, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001174 %load1 = load <2 x i64>, <2 x i64>* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +00001175 %gep2 = getelementptr <2 x i64>, <2 x i64>* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001176 store <2 x i64> %load1, <2 x i64>* %gep2
David Blaikiea79ac142015-02-27 21:17:42 +00001177 %load2 = load <2 x i64>, <2 x i64>* %phi1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001178 store <2 x i64> %load2, <2 x i64>* %phi2
1179 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +00001180 %gep3 = getelementptr <2 x i64>, <2 x i64>* %phi2, i64 -2
1181 %gep4 = getelementptr <2 x i64>, <2 x i64>* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001182 %cond = icmp sgt i64 %dec.i, 0
1183 br i1 %cond, label %for.body, label %end
1184end:
1185 ret void
1186}
1187
1188define void @post-indexed-sub-float(float* %a, float* %b, i64 %count) nounwind {
1189; CHECK-LABEL: post-indexed-sub-float
1190; CHECK: ldr s{{[0-9]+}}, [x{{[0-9]+}}], #-8
1191; CHECK: str s{{[0-9]+}}, [x{{[0-9]+}}], #-8
1192 br label %for.body
1193for.body:
1194 %phi1 = phi float* [ %gep4, %for.body ], [ %b, %0 ]
1195 %phi2 = phi float* [ %gep3, %for.body ], [ %a, %0 ]
1196 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +00001197 %gep1 = getelementptr float, float* %phi1, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001198 %load1 = load float, float* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +00001199 %gep2 = getelementptr float, float* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001200 store float %load1, float* %gep2
David Blaikiea79ac142015-02-27 21:17:42 +00001201 %load2 = load float, float* %phi1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001202 store float %load2, float* %phi2
1203 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +00001204 %gep3 = getelementptr float, float* %phi2, i64 -2
1205 %gep4 = getelementptr float, float* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001206 %cond = icmp sgt i64 %dec.i, 0
1207 br i1 %cond, label %for.body, label %end
1208end:
1209 ret void
1210}
1211
1212define void @post-indexed-sub-double(double* %a, double* %b, i64 %count) nounwind {
1213; CHECK-LABEL: post-indexed-sub-double
1214; CHECK: ldr d{{[0-9]+}}, [x{{[0-9]+}}], #-16
1215; CHECK: str d{{[0-9]+}}, [x{{[0-9]+}}], #-16
1216 br label %for.body
1217for.body:
1218 %phi1 = phi double* [ %gep4, %for.body ], [ %b, %0 ]
1219 %phi2 = phi double* [ %gep3, %for.body ], [ %a, %0 ]
1220 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
David Blaikie79e6c742015-02-27 19:29:02 +00001221 %gep1 = getelementptr double, double* %phi1, i64 -1
David Blaikiea79ac142015-02-27 21:17:42 +00001222 %load1 = load double, double* %gep1
David Blaikie79e6c742015-02-27 19:29:02 +00001223 %gep2 = getelementptr double, double* %phi2, i64 -1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001224 store double %load1, double* %gep2
David Blaikiea79ac142015-02-27 21:17:42 +00001225 %load2 = load double, double* %phi1
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001226 store double %load2, double* %phi2
1227 %dec.i = add nsw i64 %i, -1
David Blaikie79e6c742015-02-27 19:29:02 +00001228 %gep3 = getelementptr double, double* %phi2, i64 -2
1229 %gep4 = getelementptr double, double* %phi1, i64 -2
Tilmann Scheller2a7efeb2014-06-03 16:03:00 +00001230 %cond = icmp sgt i64 %dec.i, 0
1231 br i1 %cond, label %for.body, label %end
1232end:
1233 ret void
1234}
Eli Friedman8585e9d2016-08-12 20:28:02 +00001235
1236define void @post-indexed-sub-doubleword-offset-min(i64* %a, i64* %b, i64 %count) nounwind {
1237; CHECK-LABEL: post-indexed-sub-doubleword-offset-min
1238; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}], #-256
1239; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}], #-256
1240 br label %for.body
1241for.body:
1242 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
1243 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
1244 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
1245 %gep1 = getelementptr i64, i64* %phi1, i64 1
1246 %load1 = load i64, i64* %gep1
1247 %gep2 = getelementptr i64, i64* %phi2, i64 1
1248 store i64 %load1, i64* %gep2
1249 %load2 = load i64, i64* %phi1
1250 store i64 %load2, i64* %phi2
1251 %dec.i = add nsw i64 %i, -1
1252 %gep3 = getelementptr i64, i64* %phi2, i64 -32
1253 %gep4 = getelementptr i64, i64* %phi1, i64 -32
1254 %cond = icmp sgt i64 %dec.i, 0
1255 br i1 %cond, label %for.body, label %end
1256end:
1257 ret void
1258}
1259
1260define void @post-indexed-doubleword-offset-out-of-range(i64* %a, i64* %b, i64 %count) nounwind {
1261; CHECK-LABEL: post-indexed-doubleword-offset-out-of-range
1262; CHECK: ldr x{{[0-9]+}}, [x{{[0-9]+}}]
1263; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #256
1264; CHECK: str x{{[0-9]+}}, [x{{[0-9]+}}]
1265; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #256
1266
1267 br label %for.body
1268for.body:
1269 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
1270 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
1271 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
1272 %gep1 = getelementptr i64, i64* %phi1, i64 1
1273 %load1 = load i64, i64* %gep1
1274 %gep2 = getelementptr i64, i64* %phi2, i64 1
1275 store i64 %load1, i64* %gep2
1276 %load2 = load i64, i64* %phi1
1277 store i64 %load2, i64* %phi2
1278 %dec.i = add nsw i64 %i, -1
1279 %gep3 = getelementptr i64, i64* %phi2, i64 32
1280 %gep4 = getelementptr i64, i64* %phi1, i64 32
1281 %cond = icmp sgt i64 %dec.i, 0
1282 br i1 %cond, label %for.body, label %end
1283end:
1284 ret void
1285}
1286
1287define void @post-indexed-paired-min-offset(i64* %a, i64* %b, i64 %count) nounwind {
1288; CHECK-LABEL: post-indexed-paired-min-offset
1289; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-512
1290; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}], #-512
1291 br label %for.body
1292for.body:
1293 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
1294 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
1295 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
1296 %gep1 = getelementptr i64, i64* %phi1, i64 1
1297 %load1 = load i64, i64* %gep1
1298 %gep2 = getelementptr i64, i64* %phi2, i64 1
1299 %load2 = load i64, i64* %phi1
1300 store i64 %load1, i64* %gep2
1301 store i64 %load2, i64* %phi2
1302 %dec.i = add nsw i64 %i, -1
1303 %gep3 = getelementptr i64, i64* %phi2, i64 -64
1304 %gep4 = getelementptr i64, i64* %phi1, i64 -64
1305 %cond = icmp sgt i64 %dec.i, 0
1306 br i1 %cond, label %for.body, label %end
1307end:
1308 ret void
1309}
1310
1311define void @post-indexed-paired-offset-out-of-range(i64* %a, i64* %b, i64 %count) nounwind {
1312; CHECK-LABEL: post-indexed-paired-offset-out-of-range
1313; CHECK: ldp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]
1314; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #512
1315; CHECK: stp x{{[0-9]+}}, x{{[0-9]+}}, [x{{[0-9]+}}]
1316; CHECK: add x{{[0-9]+}}, x{{[0-9]+}}, #512
1317 br label %for.body
1318for.body:
1319 %phi1 = phi i64* [ %gep4, %for.body ], [ %b, %0 ]
1320 %phi2 = phi i64* [ %gep3, %for.body ], [ %a, %0 ]
1321 %i = phi i64 [ %dec.i, %for.body], [ %count, %0 ]
1322 %gep1 = getelementptr i64, i64* %phi1, i64 1
1323 %load1 = load i64, i64* %phi1
1324 %gep2 = getelementptr i64, i64* %phi2, i64 1
1325 %load2 = load i64, i64* %gep1
1326 store i64 %load1, i64* %gep2
1327 store i64 %load2, i64* %phi2
1328 %dec.i = add nsw i64 %i, -1
1329 %gep3 = getelementptr i64, i64* %phi2, i64 64
1330 %gep4 = getelementptr i64, i64* %phi1, i64 64
1331 %cond = icmp sgt i64 %dec.i, 0
1332 br i1 %cond, label %for.body, label %end
1333end:
1334 ret void
1335}