1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64--    | FileCheck %s --check-prefixes=CHECK,LE
3; RUN: llc < %s -mtriple=aarch64_be-- | FileCheck %s --check-prefixes=CHECK,BE
4
5define void @le_i16_to_i8(i16 %x, i8* %p0) {
6; LE-LABEL: le_i16_to_i8:
7; LE:       // %bb.0:
8; LE-NEXT:    strh w0, [x1]
9; LE-NEXT:    ret
10;
11; BE-LABEL: le_i16_to_i8:
12; BE:       // %bb.0:
13; BE-NEXT:    rev w8, w0
14; BE-NEXT:    lsr w8, w8, #16
15; BE-NEXT:    strh w8, [x1]
16; BE-NEXT:    ret
17  %sh1 = lshr i16 %x, 8
18  %t0 = trunc i16 %x to i8
19  %t1 = trunc i16 %sh1 to i8
20  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
21  store i8 %t0, i8* %p0, align 1
22  store i8 %t1, i8* %p1, align 1
23  ret void
24}
25
26define void @le_i16_to_i8_order(i16 %x, i8* %p0) {
27; LE-LABEL: le_i16_to_i8_order:
28; LE:       // %bb.0:
29; LE-NEXT:    strh w0, [x1]
30; LE-NEXT:    ret
31;
32; BE-LABEL: le_i16_to_i8_order:
33; BE:       // %bb.0:
34; BE-NEXT:    rev w8, w0
35; BE-NEXT:    lsr w8, w8, #16
36; BE-NEXT:    strh w8, [x1]
37; BE-NEXT:    ret
38  %sh1 = lshr i16 %x, 8
39  %t0 = trunc i16 %x to i8
40  %t1 = trunc i16 %sh1 to i8
41  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
42  store i8 %t1, i8* %p1, align 1
43  store i8 %t0, i8* %p0, align 1
44  ret void
45}
46
47define void @be_i16_to_i8_offset(i16 %x, i8* %p0) {
48; LE-LABEL: be_i16_to_i8_offset:
49; LE:       // %bb.0:
50; LE-NEXT:    rev w8, w0
51; LE-NEXT:    lsr w8, w8, #16
52; LE-NEXT:    sturh w8, [x1, #11]
53; LE-NEXT:    ret
54;
55; BE-LABEL: be_i16_to_i8_offset:
56; BE:       // %bb.0:
57; BE-NEXT:    sturh w0, [x1, #11]
58; BE-NEXT:    ret
59  %sh1 = lshr i16 %x, 8
60  %t0 = trunc i16 %x to i8
61  %t1 = trunc i16 %sh1 to i8
62  %p11 = getelementptr inbounds i8, i8* %p0, i64 11
63  %p12 = getelementptr inbounds i8, i8* %p0, i64 12
64  store i8 %t0, i8* %p12, align 1
65  store i8 %t1, i8* %p11, align 1
66  ret void
67}
68
69define void @be_i16_to_i8_order(i16 %x, i8* %p0) {
70; LE-LABEL: be_i16_to_i8_order:
71; LE:       // %bb.0:
72; LE-NEXT:    rev w8, w0
73; LE-NEXT:    lsr w8, w8, #16
74; LE-NEXT:    strh w8, [x1]
75; LE-NEXT:    ret
76;
77; BE-LABEL: be_i16_to_i8_order:
78; BE:       // %bb.0:
79; BE-NEXT:    strh w0, [x1]
80; BE-NEXT:    ret
81  %sh1 = lshr i16 %x, 8
82  %t0 = trunc i16 %x to i8
83  %t1 = trunc i16 %sh1 to i8
84  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
85  store i8 %t1, i8* %p0, align 1
86  store i8 %t0, i8* %p1, align 1
87  ret void
88}
89
90define void @le_i32_to_i8(i32 %x, i8* %p0) {
91; LE-LABEL: le_i32_to_i8:
92; LE:       // %bb.0:
93; LE-NEXT:    str w0, [x1]
94; LE-NEXT:    ret
95;
96; BE-LABEL: le_i32_to_i8:
97; BE:       // %bb.0:
98; BE-NEXT:    rev w8, w0
99; BE-NEXT:    str w8, [x1]
100; BE-NEXT:    ret
101  %sh1 = lshr i32 %x, 8
102  %sh2 = lshr i32 %x, 16
103  %sh3 = lshr i32 %x, 24
104  %t0 = trunc i32 %x to i8
105  %t1 = trunc i32 %sh1 to i8
106  %t2 = trunc i32 %sh2 to i8
107  %t3 = trunc i32 %sh3 to i8
108  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
109  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
110  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
111  store i8 %t0, i8* %p0, align 1
112  store i8 %t1, i8* %p1, align 1
113  store i8 %t2, i8* %p2, align 1
114  store i8 %t3, i8* %p3, align 1
115  ret void
116}
117
118define void @le_i32_to_i8_order(i32 %x, i8* %p0) {
119; LE-LABEL: le_i32_to_i8_order:
120; LE:       // %bb.0:
121; LE-NEXT:    str w0, [x1]
122; LE-NEXT:    ret
123;
124; BE-LABEL: le_i32_to_i8_order:
125; BE:       // %bb.0:
126; BE-NEXT:    rev w8, w0
127; BE-NEXT:    str w8, [x1]
128; BE-NEXT:    ret
129  %sh1 = lshr i32 %x, 8
130  %sh2 = lshr i32 %x, 16
131  %sh3 = lshr i32 %x, 24
132  %t0 = trunc i32 %x to i8
133  %t1 = trunc i32 %sh1 to i8
134  %t2 = trunc i32 %sh2 to i8
135  %t3 = trunc i32 %sh3 to i8
136  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
137  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
138  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
139  store i8 %t3, i8* %p3, align 1
140  store i8 %t1, i8* %p1, align 1
141  store i8 %t0, i8* %p0, align 1
142  store i8 %t2, i8* %p2, align 1
143  ret void
144}
145
146define void @be_i32_to_i8(i32 %x, i8* %p0) {
147; LE-LABEL: be_i32_to_i8:
148; LE:       // %bb.0:
149; LE-NEXT:    rev w8, w0
150; LE-NEXT:    str w8, [x1]
151; LE-NEXT:    ret
152;
153; BE-LABEL: be_i32_to_i8:
154; BE:       // %bb.0:
155; BE-NEXT:    str w0, [x1]
156; BE-NEXT:    ret
157  %sh1 = lshr i32 %x, 8
158  %sh2 = lshr i32 %x, 16
159  %sh3 = lshr i32 %x, 24
160  %t0 = trunc i32 %x to i8
161  %t1 = trunc i32 %sh1 to i8
162  %t2 = trunc i32 %sh2 to i8
163  %t3 = trunc i32 %sh3 to i8
164  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
165  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
166  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
167  store i8 %t0, i8* %p3, align 1
168  store i8 %t1, i8* %p2, align 1
169  store i8 %t2, i8* %p1, align 1
170  store i8 %t3, i8* %p0, align 1
171  ret void
172}
173
174define void @be_i32_to_i8_order(i32 %x, i8* %p0) {
175; LE-LABEL: be_i32_to_i8_order:
176; LE:       // %bb.0:
177; LE-NEXT:    rev w8, w0
178; LE-NEXT:    str w8, [x1]
179; LE-NEXT:    ret
180;
181; BE-LABEL: be_i32_to_i8_order:
182; BE:       // %bb.0:
183; BE-NEXT:    str w0, [x1]
184; BE-NEXT:    ret
185  %sh1 = lshr i32 %x, 8
186  %sh2 = lshr i32 %x, 16
187  %sh3 = lshr i32 %x, 24
188  %t0 = trunc i32 %x to i8
189  %t1 = trunc i32 %sh1 to i8
190  %t2 = trunc i32 %sh2 to i8
191  %t3 = trunc i32 %sh3 to i8
192  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
193  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
194  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
195  store i8 %t3, i8* %p0, align 1
196  store i8 %t2, i8* %p1, align 1
197  store i8 %t0, i8* %p3, align 1
198  store i8 %t1, i8* %p2, align 1
199  ret void
200}
201
202define void @le_i32_to_i16(i32 %x, i16* %p0) {
203; LE-LABEL: le_i32_to_i16:
204; LE:       // %bb.0:
205; LE-NEXT:    str w0, [x1]
206; LE-NEXT:    ret
207;
208; BE-LABEL: le_i32_to_i16:
209; BE:       // %bb.0:
210; BE-NEXT:    ror w8, w0, #16
211; BE-NEXT:    str w8, [x1]
212; BE-NEXT:    ret
213  %sh1 = lshr i32 %x, 16
214  %t0 = trunc i32 %x to i16
215  %t1 = trunc i32 %sh1 to i16
216  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
217  store i16 %t0, i16* %p0, align 2
218  store i16 %t1, i16* %p1, align 2
219  ret void
220}
221
222define void @le_i32_to_i16_order(i32 %x, i16* %p0) {
223; LE-LABEL: le_i32_to_i16_order:
224; LE:       // %bb.0:
225; LE-NEXT:    str w0, [x1]
226; LE-NEXT:    ret
227;
228; BE-LABEL: le_i32_to_i16_order:
229; BE:       // %bb.0:
230; BE-NEXT:    ror w8, w0, #16
231; BE-NEXT:    str w8, [x1]
232; BE-NEXT:    ret
233  %sh1 = lshr i32 %x, 16
234  %t0 = trunc i32 %x to i16
235  %t1 = trunc i32 %sh1 to i16
236  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
237  store i16 %t1, i16* %p1, align 2
238  store i16 %t0, i16* %p0, align 2
239  ret void
240}
241
242define void @be_i32_to_i16(i32 %x, i16* %p0) {
243; LE-LABEL: be_i32_to_i16:
244; LE:       // %bb.0:
245; LE-NEXT:    ror w8, w0, #16
246; LE-NEXT:    str w8, [x1]
247; LE-NEXT:    ret
248;
249; BE-LABEL: be_i32_to_i16:
250; BE:       // %bb.0:
251; BE-NEXT:    str w0, [x1]
252; BE-NEXT:    ret
253  %sh1 = lshr i32 %x, 16
254  %t0 = trunc i32 %x to i16
255  %t1 = trunc i32 %sh1 to i16
256  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
257  store i16 %t0, i16* %p1, align 2
258  store i16 %t1, i16* %p0, align 2
259  ret void
260}
261
262define void @be_i32_to_i16_order(i32 %x, i16* %p0) {
263; LE-LABEL: be_i32_to_i16_order:
264; LE:       // %bb.0:
265; LE-NEXT:    ror w8, w0, #16
266; LE-NEXT:    str w8, [x1]
267; LE-NEXT:    ret
268;
269; BE-LABEL: be_i32_to_i16_order:
270; BE:       // %bb.0:
271; BE-NEXT:    str w0, [x1]
272; BE-NEXT:    ret
273  %sh1 = lshr i32 %x, 16
274  %t0 = trunc i32 %x to i16
275  %t1 = trunc i32 %sh1 to i16
276  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
277  store i16 %t1, i16* %p0, align 2
278  store i16 %t0, i16* %p1, align 2
279  ret void
280}
281
282define void @le_i64_to_i8(i64 %x, i8* %p0) {
283; LE-LABEL: le_i64_to_i8:
284; LE:       // %bb.0:
285; LE-NEXT:    str x0, [x1]
286; LE-NEXT:    ret
287;
288; BE-LABEL: le_i64_to_i8:
289; BE:       // %bb.0:
290; BE-NEXT:    rev x8, x0
291; BE-NEXT:    str x8, [x1]
292; BE-NEXT:    ret
293  %sh1 = lshr i64 %x, 8
294  %sh2 = lshr i64 %x, 16
295  %sh3 = lshr i64 %x, 24
296  %sh4 = lshr i64 %x, 32
297  %sh5 = lshr i64 %x, 40
298  %sh6 = lshr i64 %x, 48
299  %sh7 = lshr i64 %x, 56
300  %t0 = trunc i64 %x to i8
301  %t1 = trunc i64 %sh1 to i8
302  %t2 = trunc i64 %sh2 to i8
303  %t3 = trunc i64 %sh3 to i8
304  %t4 = trunc i64 %sh4 to i8
305  %t5 = trunc i64 %sh5 to i8
306  %t6 = trunc i64 %sh6 to i8
307  %t7 = trunc i64 %sh7 to i8
308  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
309  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
310  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
311  %p4 = getelementptr inbounds i8, i8* %p0, i64 4
312  %p5 = getelementptr inbounds i8, i8* %p0, i64 5
313  %p6 = getelementptr inbounds i8, i8* %p0, i64 6
314  %p7 = getelementptr inbounds i8, i8* %p0, i64 7
315  store i8 %t0, i8* %p0, align 1
316  store i8 %t1, i8* %p1, align 1
317  store i8 %t2, i8* %p2, align 1
318  store i8 %t3, i8* %p3, align 1
319  store i8 %t4, i8* %p4, align 1
320  store i8 %t5, i8* %p5, align 1
321  store i8 %t6, i8* %p6, align 1
322  store i8 %t7, i8* %p7, align 1
323  ret void
324}
325
326define void @le_i64_to_i8_order(i64 %x, i8* %p0) {
327; LE-LABEL: le_i64_to_i8_order:
328; LE:       // %bb.0:
329; LE-NEXT:    str x0, [x1]
330; LE-NEXT:    ret
331;
332; BE-LABEL: le_i64_to_i8_order:
333; BE:       // %bb.0:
334; BE-NEXT:    rev x8, x0
335; BE-NEXT:    str x8, [x1]
336; BE-NEXT:    ret
337  %sh1 = lshr i64 %x, 8
338  %sh2 = lshr i64 %x, 16
339  %sh3 = lshr i64 %x, 24
340  %sh4 = lshr i64 %x, 32
341  %sh5 = lshr i64 %x, 40
342  %sh6 = lshr i64 %x, 48
343  %sh7 = lshr i64 %x, 56
344  %t0 = trunc i64 %x to i8
345  %t1 = trunc i64 %sh1 to i8
346  %t2 = trunc i64 %sh2 to i8
347  %t3 = trunc i64 %sh3 to i8
348  %t4 = trunc i64 %sh4 to i8
349  %t5 = trunc i64 %sh5 to i8
350  %t6 = trunc i64 %sh6 to i8
351  %t7 = trunc i64 %sh7 to i8
352  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
353  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
354  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
355  %p4 = getelementptr inbounds i8, i8* %p0, i64 4
356  %p5 = getelementptr inbounds i8, i8* %p0, i64 5
357  %p6 = getelementptr inbounds i8, i8* %p0, i64 6
358  %p7 = getelementptr inbounds i8, i8* %p0, i64 7
359  store i8 %t5, i8* %p5, align 1
360  store i8 %t0, i8* %p0, align 1
361  store i8 %t3, i8* %p3, align 1
362  store i8 %t7, i8* %p7, align 1
363  store i8 %t1, i8* %p1, align 1
364  store i8 %t6, i8* %p6, align 1
365  store i8 %t2, i8* %p2, align 1
366  store i8 %t4, i8* %p4, align 1
367  ret void
368}
369
370define void @be_i64_to_i8(i64 %x, i8* %p0) {
371; LE-LABEL: be_i64_to_i8:
372; LE:       // %bb.0:
373; LE-NEXT:    rev x8, x0
374; LE-NEXT:    str x8, [x1]
375; LE-NEXT:    ret
376;
377; BE-LABEL: be_i64_to_i8:
378; BE:       // %bb.0:
379; BE-NEXT:    str x0, [x1]
380; BE-NEXT:    ret
381  %sh1 = lshr i64 %x, 8
382  %sh2 = lshr i64 %x, 16
383  %sh3 = lshr i64 %x, 24
384  %sh4 = lshr i64 %x, 32
385  %sh5 = lshr i64 %x, 40
386  %sh6 = lshr i64 %x, 48
387  %sh7 = lshr i64 %x, 56
388  %t0 = trunc i64 %x to i8
389  %t1 = trunc i64 %sh1 to i8
390  %t2 = trunc i64 %sh2 to i8
391  %t3 = trunc i64 %sh3 to i8
392  %t4 = trunc i64 %sh4 to i8
393  %t5 = trunc i64 %sh5 to i8
394  %t6 = trunc i64 %sh6 to i8
395  %t7 = trunc i64 %sh7 to i8
396  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
397  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
398  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
399  %p4 = getelementptr inbounds i8, i8* %p0, i64 4
400  %p5 = getelementptr inbounds i8, i8* %p0, i64 5
401  %p6 = getelementptr inbounds i8, i8* %p0, i64 6
402  %p7 = getelementptr inbounds i8, i8* %p0, i64 7
403  store i8 %t0, i8* %p7, align 1
404  store i8 %t1, i8* %p6, align 1
405  store i8 %t2, i8* %p5, align 1
406  store i8 %t3, i8* %p4, align 1
407  store i8 %t4, i8* %p3, align 1
408  store i8 %t5, i8* %p2, align 1
409  store i8 %t6, i8* %p1, align 1
410  store i8 %t7, i8* %p0, align 1
411  ret void
412}
413
414define void @be_i64_to_i8_order(i64 %x, i8* %p0) {
415; LE-LABEL: be_i64_to_i8_order:
416; LE:       // %bb.0:
417; LE-NEXT:    rev x8, x0
418; LE-NEXT:    str x8, [x1]
419; LE-NEXT:    ret
420;
421; BE-LABEL: be_i64_to_i8_order:
422; BE:       // %bb.0:
423; BE-NEXT:    str x0, [x1]
424; BE-NEXT:    ret
425  %sh1 = lshr i64 %x, 8
426  %sh2 = lshr i64 %x, 16
427  %sh3 = lshr i64 %x, 24
428  %sh4 = lshr i64 %x, 32
429  %sh5 = lshr i64 %x, 40
430  %sh6 = lshr i64 %x, 48
431  %sh7 = lshr i64 %x, 56
432  %t0 = trunc i64 %x to i8
433  %t1 = trunc i64 %sh1 to i8
434  %t2 = trunc i64 %sh2 to i8
435  %t3 = trunc i64 %sh3 to i8
436  %t4 = trunc i64 %sh4 to i8
437  %t5 = trunc i64 %sh5 to i8
438  %t6 = trunc i64 %sh6 to i8
439  %t7 = trunc i64 %sh7 to i8
440  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
441  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
442  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
443  %p4 = getelementptr inbounds i8, i8* %p0, i64 4
444  %p5 = getelementptr inbounds i8, i8* %p0, i64 5
445  %p6 = getelementptr inbounds i8, i8* %p0, i64 6
446  %p7 = getelementptr inbounds i8, i8* %p0, i64 7
447  store i8 %t7, i8* %p0, align 1
448  store i8 %t6, i8* %p1, align 1
449  store i8 %t5, i8* %p2, align 1
450  store i8 %t4, i8* %p3, align 1
451  store i8 %t3, i8* %p4, align 1
452  store i8 %t2, i8* %p5, align 1
453  store i8 %t1, i8* %p6, align 1
454  store i8 %t0, i8* %p7, align 1
455  ret void
456}
457
458define void @le_i64_to_i16(i64 %x, i16* %p0) {
459; LE-LABEL: le_i64_to_i16:
460; LE:       // %bb.0:
461; LE-NEXT:    str x0, [x1]
462; LE-NEXT:    ret
463;
464; BE-LABEL: le_i64_to_i16:
465; BE:       // %bb.0:
466; BE-NEXT:    lsr x8, x0, #16
467; BE-NEXT:    lsr x9, x0, #32
468; BE-NEXT:    lsr x10, x0, #48
469; BE-NEXT:    strh w0, [x1]
470; BE-NEXT:    strh w8, [x1, #2]
471; BE-NEXT:    strh w9, [x1, #4]
472; BE-NEXT:    strh w10, [x1, #6]
473; BE-NEXT:    ret
474  %sh1 = lshr i64 %x, 16
475  %sh2 = lshr i64 %x, 32
476  %sh3 = lshr i64 %x, 48
477  %t0 = trunc i64 %x to i16
478  %t1 = trunc i64 %sh1 to i16
479  %t2 = trunc i64 %sh2 to i16
480  %t3 = trunc i64 %sh3 to i16
481  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
482  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
483  %p3 = getelementptr inbounds i16, i16* %p0, i64 3
484  store i16 %t0, i16* %p0, align 2
485  store i16 %t1, i16* %p1, align 2
486  store i16 %t2, i16* %p2, align 2
487  store i16 %t3, i16* %p3, align 2
488  ret void
489}
490
491define void @le_i64_to_i16_order(i64 %x, i16* %p0) {
492; LE-LABEL: le_i64_to_i16_order:
493; LE:       // %bb.0:
494; LE-NEXT:    str x0, [x1]
495; LE-NEXT:    ret
496;
497; BE-LABEL: le_i64_to_i16_order:
498; BE:       // %bb.0:
499; BE-NEXT:    lsr x8, x0, #16
500; BE-NEXT:    lsr x9, x0, #32
501; BE-NEXT:    lsr x10, x0, #48
502; BE-NEXT:    strh w0, [x1]
503; BE-NEXT:    strh w8, [x1, #2]
504; BE-NEXT:    strh w10, [x1, #6]
505; BE-NEXT:    strh w9, [x1, #4]
506; BE-NEXT:    ret
507  %sh1 = lshr i64 %x, 16
508  %sh2 = lshr i64 %x, 32
509  %sh3 = lshr i64 %x, 48
510  %t0 = trunc i64 %x to i16
511  %t1 = trunc i64 %sh1 to i16
512  %t2 = trunc i64 %sh2 to i16
513  %t3 = trunc i64 %sh3 to i16
514  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
515  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
516  %p3 = getelementptr inbounds i16, i16* %p0, i64 3
517  store i16 %t1, i16* %p1, align 2
518  store i16 %t3, i16* %p3, align 2
519  store i16 %t0, i16* %p0, align 2
520  store i16 %t2, i16* %p2, align 2
521  ret void
522}
523
524define void @be_i64_to_i16(i64 %x, i16* %p0) {
525; LE-LABEL: be_i64_to_i16:
526; LE:       // %bb.0:
527; LE-NEXT:    lsr x8, x0, #32
528; LE-NEXT:    lsr x9, x0, #48
529; LE-NEXT:    ror w10, w0, #16
530; LE-NEXT:    str w10, [x1, #4]
531; LE-NEXT:    strh w8, [x1, #2]
532; LE-NEXT:    strh w9, [x1]
533; LE-NEXT:    ret
534;
535; BE-LABEL: be_i64_to_i16:
536; BE:       // %bb.0:
537; BE-NEXT:    str x0, [x1]
538; BE-NEXT:    ret
539  %sh1 = lshr i64 %x, 16
540  %sh2 = lshr i64 %x, 32
541  %sh3 = lshr i64 %x, 48
542  %t0 = trunc i64 %x to i16
543  %t1 = trunc i64 %sh1 to i16
544  %t2 = trunc i64 %sh2 to i16
545  %t3 = trunc i64 %sh3 to i16
546  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
547  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
548  %p3 = getelementptr inbounds i16, i16* %p0, i64 3
549  store i16 %t0, i16* %p3, align 2
550  store i16 %t1, i16* %p2, align 2
551  store i16 %t2, i16* %p1, align 2
552  store i16 %t3, i16* %p0, align 2
553  ret void
554}
555
556define void @be_i64_to_i16_order(i64 %x, i16* %p0) {
557; LE-LABEL: be_i64_to_i16_order:
558; LE:       // %bb.0:
559; LE-NEXT:    lsr x8, x0, #16
560; LE-NEXT:    lsr x9, x0, #32
561; LE-NEXT:    lsr x10, x0, #48
562; LE-NEXT:    strh w0, [x1, #6]
563; LE-NEXT:    strh w10, [x1]
564; LE-NEXT:    strh w9, [x1, #2]
565; LE-NEXT:    strh w8, [x1, #4]
566; LE-NEXT:    ret
567;
568; BE-LABEL: be_i64_to_i16_order:
569; BE:       // %bb.0:
570; BE-NEXT:    str x0, [x1]
571; BE-NEXT:    ret
572  %sh1 = lshr i64 %x, 16
573  %sh2 = lshr i64 %x, 32
574  %sh3 = lshr i64 %x, 48
575  %t0 = trunc i64 %x to i16
576  %t1 = trunc i64 %sh1 to i16
577  %t2 = trunc i64 %sh2 to i16
578  %t3 = trunc i64 %sh3 to i16
579  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
580  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
581  %p3 = getelementptr inbounds i16, i16* %p0, i64 3
582  store i16 %t0, i16* %p3, align 2
583  store i16 %t3, i16* %p0, align 2
584  store i16 %t2, i16* %p1, align 2
585  store i16 %t1, i16* %p2, align 2
586  ret void
587}
588
589define void @le_i64_to_i32(i64 %x, i32* %p0) {
590; LE-LABEL: le_i64_to_i32:
591; LE:       // %bb.0:
592; LE-NEXT:    str x0, [x1]
593; LE-NEXT:    ret
594;
595; BE-LABEL: le_i64_to_i32:
596; BE:       // %bb.0:
597; BE-NEXT:    ror x8, x0, #32
598; BE-NEXT:    str x8, [x1]
599; BE-NEXT:    ret
600  %sh1 = lshr i64 %x, 32
601  %t0 = trunc i64 %x to i32
602  %t1 = trunc i64 %sh1 to i32
603  %p1 = getelementptr inbounds i32, i32* %p0, i64 1
604  store i32 %t0, i32* %p0, align 4
605  store i32 %t1, i32* %p1, align 4
606  ret void
607}
608
609define void @le_i64_to_i32_order(i64 %x, i32* %p0) {
610; LE-LABEL: le_i64_to_i32_order:
611; LE:       // %bb.0:
612; LE-NEXT:    str x0, [x1]
613; LE-NEXT:    ret
614;
615; BE-LABEL: le_i64_to_i32_order:
616; BE:       // %bb.0:
617; BE-NEXT:    ror x8, x0, #32
618; BE-NEXT:    str x8, [x1]
619; BE-NEXT:    ret
620  %sh1 = lshr i64 %x, 32
621  %t0 = trunc i64 %x to i32
622  %t1 = trunc i64 %sh1 to i32
623  %p1 = getelementptr inbounds i32, i32* %p0, i64 1
624  store i32 %t1, i32* %p1, align 4
625  store i32 %t0, i32* %p0, align 4
626  ret void
627}
628
629define void @be_i64_to_i32(i64 %x, i32* %p0) {
630; LE-LABEL: be_i64_to_i32:
631; LE:       // %bb.0:
632; LE-NEXT:    ror x8, x0, #32
633; LE-NEXT:    str x8, [x1]
634; LE-NEXT:    ret
635;
636; BE-LABEL: be_i64_to_i32:
637; BE:       // %bb.0:
638; BE-NEXT:    str x0, [x1]
639; BE-NEXT:    ret
640  %sh1 = lshr i64 %x, 32
641  %t0 = trunc i64 %x to i32
642  %t1 = trunc i64 %sh1 to i32
643  %p1 = getelementptr inbounds i32, i32* %p0, i64 1
644  store i32 %t0, i32* %p1, align 4
645  store i32 %t1, i32* %p0, align 4
646  ret void
647}
648
649define void @be_i64_to_i32_order(i64 %x, i32* %p0) {
650; LE-LABEL: be_i64_to_i32_order:
651; LE:       // %bb.0:
652; LE-NEXT:    ror x8, x0, #32
653; LE-NEXT:    str x8, [x1]
654; LE-NEXT:    ret
655;
656; BE-LABEL: be_i64_to_i32_order:
657; BE:       // %bb.0:
658; BE-NEXT:    str x0, [x1]
659; BE-NEXT:    ret
660  %sh1 = lshr i64 %x, 32
661  %t0 = trunc i64 %x to i32
662  %t1 = trunc i64 %sh1 to i32
663  %p1 = getelementptr inbounds i32, i32* %p0, i64 1
664  store i32 %t1, i32* %p0, align 4
665  store i32 %t0, i32* %p1, align 4
666  ret void
667}
668
669; Negative test - not consecutive addresses
670
671define void @i64_to_i32_wrong_addr(i64 %x, i32* %p0) {
672; CHECK-LABEL: i64_to_i32_wrong_addr:
673; CHECK:       // %bb.0:
674; CHECK-NEXT:    lsr x8, x0, #32
675; CHECK-NEXT:    str w8, [x1, #12]
676; CHECK-NEXT:    str w0, [x1]
677; CHECK-NEXT:    ret
678  %sh1 = lshr i64 %x, 32
679  %t0 = trunc i64 %x to i32
680  %t1 = trunc i64 %sh1 to i32
681  %p3 = getelementptr inbounds i32, i32* %p0, i64 3
682  store i32 %t1, i32* %p3, align 4
683  store i32 %t0, i32* %p0, align 4
684  ret void
685}
686
687; Negative test - addresses don't line up with shift amounts
688
689define void @i64_to_i16_wrong_order(i64 %x, i16* %p0) {
690; CHECK-LABEL: i64_to_i16_wrong_order:
691; CHECK:       // %bb.0:
692; CHECK-NEXT:    lsr x8, x0, #16
693; CHECK-NEXT:    lsr x9, x0, #32
694; CHECK-NEXT:    lsr x10, x0, #48
695; CHECK-NEXT:    strh w10, [x1, #6]
696; CHECK-NEXT:    strh w8, [x1, #4]
697; CHECK-NEXT:    strh w9, [x1, #2]
698; CHECK-NEXT:    strh w0, [x1]
699; CHECK-NEXT:    ret
700  %sh1 = lshr i64 %x, 16
701  %sh2 = lshr i64 %x, 32
702  %sh3 = lshr i64 %x, 48
703  %t0 = trunc i64 %x to i16
704  %t1 = trunc i64 %sh1 to i16
705  %t2 = trunc i64 %sh2 to i16
706  %t3 = trunc i64 %sh3 to i16
707  %p1 = getelementptr inbounds i16, i16* %p0, i64 1
708  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
709  %p3 = getelementptr inbounds i16, i16* %p0, i64 3
710  store i16 %t3, i16* %p3, align 2
711  store i16 %t1, i16* %p2, align 2
712  store i16 %t2, i16* %p1, align 2
713  store i16 %t0, i16* %p0, align 2
714  ret void
715}
716
717; Negative test - no store of 't1'
718
719define void @i32_to_i8_incomplete(i32 %x, i8* %p0) {
720; CHECK-LABEL: i32_to_i8_incomplete:
721; CHECK:       // %bb.0:
722; CHECK-NEXT:    lsr w8, w0, #16
723; CHECK-NEXT:    lsr w9, w0, #24
724; CHECK-NEXT:    strb w0, [x1]
725; CHECK-NEXT:    strb w8, [x1, #2]
726; CHECK-NEXT:    strb w9, [x1, #3]
727; CHECK-NEXT:    ret
728  %sh1 = lshr i32 %x, 8
729  %sh2 = lshr i32 %x, 16
730  %sh3 = lshr i32 %x, 24
731  %t0 = trunc i32 %x to i8
732  %t1 = trunc i32 %sh1 to i8
733  %t2 = trunc i32 %sh2 to i8
734  %t3 = trunc i32 %sh3 to i8
735  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
736  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
737  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
738  store i8 %t0, i8* %p0, align 1
739  store i8 %t2, i8* %p2, align 1
740  store i8 %t3, i8* %p3, align 1
741  ret void
742}
743
744; Negative test - no store of 't3'
745
746define void @i64_to_i8_incomplete(i64 %x, i8* %p0) {
747; CHECK-LABEL: i64_to_i8_incomplete:
748; CHECK:       // %bb.0:
749; CHECK-NEXT:    lsr x8, x0, #8
750; CHECK-NEXT:    lsr x9, x0, #16
751; CHECK-NEXT:    lsr x10, x0, #32
752; CHECK-NEXT:    lsr x11, x0, #40
753; CHECK-NEXT:    lsr x12, x0, #48
754; CHECK-NEXT:    lsr x13, x0, #56
755; CHECK-NEXT:    strb w13, [x1]
756; CHECK-NEXT:    strb w12, [x1, #1]
757; CHECK-NEXT:    strb w11, [x1, #2]
758; CHECK-NEXT:    strb w10, [x1, #3]
759; CHECK-NEXT:    strb w9, [x1, #5]
760; CHECK-NEXT:    strb w8, [x1, #6]
761; CHECK-NEXT:    strb w0, [x1, #7]
762; CHECK-NEXT:    ret
763  %sh1 = lshr i64 %x, 8
764  %sh2 = lshr i64 %x, 16
765  %sh3 = lshr i64 %x, 24
766  %sh4 = lshr i64 %x, 32
767  %sh5 = lshr i64 %x, 40
768  %sh6 = lshr i64 %x, 48
769  %sh7 = lshr i64 %x, 56
770  %t0 = trunc i64 %x to i8
771  %t1 = trunc i64 %sh1 to i8
772  %t2 = trunc i64 %sh2 to i8
773  %t3 = trunc i64 %sh3 to i8
774  %t4 = trunc i64 %sh4 to i8
775  %t5 = trunc i64 %sh5 to i8
776  %t6 = trunc i64 %sh6 to i8
777  %t7 = trunc i64 %sh7 to i8
778  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
779  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
780  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
781  %p4 = getelementptr inbounds i8, i8* %p0, i64 4
782  %p5 = getelementptr inbounds i8, i8* %p0, i64 5
783  %p6 = getelementptr inbounds i8, i8* %p0, i64 6
784  %p7 = getelementptr inbounds i8, i8* %p0, i64 7
785  store i8 %t7, i8* %p0, align 1
786  store i8 %t6, i8* %p1, align 1
787  store i8 %t5, i8* %p2, align 1
788  store i8 %t4, i8* %p3, align 1
789  store i8 %t2, i8* %p5, align 1
790  store i8 %t1, i8* %p6, align 1
791  store i8 %t0, i8* %p7, align 1
792  ret void
793}
794
795; Negative test - not consecutive addresses
796
797define void @i32_to_i16_wrong_addr(i32 %x, i16* %p0) {
798; CHECK-LABEL: i32_to_i16_wrong_addr:
799; CHECK:       // %bb.0:
800; CHECK-NEXT:    lsr w8, w0, #16
801; CHECK-NEXT:    strh w8, [x1, #4]
802; CHECK-NEXT:    strh w0, [x1]
803; CHECK-NEXT:    ret
804  %sh1 = lshr i32 %x, 16
805  %t0 = trunc i32 %x to i16
806  %t1 = trunc i32 %sh1 to i16
807  %p2 = getelementptr inbounds i16, i16* %p0, i64 2
808  store i16 %t1, i16* %p2, align 2
809  store i16 %t0, i16* %p0, align 2
810  ret void
811}
812
813; Negative test - addresses don't line up with shift amounts
814
815define void @i32_to_i8_wrong_order(i32 %x, i8* %p0) {
816; CHECK-LABEL: i32_to_i8_wrong_order:
817; CHECK:       // %bb.0:
818; CHECK-NEXT:    lsr w8, w0, #8
819; CHECK-NEXT:    lsr w9, w0, #16
820; CHECK-NEXT:    lsr w10, w0, #24
821; CHECK-NEXT:    strb w0, [x1, #3]
822; CHECK-NEXT:    strb w10, [x1, #1]
823; CHECK-NEXT:    strb w9, [x1]
824; CHECK-NEXT:    strb w8, [x1, #2]
825; CHECK-NEXT:    ret
826  %sh1 = lshr i32 %x, 8
827  %sh2 = lshr i32 %x, 16
828  %sh3 = lshr i32 %x, 24
829  %t0 = trunc i32 %x to i8
830  %t1 = trunc i32 %sh1 to i8
831  %t2 = trunc i32 %sh2 to i8
832  %t3 = trunc i32 %sh3 to i8
833  %p1 = getelementptr inbounds i8, i8* %p0, i64 1
834  %p2 = getelementptr inbounds i8, i8* %p0, i64 2
835  %p3 = getelementptr inbounds i8, i8* %p0, i64 3
836  store i8 %t3, i8* %p1, align 1
837  store i8 %t2, i8* %p0, align 1
838  store i8 %t0, i8* %p3, align 1
839  store i8 %t1, i8* %p2, align 1
840  ret void
841}
842