[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / trunc-to-tbl.ll
blob9650a9b121654bc81bd87fc3f54ed6e0a6b960a5
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=arm64-apple-ios -o - %s | FileCheck %s
3 ; RUN: llc -mtriple=aarch64_be-unknown-linux -o - %s | FileCheck --check-prefix=CHECK-BE %s
5 ; CHECK-LABEL: lCPI0_0:
6 ; CHECK-NEXT:   .byte   0                               ; 0x0
7 ; CHECK-NEXT:   .byte   4                               ; 0x4
8 ; CHECK-NEXT:   .byte   8                               ; 0x8
9 ; CHECK-NEXT:   .byte   12                              ; 0xc
10 ; CHECK-NEXT:   .byte   16                              ; 0x10
11 ; CHECK-NEXT:   .byte   20                              ; 0x14
12 ; CHECK-NEXT:   .byte   24                              ; 0x18
13 ; CHECK-NEXT:   .byte   28                              ; 0x1c
14 ; CHECK-NEXT:   .byte   32                              ; 0x20
15 ; CHECK-NEXT:   .byte   36                              ; 0x24
16 ; CHECK-NEXT:   .byte   40                              ; 0x28
17 ; CHECK-NEXT:   .byte   44                              ; 0x2c
18 ; CHECK-NEXT:   .byte   48                              ; 0x30
19 ; CHECK-NEXT:   .byte   52                              ; 0x34
20 ; CHECK-NEXT:   .byte   56                              ; 0x38
21 ; CHECK-NEXT:   .byte   60                              ; 0x3c
23 ; CHECK-BE-LABEL:   .LCPI0_0:
24 ; CHECK-BE-NEXT:   .byte    3                               // 0x3
25 ; CHECK-BE-NEXT:   .byte    7                               // 0x7
26 ; CHECK-BE-NEXT:   .byte    11                              // 0xb
27 ; CHECK-BE-NEXT:   .byte    15                              // 0xf
28 ; CHECK-BE-NEXT:   .byte    19                              // 0x13
29 ; CHECK-BE-NEXT:   .byte    23                              // 0x17
30 ; CHECK-BE-NEXT:   .byte    27                              // 0x1b
31 ; CHECK-BE-NEXT:   .byte    31                              // 0x1f
32 ; CHECK-BE-NEXT:   .byte    35                              // 0x23
33 ; CHECK-BE-NEXT:   .byte    39                              // 0x27
34 ; CHECK-BE-NEXT:   .byte    43                              // 0x2b
35 ; CHECK-BE-NEXT:   .byte    47                              // 0x2f
36 ; CHECK-BE-NEXT:   .byte    51                              // 0x33
37 ; CHECK-BE-NEXT:   .byte    55                              // 0x37
38 ; CHECK-BE-NEXT:   .byte    59                              // 0x3b
39 ; CHECK-BE-NEXT:   .byte    63                              // 0x3f
41 ; It's profitable to use a single tbl.4 instruction to lower the truncate.
42 define void @trunc_v16i32_to_v16i8_in_loop(ptr %A, ptr %dst) {
43 ; CHECK-LABEL: trunc_v16i32_to_v16i8_in_loop:
44 ; CHECK:       ; %bb.0: ; %entry
45 ; CHECK-NEXT:  Lloh0:
46 ; CHECK-NEXT:    adrp x8, lCPI0_0@PAGE
47 ; CHECK-NEXT:  Lloh1:
48 ; CHECK-NEXT:    ldr q0, [x8, lCPI0_0@PAGEOFF]
49 ; CHECK-NEXT:    mov x8, xzr
50 ; CHECK-NEXT:  LBB0_1: ; %loop
51 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
52 ; CHECK-NEXT:    add x9, x0, x8, lsl #6
53 ; CHECK-NEXT:    ldp q1, q2, [x9]
54 ; CHECK-NEXT:    ldp q3, q4, [x9, #32]
55 ; CHECK-NEXT:    tbl.16b v1, { v1, v2, v3, v4 }, v0
56 ; CHECK-NEXT:    str q1, [x1, x8, lsl #4]
57 ; CHECK-NEXT:    add x8, x8, #1
58 ; CHECK-NEXT:    cmp x8, #1000
59 ; CHECK-NEXT:    b.eq LBB0_1
60 ; CHECK-NEXT:  ; %bb.2: ; %exit
61 ; CHECK-NEXT:    ret
62 ; CHECK-NEXT:    .loh AdrpLdr Lloh0, Lloh1
64 ; CHECK-BE-LABEL: trunc_v16i32_to_v16i8_in_loop:
65 ; CHECK-BE:       // %bb.0: // %entry
66 ; CHECK-BE-NEXT:    adrp x8, .LCPI0_0
67 ; CHECK-BE-NEXT:    add x8, x8, :lo12:.LCPI0_0
68 ; CHECK-BE-NEXT:    ld1 { v0.16b }, [x8]
69 ; CHECK-BE-NEXT:    mov x8, xzr
70 ; CHECK-BE-NEXT:  .LBB0_1: // %loop
71 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
72 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #6
73 ; CHECK-BE-NEXT:    add x10, x9, #16
74 ; CHECK-BE-NEXT:    ld1 { v1.16b }, [x9]
75 ; CHECK-BE-NEXT:    add x11, x9, #32
76 ; CHECK-BE-NEXT:    ld1 { v2.16b }, [x10]
77 ; CHECK-BE-NEXT:    add x9, x9, #48
78 ; CHECK-BE-NEXT:    ld1 { v3.16b }, [x11]
79 ; CHECK-BE-NEXT:    ld1 { v4.16b }, [x9]
80 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #4
81 ; CHECK-BE-NEXT:    add x8, x8, #1
82 ; CHECK-BE-NEXT:    cmp x8, #1000
83 ; CHECK-BE-NEXT:    tbl v1.16b, { v1.16b, v2.16b, v3.16b, v4.16b }, v0.16b
84 ; CHECK-BE-NEXT:    st1 { v1.16b }, [x9]
85 ; CHECK-BE-NEXT:    b.eq .LBB0_1
86 ; CHECK-BE-NEXT:  // %bb.2: // %exit
87 ; CHECK-BE-NEXT:    ret
89 entry:
90   br label %loop
92 loop:
93   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
94   %gep.A = getelementptr inbounds <16 x i32>, ptr %A, i64 %iv
95   %l.A = load <16 x i32>, ptr %gep.A
96   %trunc = trunc <16 x i32> %l.A to <16 x i8>
97   %gep.dst = getelementptr inbounds <16 x i8>, ptr %dst, i64 %iv
98   store <16 x i8> %trunc, ptr %gep.dst
99   %iv.next = add i64 %iv, 1
100   %ec = icmp eq i64 %iv.next, 1000
101   br i1 %ec, label %loop, label %exit
103 exit:
104   ret void
107 ; Not profitable to use tbl, as materializing the masks requires more
108 ; instructions.
109 define void @trunc_v16i32_to_v16i8_no_loop(ptr %A, ptr %dst) {
110 ; CHECK-LABEL: trunc_v16i32_to_v16i8_no_loop:
111 ; CHECK:       ; %bb.0: ; %entry
112 ; CHECK-NEXT:    ldp q1, q0, [x0]
113 ; CHECK-NEXT:    ldp q3, q2, [x0, #32]
114 ; CHECK-NEXT:    uzp1.8h v0, v1, v0
115 ; CHECK-NEXT:    uzp1.8h v2, v3, v2
116 ; CHECK-NEXT:    uzp1.16b v0, v0, v2
117 ; CHECK-NEXT:    str q0, [x1]
118 ; CHECK-NEXT:    ret
120 ; CHECK-BE-LABEL: trunc_v16i32_to_v16i8_no_loop:
121 ; CHECK-BE:       // %bb.0: // %entry
122 ; CHECK-BE-NEXT:    add x8, x0, #16
123 ; CHECK-BE-NEXT:    add x9, x0, #48
124 ; CHECK-BE-NEXT:    add x10, x0, #32
125 ; CHECK-BE-NEXT:    ld1 { v0.4s }, [x0]
126 ; CHECK-BE-NEXT:    ld1 { v1.4s }, [x8]
127 ; CHECK-BE-NEXT:    ld1 { v2.4s }, [x9]
128 ; CHECK-BE-NEXT:    ld1 { v3.4s }, [x10]
129 ; CHECK-BE-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
130 ; CHECK-BE-NEXT:    uzp1 v2.8h, v3.8h, v2.8h
131 ; CHECK-BE-NEXT:    uzp1 v0.16b, v0.16b, v2.16b
132 ; CHECK-BE-NEXT:    st1 { v0.16b }, [x1]
133 ; CHECK-BE-NEXT:    ret
134 entry:
135   %l.A = load <16 x i32>, ptr %A
136   %trunc = trunc <16 x i32> %l.A to <16 x i8>
137   store <16 x i8> %trunc, ptr %dst
138   ret void
142 ; CHECK-LABEL: lCPI2_0:
143 ; CHECK-NEXT:     .byte    0                               ; 0x0
144 ; CHECK-NEXT:     .byte    4                               ; 0x4
145 ; CHECK-NEXT:     .byte    8                               ; 0x8
146 ; CHECK-NEXT:     .byte    12                              ; 0xc
147 ; CHECK-NEXT:     .byte    16                              ; 0x10
148 ; CHECK-NEXT:     .byte    20                              ; 0x14
149 ; CHECK-NEXT:     .byte    24                              ; 0x18
150 ; CHECK-NEXT:     .byte    28                              ; 0x1c
151 ; CHECK-NEXT:     .byte    255                             ; 0xff
152 ; CHECK-NEXT:     .byte    255                             ; 0xff
153 ; CHECK-NEXT:     .byte    255                             ; 0xff
154 ; CHECK-NEXT:     .byte    255                             ; 0xff
155 ; CHECK-NEXT:     .byte    255                             ; 0xff
156 ; CHECK-NEXT:     .byte    255                             ; 0xff
157 ; CHECK-NEXT:     .byte    255                             ; 0xff
158 ; CHECK-NEXT:     .byte    255                             ; 0xff
160 ; CHECK-BE-LABEL: .LCPI2_0:
161 ; CHECK-BE-NEXT:     .byte    3                               // 0x3
162 ; CHECK-BE-NEXT:     .byte    7                               // 0x7
163 ; CHECK-BE-NEXT:     .byte    11                              // 0xb
164 ; CHECK-BE-NEXT:     .byte    15                              // 0xf
165 ; CHECK-BE-NEXT:     .byte    19                              // 0x13
166 ; CHECK-BE-NEXT:     .byte    23                              // 0x17
167 ; CHECK-BE-NEXT:     .byte    27                              // 0x1b
168 ; CHECK-BE-NEXT:     .byte    31                              // 0x1f
169 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
170 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
171 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
172 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
173 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
174 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
175 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
176 ; CHECK-BE-NEXT:     .byte    255                             // 0xff
177 ; It's profitable to use a single tbl.2 instruction to lower the truncate.
178 define void @trunc_v8i32_to_v8i8_in_loop(ptr %A, ptr %dst) {
179 ; CHECK-LABEL: trunc_v8i32_to_v8i8_in_loop:
180 ; CHECK:       ; %bb.0: ; %entry
181 ; CHECK-NEXT:  Lloh2:
182 ; CHECK-NEXT:    adrp x8, lCPI2_0@PAGE
183 ; CHECK-NEXT:  Lloh3:
184 ; CHECK-NEXT:    ldr q0, [x8, lCPI2_0@PAGEOFF]
185 ; CHECK-NEXT:    mov x8, xzr
186 ; CHECK-NEXT:  LBB2_1: ; %loop
187 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
188 ; CHECK-NEXT:    add x9, x0, x8, lsl #5
189 ; CHECK-NEXT:    ldp q1, q2, [x9]
190 ; CHECK-NEXT:    tbl.16b v1, { v1, v2 }, v0
191 ; CHECK-NEXT:    str d1, [x1, x8, lsl #3]
192 ; CHECK-NEXT:    add x8, x8, #1
193 ; CHECK-NEXT:    cmp x8, #1000
194 ; CHECK-NEXT:    b.eq LBB2_1
195 ; CHECK-NEXT:  ; %bb.2: ; %exit
196 ; CHECK-NEXT:    ret
197 ; CHECK-NEXT:    .loh AdrpLdr Lloh2, Lloh3
199 ; CHECK-BE-LABEL: trunc_v8i32_to_v8i8_in_loop:
200 ; CHECK-BE:       // %bb.0: // %entry
201 ; CHECK-BE-NEXT:    adrp x8, .LCPI2_0
202 ; CHECK-BE-NEXT:    add x8, x8, :lo12:.LCPI2_0
203 ; CHECK-BE-NEXT:    ld1 { v0.16b }, [x8]
204 ; CHECK-BE-NEXT:    mov x8, xzr
205 ; CHECK-BE-NEXT:  .LBB2_1: // %loop
206 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
207 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #5
208 ; CHECK-BE-NEXT:    add x10, x9, #16
209 ; CHECK-BE-NEXT:    ld1 { v1.16b }, [x9]
210 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #3
211 ; CHECK-BE-NEXT:    ld1 { v2.16b }, [x10]
212 ; CHECK-BE-NEXT:    add x8, x8, #1
213 ; CHECK-BE-NEXT:    cmp x8, #1000
214 ; CHECK-BE-NEXT:    tbl v1.16b, { v1.16b, v2.16b }, v0.16b
215 ; CHECK-BE-NEXT:    st1 { v1.8b }, [x9]
216 ; CHECK-BE-NEXT:    b.eq .LBB2_1
217 ; CHECK-BE-NEXT:  // %bb.2: // %exit
218 ; CHECK-BE-NEXT:    ret
220 entry:
221   br label %loop
223 loop:
224   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
225   %gep.A = getelementptr inbounds <8 x i32>, ptr %A, i64 %iv
226   %l.A = load <8 x i32>, ptr %gep.A
227   %trunc = trunc <8 x i32> %l.A to <8 x i8>
228   %gep.dst = getelementptr inbounds <8 x i8>, ptr %dst, i64 %iv
229   store <8 x i8> %trunc, ptr %gep.dst
230   %iv.next = add i64 %iv, 1
231   %ec = icmp eq i64 %iv.next, 1000
232   br i1 %ec, label %loop, label %exit
234 exit:
235   ret void
238 ; CHECK-LABEL:   lCPI3_0:
239 ; CHECK-NEXT:           .byte   0                               ; 0x0
240 ; CHECK-NEXT:           .byte   8                               ; 0x8
241 ; CHECK-NEXT:           .byte   16                              ; 0x10
242 ; CHECK-NEXT:           .byte   24                              ; 0x18
243 ; CHECK-NEXT:           .byte   32                              ; 0x20
244 ; CHECK-NEXT:           .byte   40                              ; 0x28
245 ; CHECK-NEXT:           .byte   48                              ; 0x30
246 ; CHECK-NEXT:           .byte   56                              ; 0x38
247 ; CHECK-NEXT:           .byte   64                              ; 0x40
248 ; CHECK-NEXT:           .byte   72                              ; 0x48
249 ; CHECK-NEXT:           .byte   80                              ; 0x50
250 ; CHECK-NEXT:           .byte   88                              ; 0x58
251 ; CHECK-NEXT:           .byte   96                              ; 0x60
252 ; CHECK-NEXT:           .byte   104                             ; 0x68
253 ; CHECK-NEXT:           .byte   112                             ; 0x70
254 ; CHECK-NEXT:           .byte   120                             ; 0x78
256 ; CHECK-BE-LABEL:    .LCPI3_0:
257 ; CHECK-BE-NEXT:        .byte   7                               // 0x7
258 ; CHECK-BE-NEXT:        .byte   15                              // 0xf
259 ; CHECK-BE-NEXT:        .byte   23                              // 0x17
260 ; CHECK-BE-NEXT:        .byte   31                              // 0x1f
261 ; CHECK-BE-NEXT:        .byte   39                              // 0x27
262 ; CHECK-BE-NEXT:        .byte   47                              // 0x2f
263 ; CHECK-BE-NEXT:        .byte   55                              // 0x37
264 ; CHECK-BE-NEXT:        .byte   63                              // 0x3f
265 ; CHECK-BE-NEXT:        .byte   71                              // 0x47
266 ; CHECK-BE-NEXT:        .byte   79                              // 0x4f
267 ; CHECK-BE-NEXT:        .byte   87                              // 0x57
268 ; CHECK-BE-NEXT:        .byte   95                              // 0x5f
269 ; CHECK-BE-NEXT:        .byte   103                             // 0x67
270 ; CHECK-BE-NEXT:        .byte   111                             // 0x6f
271 ; CHECK-BE-NEXT:        .byte   119                             // 0x77
272 ; CHECK-BE-NEXT:        .byte   127                             // 0x7f
273 define void @trunc_v16i64_to_v16i8_in_loop(ptr %A, ptr %dst) {
274 ; CHECK-LABEL: trunc_v16i64_to_v16i8_in_loop:
275 ; CHECK:       ; %bb.0: ; %entry
276 ; CHECK-NEXT:  Lloh4:
277 ; CHECK-NEXT:    adrp x8, lCPI3_0@PAGE
278 ; CHECK-NEXT:  Lloh5:
279 ; CHECK-NEXT:    ldr q0, [x8, lCPI3_0@PAGEOFF]
280 ; CHECK-NEXT:    mov x8, xzr
281 ; CHECK-NEXT:  LBB3_1: ; %loop
282 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
283 ; CHECK-NEXT:    add x9, x0, x8, lsl #7
284 ; CHECK-NEXT:    ldp q1, q2, [x9]
285 ; CHECK-NEXT:    ldp q16, q17, [x9, #64]
286 ; CHECK-NEXT:    ldp q3, q4, [x9, #32]
287 ; CHECK-NEXT:    ldp q18, q19, [x9, #96]
288 ; CHECK-NEXT:    tbl.16b v1, { v1, v2, v3, v4 }, v0
289 ; CHECK-NEXT:    tbl.16b v2, { v16, v17, v18, v19 }, v0
290 ; CHECK-NEXT:    mov.d v1[1], v2[0]
291 ; CHECK-NEXT:    str q1, [x1, x8, lsl #4]
292 ; CHECK-NEXT:    add x8, x8, #1
293 ; CHECK-NEXT:    cmp x8, #1000
294 ; CHECK-NEXT:    b.eq LBB3_1
295 ; CHECK-NEXT:  ; %bb.2: ; %exit
296 ; CHECK-NEXT:    ret
297 ; CHECK-NEXT:    .loh AdrpLdr Lloh4, Lloh5
299 ; CHECK-BE-LABEL: trunc_v16i64_to_v16i8_in_loop:
300 ; CHECK-BE:       // %bb.0: // %entry
301 ; CHECK-BE-NEXT:    adrp x8, .LCPI3_0
302 ; CHECK-BE-NEXT:    add x8, x8, :lo12:.LCPI3_0
303 ; CHECK-BE-NEXT:    ld1 { v0.16b }, [x8]
304 ; CHECK-BE-NEXT:    mov x8, xzr
305 ; CHECK-BE-NEXT:  .LBB3_1: // %loop
306 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
307 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #7
308 ; CHECK-BE-NEXT:    add x13, x9, #64
309 ; CHECK-BE-NEXT:    add x12, x9, #80
310 ; CHECK-BE-NEXT:    add x14, x9, #16
311 ; CHECK-BE-NEXT:    ld1 { v1.16b }, [x9]
312 ; CHECK-BE-NEXT:    ld1 { v16.16b }, [x13]
313 ; CHECK-BE-NEXT:    add x11, x9, #96
314 ; CHECK-BE-NEXT:    add x13, x9, #32
315 ; CHECK-BE-NEXT:    ld1 { v2.16b }, [x14]
316 ; CHECK-BE-NEXT:    ld1 { v17.16b }, [x12]
317 ; CHECK-BE-NEXT:    add x10, x9, #112
318 ; CHECK-BE-NEXT:    add x9, x9, #48
319 ; CHECK-BE-NEXT:    ld1 { v3.16b }, [x13]
320 ; CHECK-BE-NEXT:    ld1 { v18.16b }, [x11]
321 ; CHECK-BE-NEXT:    ld1 { v4.16b }, [x9]
322 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #4
323 ; CHECK-BE-NEXT:    ld1 { v19.16b }, [x10]
324 ; CHECK-BE-NEXT:    add x8, x8, #1
325 ; CHECK-BE-NEXT:    cmp x8, #1000
326 ; CHECK-BE-NEXT:    tbl v1.16b, { v1.16b, v2.16b, v3.16b, v4.16b }, v0.16b
327 ; CHECK-BE-NEXT:    tbl v2.16b, { v16.16b, v17.16b, v18.16b, v19.16b }, v0.16b
328 ; CHECK-BE-NEXT:    mov v1.d[1], v2.d[0]
329 ; CHECK-BE-NEXT:    st1 { v1.16b }, [x9]
330 ; CHECK-BE-NEXT:    b.eq .LBB3_1
331 ; CHECK-BE-NEXT:  // %bb.2: // %exit
332 ; CHECK-BE-NEXT:    ret
335 entry:
336   br label %loop
338 loop:
339   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
340   %gep.A = getelementptr inbounds <16 x i64>, ptr %A, i64 %iv
341   %l.A = load <16 x i64>, ptr %gep.A
342   %trunc = trunc <16 x i64> %l.A to <16 x i8>
343   %gep.dst = getelementptr inbounds <16 x i8>, ptr %dst, i64 %iv
344   store <16 x i8> %trunc, ptr %gep.dst
345   %iv.next = add i64 %iv, 1
346   %ec = icmp eq i64 %iv.next, 1000
347   br i1 %ec, label %loop, label %exit
349 exit:
350   ret void
353 ; CHECK-LABEL: lCPI4_0:
354 ; CHECK-NEXT:   .byte   0                               ; 0x0
355 ; CHECK-NEXT:   .byte   8                               ; 0x8
356 ; CHECK-NEXT:   .byte   16                              ; 0x10
357 ; CHECK-NEXT:   .byte   24                              ; 0x18
358 ; CHECK-NEXT:   .byte   32                              ; 0x20
359 ; CHECK-NEXT:   .byte   40                              ; 0x28
360 ; CHECK-NEXT:   .byte   48                              ; 0x30
361 ; CHECK-NEXT:   .byte   56                              ; 0x38
362 ; CHECK-NEXT:   .byte   255                             ; 0xff
363 ; CHECK-NEXT:   .byte   255                             ; 0xff
364 ; CHECK-NEXT:   .byte   255                             ; 0xff
365 ; CHECK-NEXT:   .byte   255                             ; 0xff
366 ; CHECK-NEXT:   .byte   255                             ; 0xff
367 ; CHECK-NEXT:   .byte   255                             ; 0xff
368 ; CHECK-NEXT:   .byte   255                             ; 0xff
369 ; CHECK-NEXT:   .byte   255                             ; 0xff
371 ; CHECK-BE-LABEL:   .LCPI4_0:
372 ; CHECK-BE-NEXT:        .byte   7                               // 0x7
373 ; CHECK-BE-NEXT:        .byte   15                              // 0xf
374 ; CHECK-BE-NEXT:        .byte   23                              // 0x17
375 ; CHECK-BE-NEXT:        .byte   31                              // 0x1f
376 ; CHECK-BE-NEXT:        .byte   39                              // 0x27
377 ; CHECK-BE-NEXT:        .byte   47                              // 0x2f
378 ; CHECK-BE-NEXT:        .byte   55                              // 0x37
379 ; CHECK-BE-NEXT:        .byte   63                              // 0x3f
380 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
381 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
382 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
383 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
384 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
385 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
386 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
387 ; CHECK-BE-NEXT:        .byte   255                             // 0xff
388 define void @trunc_v8i64_to_v8i8_in_loop(ptr %A, ptr %dst) {
389 ; CHECK-LABEL: trunc_v8i64_to_v8i8_in_loop:
390 ; CHECK:       ; %bb.0: ; %entry
391 ; CHECK-NEXT:  Lloh6:
392 ; CHECK-NEXT:    adrp x8, lCPI4_0@PAGE
393 ; CHECK-NEXT:  Lloh7:
394 ; CHECK-NEXT:    ldr q0, [x8, lCPI4_0@PAGEOFF]
395 ; CHECK-NEXT:    mov x8, xzr
396 ; CHECK-NEXT:  LBB4_1: ; %loop
397 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
398 ; CHECK-NEXT:    add x9, x0, x8, lsl #6
399 ; CHECK-NEXT:    ldp q1, q2, [x9]
400 ; CHECK-NEXT:    ldp q3, q4, [x9, #32]
401 ; CHECK-NEXT:    tbl.16b v1, { v1, v2, v3, v4 }, v0
402 ; CHECK-NEXT:    str d1, [x1, x8, lsl #3]
403 ; CHECK-NEXT:    add x8, x8, #1
404 ; CHECK-NEXT:    cmp x8, #1000
405 ; CHECK-NEXT:    b.eq LBB4_1
406 ; CHECK-NEXT:  ; %bb.2: ; %exit
407 ; CHECK-NEXT:    ret
408 ; CHECK-NEXT:    .loh AdrpLdr Lloh6, Lloh7
410 ; CHECK-BE-LABEL: trunc_v8i64_to_v8i8_in_loop:
411 ; CHECK-BE:       // %bb.0: // %entry
412 ; CHECK-BE-NEXT:    adrp x8, .LCPI4_0
413 ; CHECK-BE-NEXT:    add x8, x8, :lo12:.LCPI4_0
414 ; CHECK-BE-NEXT:    ld1 { v0.16b }, [x8]
415 ; CHECK-BE-NEXT:    mov x8, xzr
416 ; CHECK-BE-NEXT:  .LBB4_1: // %loop
417 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
418 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #6
419 ; CHECK-BE-NEXT:    add x10, x9, #16
420 ; CHECK-BE-NEXT:    ld1 { v1.16b }, [x9]
421 ; CHECK-BE-NEXT:    add x11, x9, #32
422 ; CHECK-BE-NEXT:    ld1 { v2.16b }, [x10]
423 ; CHECK-BE-NEXT:    add x9, x9, #48
424 ; CHECK-BE-NEXT:    ld1 { v3.16b }, [x11]
425 ; CHECK-BE-NEXT:    ld1 { v4.16b }, [x9]
426 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #3
427 ; CHECK-BE-NEXT:    add x8, x8, #1
428 ; CHECK-BE-NEXT:    cmp x8, #1000
429 ; CHECK-BE-NEXT:    tbl v1.16b, { v1.16b, v2.16b, v3.16b, v4.16b }, v0.16b
430 ; CHECK-BE-NEXT:    st1 { v1.8b }, [x9]
431 ; CHECK-BE-NEXT:    b.eq .LBB4_1
432 ; CHECK-BE-NEXT:  // %bb.2: // %exit
433 ; CHECK-BE-NEXT:    ret
436 entry:
437   br label %loop
439 loop:
440   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
441   %gep.A = getelementptr inbounds <8 x i64>, ptr %A, i64 %iv
442   %l.A = load <8 x i64>, ptr %gep.A
443   %trunc = trunc <8 x i64> %l.A to <8 x i8>
444   %gep.dst = getelementptr inbounds <8 x i8>, ptr %dst, i64 %iv
445   store <8 x i8> %trunc, ptr %gep.dst
446   %iv.next = add i64 %iv, 1
447   %ec = icmp eq i64 %iv.next, 1000
448   br i1 %ec, label %loop, label %exit
450 exit:
451   ret void
454 define void @trunc_v8i19_to_v8i8_in_loop(ptr %A, ptr %dst) {
455 ; CHECK-LABEL: trunc_v8i19_to_v8i8_in_loop:
456 ; CHECK:       ; %bb.0: ; %entry
457 ; CHECK-NEXT:    mov x8, xzr
458 ; CHECK-NEXT:  LBB5_1: ; %loop
459 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
460 ; CHECK-NEXT:    ldp x10, x9, [x0]
461 ; CHECK-NEXT:    ldrb w13, [x0, #18]
462 ; CHECK-NEXT:    ldrh w14, [x0, #16]
463 ; CHECK-NEXT:    add x0, x0, #32
464 ; CHECK-NEXT:    ubfx x12, x9, #12, #20
465 ; CHECK-NEXT:    fmov s0, w10
466 ; CHECK-NEXT:    lsr x11, x10, #19
467 ; CHECK-NEXT:    lsr x15, x9, #31
468 ; CHECK-NEXT:    fmov s1, w12
469 ; CHECK-NEXT:    lsr x12, x9, #50
470 ; CHECK-NEXT:    mov.s v0[1], w11
471 ; CHECK-NEXT:    orr w11, w14, w13, lsl #16
472 ; CHECK-NEXT:    lsr x13, x10, #38
473 ; CHECK-NEXT:    lsr x10, x10, #57
474 ; CHECK-NEXT:    mov.s v1[1], w15
475 ; CHECK-NEXT:    orr w12, w12, w11, lsl #14
476 ; CHECK-NEXT:    orr w9, w10, w9, lsl #7
477 ; CHECK-NEXT:    lsr w10, w11, #5
478 ; CHECK-NEXT:    mov.s v0[2], w13
479 ; CHECK-NEXT:    mov.s v1[2], w12
480 ; CHECK-NEXT:    mov.s v0[3], w9
481 ; CHECK-NEXT:    mov.s v1[3], w10
482 ; CHECK-NEXT:    uzp1.8h v0, v0, v1
483 ; CHECK-NEXT:    xtn.8b v0, v0
484 ; CHECK-NEXT:    str d0, [x1, x8, lsl #3]
485 ; CHECK-NEXT:    add x8, x8, #1
486 ; CHECK-NEXT:    cmp x8, #1000
487 ; CHECK-NEXT:    b.eq LBB5_1
488 ; CHECK-NEXT:  ; %bb.2: ; %exit
489 ; CHECK-NEXT:    ret
491 ; CHECK-BE-LABEL: trunc_v8i19_to_v8i8_in_loop:
492 ; CHECK-BE:       // %bb.0: // %entry
493 ; CHECK-BE-NEXT:    mov x8, xzr
494 ; CHECK-BE-NEXT:  .LBB5_1: // %loop
495 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
496 ; CHECK-BE-NEXT:    ldp x10, x9, [x0]
497 ; CHECK-BE-NEXT:    ldrb w16, [x0, #18]
498 ; CHECK-BE-NEXT:    lsr x11, x9, #40
499 ; CHECK-BE-NEXT:    ubfx x12, x9, #33, #7
500 ; CHECK-BE-NEXT:    lsr x15, x10, #45
501 ; CHECK-BE-NEXT:    lsr x13, x10, #40
502 ; CHECK-BE-NEXT:    ubfx x14, x10, #26, #14
503 ; CHECK-BE-NEXT:    orr w11, w12, w11, lsl #7
504 ; CHECK-BE-NEXT:    ldrh w12, [x0, #16]
505 ; CHECK-BE-NEXT:    fmov s0, w15
506 ; CHECK-BE-NEXT:    orr w13, w14, w13, lsl #14
507 ; CHECK-BE-NEXT:    ubfx x14, x9, #14, #18
508 ; CHECK-BE-NEXT:    add x0, x0, #32
509 ; CHECK-BE-NEXT:    fmov s1, w11
510 ; CHECK-BE-NEXT:    orr w11, w16, w12, lsl #8
511 ; CHECK-BE-NEXT:    lsl x12, x9, #24
512 ; CHECK-BE-NEXT:    mov v0.s[1], w13
513 ; CHECK-BE-NEXT:    ubfx x13, x10, #7, #25
514 ; CHECK-BE-NEXT:    extr x9, x10, x9, #40
515 ; CHECK-BE-NEXT:    orr w12, w11, w12
516 ; CHECK-BE-NEXT:    mov v1.s[1], w14
517 ; CHECK-BE-NEXT:    lsr w12, w12, #19
518 ; CHECK-BE-NEXT:    ubfx x9, x9, #12, #20
519 ; CHECK-BE-NEXT:    mov v0.s[2], w13
520 ; CHECK-BE-NEXT:    mov v1.s[2], w12
521 ; CHECK-BE-NEXT:    mov v0.s[3], w9
522 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #3
523 ; CHECK-BE-NEXT:    add x8, x8, #1
524 ; CHECK-BE-NEXT:    cmp x8, #1000
525 ; CHECK-BE-NEXT:    mov v1.s[3], w11
526 ; CHECK-BE-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
527 ; CHECK-BE-NEXT:    xtn v0.8b, v0.8h
528 ; CHECK-BE-NEXT:    st1 { v0.8b }, [x9]
529 ; CHECK-BE-NEXT:    b.eq .LBB5_1
530 ; CHECK-BE-NEXT:  // %bb.2: // %exit
531 ; CHECK-BE-NEXT:    ret
533 entry:
534   br label %loop
536 loop:
537   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
538   %gep.A = getelementptr inbounds <8 x i19>, ptr %A, i64 %iv
539   %l.A = load <8 x i19>, ptr %gep.A
540   %trunc = trunc <8 x i19> %l.A to <8 x i8>
541   %gep.dst = getelementptr inbounds <8 x i8>, ptr %dst, i64 %iv
542   store <8 x i8> %trunc, ptr %gep.dst
543   %iv.next = add i64 %iv, 1
544   %ec = icmp eq i64 %iv.next, 1000
545   br i1 %ec, label %loop, label %exit
547 exit:
548   ret void
551 define void @trunc_v11i64_to_v11i8_in_loop(ptr %A, ptr %dst) {
552 ; CHECK-LABEL: trunc_v11i64_to_v11i8_in_loop:
553 ; CHECK:       ; %bb.0: ; %entry
554 ; CHECK-NEXT:    mov w8, #1000 ; =0x3e8
555 ; CHECK-NEXT:  LBB6_1: ; %loop
556 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
557 ; CHECK-NEXT:    ldp q4, q1, [x0, #48]
558 ; CHECK-NEXT:    add x9, x1, #8
559 ; CHECK-NEXT:    ldp q3, q2, [x0]
560 ; CHECK-NEXT:    subs x8, x8, #1
561 ; CHECK-NEXT:    ldr d0, [x0, #80]
562 ; CHECK-NEXT:    ldr q5, [x0, #32]
563 ; CHECK-NEXT:    add x0, x0, #128
564 ; CHECK-NEXT:    uzp1.4s v4, v5, v4
565 ; CHECK-NEXT:    uzp1.4s v2, v3, v2
566 ; CHECK-NEXT:    uzp1.4s v0, v1, v0
567 ; CHECK-NEXT:    uzp1.8h v1, v2, v4
568 ; CHECK-NEXT:    xtn.4h v0, v0
569 ; CHECK-NEXT:    uzp1.16b v1, v1, v0
570 ; CHECK-NEXT:    xtn.8b v0, v0
571 ; CHECK-NEXT:    st1.h { v1 }[4], [x9]
572 ; CHECK-NEXT:    add x9, x1, #10
573 ; CHECK-NEXT:    st1.b { v0 }[2], [x9]
574 ; CHECK-NEXT:    str d1, [x1], #16
575 ; CHECK-NEXT:    b.eq LBB6_1
576 ; CHECK-NEXT:  ; %bb.2: ; %exit
577 ; CHECK-NEXT:    ret
579 ; CHECK-BE-LABEL: trunc_v11i64_to_v11i8_in_loop:
580 ; CHECK-BE:       // %bb.0: // %entry
581 ; CHECK-BE-NEXT:    mov w8, #1000 // =0x3e8
582 ; CHECK-BE-NEXT:  .LBB6_1: // %loop
583 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
584 ; CHECK-BE-NEXT:    add x9, x0, #64
585 ; CHECK-BE-NEXT:    add x10, x0, #16
586 ; CHECK-BE-NEXT:    ld1 { v3.2d }, [x0]
587 ; CHECK-BE-NEXT:    ld1 { v0.2d }, [x9]
588 ; CHECK-BE-NEXT:    add x9, x0, #48
589 ; CHECK-BE-NEXT:    ld1 { v1.2d }, [x10]
590 ; CHECK-BE-NEXT:    add x10, x0, #32
591 ; CHECK-BE-NEXT:    ld1 { v2.2d }, [x9]
592 ; CHECK-BE-NEXT:    ldr d5, [x0, #80]
593 ; CHECK-BE-NEXT:    ld1 { v4.2d }, [x10]
594 ; CHECK-BE-NEXT:    add x9, x1, #10
595 ; CHECK-BE-NEXT:    subs x8, x8, #1
596 ; CHECK-BE-NEXT:    uzp1 v1.4s, v3.4s, v1.4s
597 ; CHECK-BE-NEXT:    uzp1 v0.4s, v0.4s, v5.4s
598 ; CHECK-BE-NEXT:    add x0, x0, #128
599 ; CHECK-BE-NEXT:    uzp1 v2.4s, v4.4s, v2.4s
600 ; CHECK-BE-NEXT:    xtn v0.4h, v0.4s
601 ; CHECK-BE-NEXT:    uzp1 v1.8h, v1.8h, v2.8h
602 ; CHECK-BE-NEXT:    uzp1 v1.16b, v1.16b, v0.16b
603 ; CHECK-BE-NEXT:    xtn v0.8b, v0.8h
604 ; CHECK-BE-NEXT:    rev16 v2.16b, v1.16b
605 ; CHECK-BE-NEXT:    rev64 v1.16b, v1.16b
606 ; CHECK-BE-NEXT:    st1 { v0.b }[2], [x9]
607 ; CHECK-BE-NEXT:    add x9, x1, #8
608 ; CHECK-BE-NEXT:    st1 { v2.h }[4], [x9]
609 ; CHECK-BE-NEXT:    str d1, [x1], #16
610 ; CHECK-BE-NEXT:    b.eq .LBB6_1
611 ; CHECK-BE-NEXT:  // %bb.2: // %exit
612 ; CHECK-BE-NEXT:    ret
614 entry:
615   br label %loop
617 loop:
618   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
619   %gep.A = getelementptr inbounds <11 x i64>, ptr %A, i64 %iv
620   %l.A = load <11 x i64>, ptr %gep.A
621   %trunc = trunc <11 x i64> %l.A to <11 x i8>
622   %gep.dst = getelementptr inbounds <11 x i8>, ptr %dst, i64 %iv
623   store <11 x i8> %trunc, ptr %gep.dst
624   %iv.next = add i64 %iv, 1
625   %ec = icmp eq i64 %iv.next, 1000
626   br i1 %ec, label %loop, label %exit
628 exit:
629   ret void
632 define void @trunc_v16i16_to_v16i8_in_loop(ptr %A, ptr %dst) {
633 ; CHECK-LABEL: trunc_v16i16_to_v16i8_in_loop:
634 ; CHECK:       ; %bb.0: ; %entry
635 ; CHECK-NEXT:    mov x8, xzr
636 ; CHECK-NEXT:  LBB7_1: ; %loop
637 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
638 ; CHECK-NEXT:    add x9, x0, x8, lsl #5
639 ; CHECK-NEXT:    ldp q1, q0, [x9]
640 ; CHECK-NEXT:    uzp1.16b v0, v1, v0
641 ; CHECK-NEXT:    str q0, [x1, x8, lsl #4]
642 ; CHECK-NEXT:    add x8, x8, #1
643 ; CHECK-NEXT:    cmp x8, #1000
644 ; CHECK-NEXT:    b.eq LBB7_1
645 ; CHECK-NEXT:  ; %bb.2: ; %exit
646 ; CHECK-NEXT:    ret
648 ; CHECK-BE-LABEL: trunc_v16i16_to_v16i8_in_loop:
649 ; CHECK-BE:       // %bb.0: // %entry
650 ; CHECK-BE-NEXT:    mov x8, xzr
651 ; CHECK-BE-NEXT:  .LBB7_1: // %loop
652 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
653 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #5
654 ; CHECK-BE-NEXT:    add x10, x9, #16
655 ; CHECK-BE-NEXT:    ld1 { v0.8h }, [x9]
656 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #4
657 ; CHECK-BE-NEXT:    ld1 { v1.8h }, [x10]
658 ; CHECK-BE-NEXT:    add x8, x8, #1
659 ; CHECK-BE-NEXT:    cmp x8, #1000
660 ; CHECK-BE-NEXT:    uzp1 v0.16b, v0.16b, v1.16b
661 ; CHECK-BE-NEXT:    st1 { v0.16b }, [x9]
662 ; CHECK-BE-NEXT:    b.eq .LBB7_1
663 ; CHECK-BE-NEXT:  // %bb.2: // %exit
664 ; CHECK-BE-NEXT:    ret
669 entry:
670   br label %loop
672 loop:
673   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
674   %gep.A = getelementptr inbounds <16 x i16>, ptr %A, i64 %iv
675   %l.A = load <16 x i16>, ptr %gep.A
676   %trunc = trunc <16 x i16> %l.A to <16 x i8>
677   %gep.dst = getelementptr inbounds <16 x i8>, ptr %dst, i64 %iv
678   store <16 x i8> %trunc, ptr %gep.dst
679   %iv.next = add i64 %iv, 1
680   %ec = icmp eq i64 %iv.next, 1000
681   br i1 %ec, label %loop, label %exit
683 exit:
684   ret void
687 define void @trunc_v8i16_to_v8i8_in_loop(ptr %A, ptr %dst) {
688 ; CHECK-LABEL: trunc_v8i16_to_v8i8_in_loop:
689 ; CHECK:       ; %bb.0: ; %entry
690 ; CHECK-NEXT:    mov x8, xzr
691 ; CHECK-NEXT:  LBB8_1: ; %loop
692 ; CHECK-NEXT:    ; =>This Inner Loop Header: Depth=1
693 ; CHECK-NEXT:    ldr q0, [x0, x8, lsl #4]
694 ; CHECK-NEXT:    xtn.8b v0, v0
695 ; CHECK-NEXT:    str d0, [x1, x8, lsl #3]
696 ; CHECK-NEXT:    add x8, x8, #1
697 ; CHECK-NEXT:    cmp x8, #1000
698 ; CHECK-NEXT:    b.eq LBB8_1
699 ; CHECK-NEXT:  ; %bb.2: ; %exit
700 ; CHECK-NEXT:    ret
702 ; CHECK-BE-LABEL: trunc_v8i16_to_v8i8_in_loop:
703 ; CHECK-BE:       // %bb.0: // %entry
704 ; CHECK-BE-NEXT:    mov x8, xzr
705 ; CHECK-BE-NEXT:  .LBB8_1: // %loop
706 ; CHECK-BE-NEXT:    // =>This Inner Loop Header: Depth=1
707 ; CHECK-BE-NEXT:    add x9, x0, x8, lsl #4
708 ; CHECK-BE-NEXT:    ld1 { v0.8h }, [x9]
709 ; CHECK-BE-NEXT:    add x9, x1, x8, lsl #3
710 ; CHECK-BE-NEXT:    add x8, x8, #1
711 ; CHECK-BE-NEXT:    cmp x8, #1000
712 ; CHECK-BE-NEXT:    xtn v0.8b, v0.8h
713 ; CHECK-BE-NEXT:    st1 { v0.8b }, [x9]
714 ; CHECK-BE-NEXT:    b.eq .LBB8_1
715 ; CHECK-BE-NEXT:  // %bb.2: // %exit
716 ; CHECK-BE-NEXT:    ret
721 entry:
722   br label %loop
724 loop:
725   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
726   %gep.A = getelementptr inbounds <8 x i16>, ptr %A, i64 %iv
727   %l.A = load <8 x i16>, ptr %gep.A
728   %trunc = trunc <8 x i16> %l.A to <8 x i8>
729   %gep.dst = getelementptr inbounds <8 x i8>, ptr %dst, i64 %iv
730   store <8 x i8> %trunc, ptr %gep.dst
731   %iv.next = add i64 %iv, 1
732   %ec = icmp eq i64 %iv.next, 1000
733   br i1 %ec, label %loop, label %exit
735 exit:
736   ret void