[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / CodeGen / PowerPC / store-combine.ll
blob86be121eb45b7dd6bd1f5b18cf2e6a3fffdb98c2
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs < %s | FileCheck %s -check-prefix=CHECK-PPC64LE
3 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs < %s | FileCheck %s -check-prefix=CHECK-PPC64
4 ; i8* p;
5 ; i32 m;
6 ; p[0] = (m >> 0) & 0xFF;
7 ; p[1] = (m >> 8) & 0xFF;
8 ; p[2] = (m >> 16) & 0xFF;
9 ; p[3] = (m >> 24) & 0xFF;
10 define void @store_i32_by_i8(i32 signext %m, i8* %p) {
11 ; CHECK-PPC64LE-LABEL: store_i32_by_i8:
12 ; CHECK-PPC64LE:       # %bb.0: # %entry
13 ; CHECK-PPC64LE-NEXT:    stw 3, 0(4)
14 ; CHECK-PPC64LE-NEXT:    blr
16 ; CHECK-PPC64-LABEL: store_i32_by_i8:
17 ; CHECK-PPC64:       # %bb.0: # %entry
18 ; CHECK-PPC64-NEXT:    stwbrx 3, 0, 4
19 ; CHECK-PPC64-NEXT:    blr
20 entry:
21   %conv = trunc i32 %m to i8
22   store i8 %conv, i8* %p, align 1
23   %0 = lshr i32 %m, 8
24   %conv3 = trunc i32 %0 to i8
25   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
26   store i8 %conv3, i8* %arrayidx4, align 1
27   %1 = lshr i32 %m, 16
28   %conv7 = trunc i32 %1 to i8
29   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
30   store i8 %conv7, i8* %arrayidx8, align 1
31   %2 = lshr i32 %m, 24
32   %conv11 = trunc i32 %2 to i8
33   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
34   store i8 %conv11, i8* %arrayidx12, align 1
35   ret void
37 ; i8* p;
38 ; i32 m;
39 ; p[0] = (m >> 24) & 0xFF;
40 ; p[1] = (m >> 16) & 0xFF;
41 ; p[2] = (m >> 8) & 0xFF;
42 ; p[3] = (m >> 0) & 0xFF;
43 define void @store_i32_by_i8_bswap(i32 signext %m, i8* %p)  {
44 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap:
45 ; CHECK-PPC64LE:       # %bb.0: # %entry
46 ; CHECK-PPC64LE-NEXT:    stwbrx 3, 0, 4
47 ; CHECK-PPC64LE-NEXT:    blr
49 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap:
50 ; CHECK-PPC64:       # %bb.0: # %entry
51 ; CHECK-PPC64-NEXT:    stw 3, 0(4)
52 ; CHECK-PPC64-NEXT:    blr
53 entry:
54   %0 = lshr i32 %m, 24
55   %conv = trunc i32 %0 to i8
56   store i8 %conv, i8* %p, align 1
57   %1 = lshr i32 %m, 16
58   %conv3 = trunc i32 %1 to i8
59   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
60   store i8 %conv3, i8* %arrayidx4, align 1
61   %2 = lshr i32 %m, 8
62   %conv7 = trunc i32 %2 to i8
63   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
64   store i8 %conv7, i8* %arrayidx8, align 1
65   %conv11 = trunc i32 %m to i8
66   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
67   store i8 %conv11, i8* %arrayidx12, align 1
68   ret void
70 ; i8 *p;
71 ; i64 m;
72 ; p[0] = (m >> 0) & 0xFF;
73 ; p[1] = (m >> 8) & 0xFF;
74 ; p[2] = (m >> 16) & 0xFF;
75 ; p[3] = (m >> 24) & 0xFF;
76 ; p[4] = (m >> 32) & 0xFF;
77 ; p[5] = (m >> 40) & 0xFF;
78 ; p[6] = (m >> 48) & 0xFF;
79 ; p[7] = (m >> 56) & 0xFF;
80 define void @store_i64_by_i8(i64 %m, i8* %p)  {
81 ; CHECK-PPC64LE-LABEL: store_i64_by_i8:
82 ; CHECK-PPC64LE:       # %bb.0: # %entry
83 ; CHECK-PPC64LE-NEXT:    stdx 3, 0, 4
84 ; CHECK-PPC64LE-NEXT:    blr
86 ; CHECK-PPC64-LABEL: store_i64_by_i8:
87 ; CHECK-PPC64:       # %bb.0: # %entry
88 ; CHECK-PPC64-NEXT:    stdbrx 3, 0, 4
89 ; CHECK-PPC64-NEXT:    blr
90 entry:
91   %conv = trunc i64 %m to i8
92   store i8 %conv, i8* %p, align 1
93   %0 = lshr i64 %m, 8
94   %conv3 = trunc i64 %0 to i8
95   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
96   store i8 %conv3, i8* %arrayidx4, align 1
97   %1 = lshr i64 %m, 16
98   %conv7 = trunc i64 %1 to i8
99   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
100   store i8 %conv7, i8* %arrayidx8, align 1
101   %2 = lshr i64 %m, 24
102   %conv11 = trunc i64 %2 to i8
103   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
104   store i8 %conv11, i8* %arrayidx12, align 1
105   %3 = lshr i64 %m, 32
106   %conv15 = trunc i64 %3 to i8
107   %arrayidx16 = getelementptr inbounds i8, i8* %p, i64 4
108   store i8 %conv15, i8* %arrayidx16, align 1
109   %4 = lshr i64 %m, 40
110   %conv19 = trunc i64 %4 to i8
111   %arrayidx20 = getelementptr inbounds i8, i8* %p, i64 5
112   store i8 %conv19, i8* %arrayidx20, align 1
113   %5 = lshr i64 %m, 48
114   %conv23 = trunc i64 %5 to i8
115   %arrayidx24 = getelementptr inbounds i8, i8* %p, i64 6
116   store i8 %conv23, i8* %arrayidx24, align 1
117   %6 = lshr i64 %m, 56
118   %conv27 = trunc i64 %6 to i8
119   %arrayidx28 = getelementptr inbounds i8, i8* %p, i64 7
120   store i8 %conv27, i8* %arrayidx28, align 1
121   ret void
123 ; i8 *p;
124 ; i64 m;
125 ; p[7] = (m >> 0) & 0xFF;
126 ; p[6] = (m >> 8) & 0xFF;
127 ; p[5] = (m >> 16) & 0xFF;
128 ; p[4] = (m >> 24) & 0xFF;
129 ; p[3] = (m >> 32) & 0xFF;
130 ; p[2] = (m >> 40) & 0xFF;
131 ; p[1] = (m >> 48) & 0xFF;
132 ; p[0] = (m >> 56) & 0xFF;
133 define void @store_i64_by_i8_bswap(i64 %m, i8* %p)  {
134 ; CHECK-PPC64LE-LABEL: store_i64_by_i8_bswap:
135 ; CHECK-PPC64LE:       # %bb.0: # %entry
136 ; CHECK-PPC64LE-NEXT:    stdbrx 3, 0, 4
137 ; CHECK-PPC64LE-NEXT:    blr
139 ; CHECK-PPC64-LABEL: store_i64_by_i8_bswap:
140 ; CHECK-PPC64:       # %bb.0: # %entry
141 ; CHECK-PPC64-NEXT:    stdx 3, 0, 4
142 ; CHECK-PPC64-NEXT:    blr
143 entry:
144   %conv = trunc i64 %m to i8
145   %arrayidx = getelementptr inbounds i8, i8* %p, i64 7
146   store i8 %conv, i8* %arrayidx, align 1
147   %0 = lshr i64 %m, 8
148   %conv3 = trunc i64 %0 to i8
149   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 6
150   store i8 %conv3, i8* %arrayidx4, align 1
151   %1 = lshr i64 %m, 16
152   %conv7 = trunc i64 %1 to i8
153   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 5
154   store i8 %conv7, i8* %arrayidx8, align 1
155   %2 = lshr i64 %m, 24
156   %conv11 = trunc i64 %2 to i8
157   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 4
158   store i8 %conv11, i8* %arrayidx12, align 1
159   %3 = lshr i64 %m, 32
160   %conv15 = trunc i64 %3 to i8
161   %arrayidx16 = getelementptr inbounds i8, i8* %p, i64 3
162   store i8 %conv15, i8* %arrayidx16, align 1
163   %4 = lshr i64 %m, 40
164   %conv19 = trunc i64 %4 to i8
165   %arrayidx20 = getelementptr inbounds i8, i8* %p, i64 2
166   store i8 %conv19, i8* %arrayidx20, align 1
167   %5 = lshr i64 %m, 48
168   %conv23 = trunc i64 %5 to i8
169   %arrayidx24 = getelementptr inbounds i8, i8* %p, i64 1
170   store i8 %conv23, i8* %arrayidx24, align 1
171   %6 = lshr i64 %m, 56
172   %conv27 = trunc i64 %6 to i8
173   store i8 %conv27, i8* %p, align 1
174   ret void
177 ; i32 t; i8 *p;
178 ; i64 m = t * 7;
179 ; p[7] = (m >> 0) & 0xFF;
180 ; p[6] = (m >> 8) & 0xFF;
181 ; p[5] = (m >> 16) & 0xFF;
182 ; p[4] = (m >> 24) & 0xFF;
183 ; p[3] = (m >> 32) & 0xFF;
184 ; p[2] = (m >> 40) & 0xFF;
185 ; p[1] = (m >> 48) & 0xFF;
186 ; p[0] = (m >> 56) & 0xFF;
187 define void @store_i64_by_i8_bswap_uses(i32 signext %t, i8* %p) {
188 ; CHECK-PPC64LE-LABEL: store_i64_by_i8_bswap_uses:
189 ; CHECK-PPC64LE:       # %bb.0: # %entry
190 ; CHECK-PPC64LE-NEXT:    slwi 5, 3, 3
191 ; CHECK-PPC64LE-NEXT:    subf 3, 3, 5
192 ; CHECK-PPC64LE-NEXT:    extsw 3, 3
193 ; CHECK-PPC64LE-NEXT:    stdbrx 3, 0, 4
194 ; CHECK-PPC64LE-NEXT:    blr
196 ; CHECK-PPC64-LABEL: store_i64_by_i8_bswap_uses:
197 ; CHECK-PPC64:       # %bb.0: # %entry
198 ; CHECK-PPC64-NEXT:    slwi 5, 3, 3
199 ; CHECK-PPC64-NEXT:    subf 3, 3, 5
200 ; CHECK-PPC64-NEXT:    extsw 3, 3
201 ; CHECK-PPC64-NEXT:    stdx 3, 0, 4
202 ; CHECK-PPC64-NEXT:    blr
203 entry:
204   %mul = mul nsw i32 %t, 7
205   %conv = sext i32 %mul to i64
206   %conv1 = trunc i32 %mul to i8
207   %arrayidx = getelementptr inbounds i8, i8* %p, i64 7
208   store i8 %conv1, i8* %arrayidx, align 1
209   %0 = lshr i64 %conv, 8
210   %conv4 = trunc i64 %0 to i8
211   %arrayidx5 = getelementptr inbounds i8, i8* %p, i64 6
212   store i8 %conv4, i8* %arrayidx5, align 1
213   %1 = lshr i64 %conv, 16
214   %conv8 = trunc i64 %1 to i8
215   %arrayidx9 = getelementptr inbounds i8, i8* %p, i64 5
216   store i8 %conv8, i8* %arrayidx9, align 1
217   %2 = lshr i64 %conv, 24
218   %conv12 = trunc i64 %2 to i8
219   %arrayidx13 = getelementptr inbounds i8, i8* %p, i64 4
220   store i8 %conv12, i8* %arrayidx13, align 1
221   %shr14 = ashr i64 %conv, 32
222   %conv16 = trunc i64 %shr14 to i8
223   %arrayidx17 = getelementptr inbounds i8, i8* %p, i64 3
224   store i8 %conv16, i8* %arrayidx17, align 1
225   %shr18 = ashr i64 %conv, 40
226   %conv20 = trunc i64 %shr18 to i8
227   %arrayidx21 = getelementptr inbounds i8, i8* %p, i64 2
228   store i8 %conv20, i8* %arrayidx21, align 1
229   %shr22 = ashr i64 %conv, 48
230   %conv24 = trunc i64 %shr22 to i8
231   %arrayidx25 = getelementptr inbounds i8, i8* %p, i64 1
232   store i8 %conv24, i8* %arrayidx25, align 1
233   %shr26 = ashr i64 %conv, 56
234   %conv28 = trunc i64 %shr26 to i8
235   store i8 %conv28, i8* %p, align 1
236   ret void
239 ; One of the stores is volatile
240 ; i8 *p;
241 ; p0 = volatile *p;
242 ; p[3] = (m >> 0) & 0xFF;
243 ; p[2] = (m >> 8) & 0xFF;
244 ; p[1] = (m >> 16) & 0xFF;
245 ; *p0 = (m >> 24) & 0xFF;
246 define void @store_i32_by_i8_bswap_volatile(i32 signext %m, i8* %p) {
247 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_volatile:
248 ; CHECK-PPC64LE:       # %bb.0: # %entry
249 ; CHECK-PPC64LE-NEXT:    li 5, 2
250 ; CHECK-PPC64LE-NEXT:    sthbrx 3, 4, 5
251 ; CHECK-PPC64LE-NEXT:    srwi 5, 3, 16
252 ; CHECK-PPC64LE-NEXT:    srwi 3, 3, 24
253 ; CHECK-PPC64LE-NEXT:    stb 5, 1(4)
254 ; CHECK-PPC64LE-NEXT:    stb 3, 0(4)
255 ; CHECK-PPC64LE-NEXT:    blr
257 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_volatile:
258 ; CHECK-PPC64:       # %bb.0: # %entry
259 ; CHECK-PPC64-NEXT:    sth 3, 2(4)
260 ; CHECK-PPC64-NEXT:    srwi 5, 3, 16
261 ; CHECK-PPC64-NEXT:    srwi 3, 3, 24
262 ; CHECK-PPC64-NEXT:    stb 5, 1(4)
263 ; CHECK-PPC64-NEXT:    stb 3, 0(4)
264 ; CHECK-PPC64-NEXT:    blr
265 entry:
266   %conv = trunc i32 %m to i8
267   %arrayidx = getelementptr inbounds i8, i8* %p, i64 3
268   store i8 %conv, i8* %arrayidx, align 1
269   %0 = lshr i32 %m, 8
270   %conv3 = trunc i32 %0 to i8
271   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 2
272   store i8 %conv3, i8* %arrayidx4, align 1
273   %1 = lshr i32 %m, 16
274   %conv7 = trunc i32 %1 to i8
275   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
276   store i8 %conv7, i8* %arrayidx8, align 1
277   %2 = lshr i32 %m, 24
278   %conv11 = trunc i32 %2 to i8
279   store volatile i8 %conv11, i8* %p, align 1
280   ret void
283 ; There is a store in between individual stores
284 ; i8* p, q;
285 ; p[3] = (m >> 0) & 0xFF;
286 ; p[2] = (m >> 8) & 0xFF;
287 ; *q = 3;
288 ; p[1] = (m >> 16) & 0xFF;
289 ; p[0] = (m >> 24) & 0xFF;
290 define void @store_i32_by_i8_bswap_store_in_between(i32 signext %m, i8* %p, i8* %q) {
291 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_store_in_between:
292 ; CHECK-PPC64LE:       # %bb.0: # %entry
293 ; CHECK-PPC64LE-NEXT:    li 6, 2
294 ; CHECK-PPC64LE-NEXT:    sthbrx 3, 4, 6
295 ; CHECK-PPC64LE-NEXT:    li 6, 3
296 ; CHECK-PPC64LE-NEXT:    stb 6, 0(5)
297 ; CHECK-PPC64LE-NEXT:    srwi 5, 3, 16
298 ; CHECK-PPC64LE-NEXT:    srwi 3, 3, 24
299 ; CHECK-PPC64LE-NEXT:    stb 5, 1(4)
300 ; CHECK-PPC64LE-NEXT:    stb 3, 0(4)
301 ; CHECK-PPC64LE-NEXT:    blr
303 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_store_in_between:
304 ; CHECK-PPC64:       # %bb.0: # %entry
305 ; CHECK-PPC64-NEXT:    li 6, 3
306 ; CHECK-PPC64-NEXT:    sth 3, 2(4)
307 ; CHECK-PPC64-NEXT:    stb 6, 0(5)
308 ; CHECK-PPC64-NEXT:    srwi 5, 3, 16
309 ; CHECK-PPC64-NEXT:    srwi 3, 3, 24
310 ; CHECK-PPC64-NEXT:    stb 5, 1(4)
311 ; CHECK-PPC64-NEXT:    stb 3, 0(4)
312 ; CHECK-PPC64-NEXT:    blr
313 entry:
314   %conv = trunc i32 %m to i8
315   %arrayidx = getelementptr inbounds i8, i8* %p, i64 3
316   store i8 %conv, i8* %arrayidx, align 1
317   %0 = lshr i32 %m, 8
318   %conv3 = trunc i32 %0 to i8
319   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 2
320   store i8 %conv3, i8* %arrayidx4, align 1
321   store i8 3, i8* %q, align 1
322   %1 = lshr i32 %m, 16
323   %conv7 = trunc i32 %1 to i8
324   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
325   store i8 %conv7, i8* %arrayidx8, align 1
326   %2 = lshr i32 %m, 24
327   %conv11 = trunc i32 %2 to i8
328   store i8 %conv11, i8* %p, align 1
329   ret void
332 define void @store_i32_by_i8_bswap_unrelated_store(i32 signext %m, i8* %p, i8* %q) {
333 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_unrelated_store:
334 ; CHECK-PPC64LE:       # %bb.0: # %entry
335 ; CHECK-PPC64LE-NEXT:    srwi 6, 3, 8
336 ; CHECK-PPC64LE-NEXT:    stb 3, 3(4)
337 ; CHECK-PPC64LE-NEXT:    stb 6, 2(5)
338 ; CHECK-PPC64LE-NEXT:    srwi 5, 3, 16
339 ; CHECK-PPC64LE-NEXT:    srwi 3, 3, 24
340 ; CHECK-PPC64LE-NEXT:    stb 5, 1(4)
341 ; CHECK-PPC64LE-NEXT:    stb 3, 0(4)
342 ; CHECK-PPC64LE-NEXT:    blr
344 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_unrelated_store:
345 ; CHECK-PPC64:       # %bb.0: # %entry
346 ; CHECK-PPC64-NEXT:    srwi 6, 3, 8
347 ; CHECK-PPC64-NEXT:    stb 3, 3(4)
348 ; CHECK-PPC64-NEXT:    stb 6, 2(5)
349 ; CHECK-PPC64-NEXT:    srwi 5, 3, 16
350 ; CHECK-PPC64-NEXT:    srwi 3, 3, 24
351 ; CHECK-PPC64-NEXT:    stb 5, 1(4)
352 ; CHECK-PPC64-NEXT:    stb 3, 0(4)
353 ; CHECK-PPC64-NEXT:    blr
354 entry:
355   %conv = trunc i32 %m to i8
356   %arrayidx = getelementptr inbounds i8, i8* %p, i64 3
357   store i8 %conv, i8* %arrayidx, align 1
358   %0 = lshr i32 %m, 8
359   %conv3 = trunc i32 %0 to i8
360   %arrayidx4 = getelementptr inbounds i8, i8* %q, i64 2
361   store i8 %conv3, i8* %arrayidx4, align 1
362   %1 = lshr i32 %m, 16
363   %conv7 = trunc i32 %1 to i8
364   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
365   store i8 %conv7, i8* %arrayidx8, align 1
366   %2 = lshr i32 %m, 24
367   %conv11 = trunc i32 %2 to i8
368   store i8 %conv11, i8* %p, align 1
369   ret void
371 ; i32 m;
372 ; i8* p;
373 ; p[3] = (m >> 8) & 0xFF;
374 ; p[4] = (m >> 0) & 0xFF;
375 ; p[2] = (m >> 16) & 0xFF;
376 ; p[1] = (m >> 24) & 0xFF;
377 define void @store_i32_by_i8_bswap_nonzero_offset(i32 signext %m, i8* %p) {
378 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_nonzero_offset:
379 ; CHECK-PPC64LE:       # %bb.0: # %entry
380 ; CHECK-PPC64LE-NEXT:    addi 4, 4, 1
381 ; CHECK-PPC64LE-NEXT:    stwbrx 3, 0, 4
382 ; CHECK-PPC64LE-NEXT:    blr
384 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_nonzero_offset:
385 ; CHECK-PPC64:       # %bb.0: # %entry
386 ; CHECK-PPC64-NEXT:    stw 3, 1(4)
387 ; CHECK-PPC64-NEXT:    blr
388 entry:
389   %0 = lshr i32 %m, 8
390   %conv = trunc i32 %0 to i8
391   %arrayidx = getelementptr inbounds i8, i8* %p, i64 3
392   store i8 %conv, i8* %arrayidx, align 1
393   %conv3 = trunc i32 %m to i8
394   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 4
395   store i8 %conv3, i8* %arrayidx4, align 1
396   %1 = lshr i32 %m, 16
397   %conv7 = trunc i32 %1 to i8
398   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
399   store i8 %conv7, i8* %arrayidx8, align 1
400   %2 = lshr i32 %m, 24
401   %conv11 = trunc i32 %2 to i8
402   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 1
403   store i8 %conv11, i8* %arrayidx12, align 1
404   ret void
406 ; i32 m;
407 ; i8* p;
408 ; p[-3] = (m >> 8) & 0xFF;
409 ; p[-4] = (m >> 0) & 0xFF;
410 ; p[-2] = (m >> 16) & 0xFF;
411 ; p[-1] = (m >> 24) & 0xFF;
412 define void @store_i32_by_i8_neg_offset(i32 signext %m, i8* %p) {
413 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_neg_offset:
414 ; CHECK-PPC64LE:       # %bb.0: # %entry
415 ; CHECK-PPC64LE-NEXT:    stw 3, -4(4)
416 ; CHECK-PPC64LE-NEXT:    blr
418 ; CHECK-PPC64-LABEL: store_i32_by_i8_neg_offset:
419 ; CHECK-PPC64:       # %bb.0: # %entry
420 ; CHECK-PPC64-NEXT:    addi 4, 4, -4
421 ; CHECK-PPC64-NEXT:    stwbrx 3, 0, 4
422 ; CHECK-PPC64-NEXT:    blr
423 entry:
424   %0 = lshr i32 %m, 8
425   %conv = trunc i32 %0 to i8
426   %arrayidx = getelementptr inbounds i8, i8* %p, i64 -3
427   store i8 %conv, i8* %arrayidx, align 1
428   %conv3 = trunc i32 %m to i8
429   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 -4
430   store i8 %conv3, i8* %arrayidx4, align 1
431   %1 = lshr i32 %m, 16
432   %conv7 = trunc i32 %1 to i8
433   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 -2
434   store i8 %conv7, i8* %arrayidx8, align 1
435   %2 = lshr i32 %m, 24
436   %conv11 = trunc i32 %2 to i8
437   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 -1
438   store i8 %conv11, i8* %arrayidx12, align 1
439   ret void
441 ; i32 m;
442 ; i8* p;
443 ; p[-3] = (m >> 16) & 0xFF;
444 ; p[-4] = (m >> 24) & 0xFF;
445 ; p[-2] = (m >> 8) & 0xFF;
446 ; p[-1] = (m >> 0) & 0xFF;
447 define void @store_i32_by_i8_bswap_neg_offset(i32 signext %m, i8* %p) {
448 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_neg_offset:
449 ; CHECK-PPC64LE:       # %bb.0: # %entry
450 ; CHECK-PPC64LE-NEXT:    addi 4, 4, -4
451 ; CHECK-PPC64LE-NEXT:    stwbrx 3, 0, 4
452 ; CHECK-PPC64LE-NEXT:    blr
454 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_neg_offset:
455 ; CHECK-PPC64:       # %bb.0: # %entry
456 ; CHECK-PPC64-NEXT:    stw 3, -4(4)
457 ; CHECK-PPC64-NEXT:    blr
458 entry:
459   %0 = lshr i32 %m, 16
460   %conv = trunc i32 %0 to i8
461   %arrayidx = getelementptr inbounds i8, i8* %p, i64 -3
462   store i8 %conv, i8* %arrayidx, align 1
463   %1 = lshr i32 %m, 24
464   %conv3 = trunc i32 %1 to i8
465   %arrayidx4 = getelementptr inbounds i8, i8* %p, i64 -4
466   store i8 %conv3, i8* %arrayidx4, align 1
467   %2 = lshr i32 %m, 8
468   %conv7 = trunc i32 %2 to i8
469   %arrayidx8 = getelementptr inbounds i8, i8* %p, i64 -2
470   store i8 %conv7, i8* %arrayidx8, align 1
471   %conv11 = trunc i32 %m to i8
472   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 -1
473   store i8 %conv11, i8* %arrayidx12, align 1
474   ret void
476 ; i32 m, i;
477 ; i8* p;
478 ; p[i-3] = (m >> 16) & 0xFF;
479 ; p[i-4] = (m >> 24) & 0xFF;
480 ; p[i-2] = (m >> 8) & 0xFF;
481 ; p[i-1] = (m >> 0) & 0xFF;
482 define void @store_i32_by_i8_bswap_base_index_offset(i32 %m, i32 %i, i8* %p) {
483 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_base_index_offset:
484 ; CHECK-PPC64LE:       # %bb.0: # %entry
485 ; CHECK-PPC64LE-NEXT:    extsw 4, 4
486 ; CHECK-PPC64LE-NEXT:    add 4, 5, 4
487 ; CHECK-PPC64LE-NEXT:    addi 4, 4, -4
488 ; CHECK-PPC64LE-NEXT:    stwbrx 3, 0, 4
489 ; CHECK-PPC64LE-NEXT:    blr
491 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_base_index_offset:
492 ; CHECK-PPC64:       # %bb.0: # %entry
493 ; CHECK-PPC64-NEXT:    extsw 4, 4
494 ; CHECK-PPC64-NEXT:    add 4, 5, 4
495 ; CHECK-PPC64-NEXT:    stw 3, -4(4)
496 ; CHECK-PPC64-NEXT:    blr
497 entry:
498   %0 = lshr i32 %m, 16
499   %conv = trunc i32 %0 to i8
500   %sub = add nsw i32 %i, -3
501   %idxprom = sext i32 %sub to i64
502   %arrayidx = getelementptr inbounds i8, i8* %p, i64 %idxprom
503   store i8 %conv, i8* %arrayidx, align 1
504   %1 = lshr i32 %m, 24
505   %conv3 = trunc i32 %1 to i8
506   %sub4 = add nsw i32 %i, -4
507   %idxprom5 = sext i32 %sub4 to i64
508   %arrayidx6 = getelementptr inbounds i8, i8* %p, i64 %idxprom5
509   store i8 %conv3, i8* %arrayidx6, align 1
510   %2 = lshr i32 %m, 8
511   %conv9 = trunc i32 %2 to i8
512   %sub10 = add nsw i32 %i, -2
513   %idxprom11 = sext i32 %sub10 to i64
514   %arrayidx12 = getelementptr inbounds i8, i8* %p, i64 %idxprom11
515   store i8 %conv9, i8* %arrayidx12, align 1
516   %conv15 = trunc i32 %m to i8
517   %sub16 = add nsw i32 %i, -1
518   %idxprom17 = sext i32 %sub16 to i64
519   %arrayidx18 = getelementptr inbounds i8, i8* %p, i64 %idxprom17
520   store i8 %conv15, i8* %arrayidx18, align 1
521   ret void
524 ; i8* p;
525 ; i32 i, m;
526 ; i8* p0 = p + i;
527 ; i8* p1 = p + i + 1;
528 ; i8* p2 = p + i + 2;
529 ; i8 *p3 = p + i + 3;
530 ; p0[3] = (m >> 24) & 0xFF;
531 ; p1[3] = (m >> 16) & 0xFF;
532 ; p2[3] = (m >> 8) & 0xFF;
533 ; p3[3] = (m >> 0) & 0xFF;
534 define void @store_i32_by_i8_bswap_complicated(i32 %m, i32 %i, i8* %p) {
535 ; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_complicated:
536 ; CHECK-PPC64LE:       # %bb.0: # %entry
537 ; CHECK-PPC64LE-NEXT:    extsw 4, 4
538 ; CHECK-PPC64LE-NEXT:    add 4, 5, 4
539 ; CHECK-PPC64LE-NEXT:    addi 4, 4, 3
540 ; CHECK-PPC64LE-NEXT:    stwbrx 3, 0, 4
541 ; CHECK-PPC64LE-NEXT:    blr
543 ; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_complicated:
544 ; CHECK-PPC64:       # %bb.0: # %entry
545 ; CHECK-PPC64-NEXT:    extsw 4, 4
546 ; CHECK-PPC64-NEXT:    add 4, 5, 4
547 ; CHECK-PPC64-NEXT:    stw 3, 3(4)
548 ; CHECK-PPC64-NEXT:    blr
549 entry:
550   %idx.ext = sext i32 %i to i64
551   %add.ptr = getelementptr inbounds i8, i8* %p, i64 %idx.ext
552   %add.ptr3 = getelementptr inbounds i8, i8* %add.ptr, i64 1
553   %add.ptr6 = getelementptr inbounds i8, i8* %add.ptr, i64 2
554   %add.ptr9 = getelementptr inbounds i8, i8* %add.ptr, i64 3
555   %0 = lshr i32 %m, 24
556   %conv = trunc i32 %0 to i8
557   store i8 %conv, i8* %add.ptr9, align 1
558   %1 = lshr i32 %m, 16
559   %conv12 = trunc i32 %1 to i8
560   %arrayidx13 = getelementptr inbounds i8, i8* %add.ptr3, i64 3
561   store i8 %conv12, i8* %arrayidx13, align 1
562   %2 = lshr i32 %m, 8
563   %conv16 = trunc i32 %2 to i8
564   %arrayidx17 = getelementptr inbounds i8, i8* %add.ptr6, i64 3
565   store i8 %conv16, i8* %arrayidx17, align 1
566   %conv20 = trunc i32 %m to i8
567   %arrayidx21 = getelementptr inbounds i8, i8* %add.ptr9, i64 3
568   store i8 %conv20, i8* %arrayidx21, align 1
569   ret void
571 ; i8* p; i32 m;
572 ; p[0] = (m >> 8) & 0xFF;
573 ; p[1] = (m >> 0) & 0xFF;
574 define void @store_i16_by_i8_bswap(i16 %m, i8* %p) {
575 ; CHECK-PPC64LE-LABEL: store_i16_by_i8_bswap:
576 ; CHECK-PPC64LE:       # %bb.0: # %entry
577 ; CHECK-PPC64LE-NEXT:    sthbrx 3, 0, 4
578 ; CHECK-PPC64LE-NEXT:    blr
580 ; CHECK-PPC64-LABEL: store_i16_by_i8_bswap:
581 ; CHECK-PPC64:       # %bb.0: # %entry
582 ; CHECK-PPC64-NEXT:    sth 3, 0(4)
583 ; CHECK-PPC64-NEXT:    blr
584 entry:
585   %0 = lshr i16 %m, 8
586   %conv1 = trunc i16 %0 to i8
587   store i8 %conv1, i8* %p, align 1
588   %conv5 = trunc i16 %m to i8
589   %arrayidx6 = getelementptr inbounds i8, i8* %p, i64 1
590   store i8 %conv5, i8* %arrayidx6, align 1
591   ret void
593 ; i8* p; i32 m;
594 ; p[0] = (m >> 0) & 0xFF;
595 ; p[1] = (m >> 8) & 0xFF;
596 define void @store_16_by_i8(i16 %m, i8* %p) {
597 ; CHECK-PPC64LE-LABEL: store_16_by_i8:
598 ; CHECK-PPC64LE:       # %bb.0: # %entry
599 ; CHECK-PPC64LE-NEXT:    sth 3, 0(4)
600 ; CHECK-PPC64LE-NEXT:    blr
602 ; CHECK-PPC64-LABEL: store_16_by_i8:
603 ; CHECK-PPC64:       # %bb.0: # %entry
604 ; CHECK-PPC64-NEXT:    sthbrx 3, 0, 4
605 ; CHECK-PPC64-NEXT:    blr
606 entry:
607   %conv1 = trunc i16 %m to i8
608   store i8 %conv1, i8* %p, align 1
609   %0 = lshr i16 %m, 8
610   %conv5 = trunc i16 %0 to i8
611   %arrayidx6 = getelementptr inbounds i8, i8* %p, i64 1
612   store i8 %conv5, i8* %arrayidx6, align 1
613   ret void
615 ; This was found when testing the hexxagon in testsuite
616 ; i8* p; i8 v;
617 ; p[0] = v;
618 ; p[1] = v;
619 define void @store_same_value_to_consecutive_mem(i8* %p, i8 zeroext %v) {
620 ; CHECK-PPC64LE-LABEL: store_same_value_to_consecutive_mem:
621 ; CHECK-PPC64LE:       # %bb.0: # %entry
622 ; CHECK-PPC64LE-NEXT:    stb 4, 0(3)
623 ; CHECK-PPC64LE-NEXT:    stb 4, 1(3)
624 ; CHECK-PPC64LE-NEXT:    blr
626 ; CHECK-PPC64-LABEL: store_same_value_to_consecutive_mem:
627 ; CHECK-PPC64:       # %bb.0: # %entry
628 ; CHECK-PPC64-NEXT:    stb 4, 0(3)
629 ; CHECK-PPC64-NEXT:    stb 4, 1(3)
630 ; CHECK-PPC64-NEXT:    blr
631 entry:
632   store i8 %v, i8* %p, align 1
633   %arrayidx1 = getelementptr inbounds i8, i8* %p, i64 1
634   store i8 %v, i8* %arrayidx1, align 1
635   ret void