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;
10define 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
15;
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
20entry:
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
36}
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;
43define 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
48;
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
53entry:
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
69}
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;
80define 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:    std 3, 0(4)
84; CHECK-PPC64LE-NEXT:    blr
85;
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
90entry:
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
122}
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;
133define 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
138;
139; CHECK-PPC64-LABEL: store_i64_by_i8_bswap:
140; CHECK-PPC64:       # %bb.0: # %entry
141; CHECK-PPC64-NEXT:    std 3, 0(4)
142; CHECK-PPC64-NEXT:    blr
143entry:
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
175}
176
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;
187define 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:    sub 3, 5, 3
192; CHECK-PPC64LE-NEXT:    extsw 3, 3
193; CHECK-PPC64LE-NEXT:    stdbrx 3, 0, 4
194; CHECK-PPC64LE-NEXT:    blr
195;
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:    sub 3, 5, 3
200; CHECK-PPC64-NEXT:    extsw 3, 3
201; CHECK-PPC64-NEXT:    std 3, 0(4)
202; CHECK-PPC64-NEXT:    blr
203entry:
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
237}
238
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;
246define 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
256;
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
265entry:
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
281}
282
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;
290define 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
302;
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
313entry:
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
330}
331
332define 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
343;
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
354entry:
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
370}
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;
377define 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
383;
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
388entry:
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
405}
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;
412define 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
417;
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
423entry:
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
440}
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;
447define 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
453;
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
458entry:
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
475}
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;
482define 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
490;
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
497entry:
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
522}
523
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;
534define 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
542;
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
549entry:
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
570}
571; i8* p; i32 m;
572; p[0] = (m >> 8) & 0xFF;
573; p[1] = (m >> 0) & 0xFF;
574define 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
579;
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
584entry:
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
592}
593; i8* p; i32 m;
594; p[0] = (m >> 0) & 0xFF;
595; p[1] = (m >> 8) & 0xFF;
596define 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
601;
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
606entry:
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
614}
615; This was found when testing the hexxagon in testsuite
616; i8* p; i8 v;
617; p[0] = v;
618; p[1] = v;
619define 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
625;
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
631entry:
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
636}
637