[ARM] Fold VCMP into VPT
[llvm-core.git] / test / CodeGen / Thumb2 / mve-masked-ldst.ll
blob0bb5a7c0958f9ca342879c62f39eeb7dd4da9da3
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+mve,+fullfp16 -enable-arm-maskedldst -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE
3 ; RUN: llc -mtriple=thumbebv8.1m.main-arm-none-eabi -mattr=+mve,+fullfp16 -enable-arm-maskedldst -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
5 define void @foo_v4i32_v4i32(<4 x i32> *%dest, <4 x i32> *%mask, <4 x i32> *%src) {
6 ; CHECK-LABEL: foo_v4i32_v4i32:
7 ; CHECK:       @ %bb.0: @ %entry
8 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
9 ; CHECK-NEXT:    vptt.s32 gt, q0, zr
10 ; CHECK-NEXT:    vldrwt.u32 q0, [r2]
11 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
12 ; CHECK-NEXT:    bx lr
13 entry:
14   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
15   %1 = icmp sgt <4 x i32> %0, zeroinitializer
16   %2 = call <4 x i32> @llvm.masked.load.v4i32(<4 x i32>* %src, i32 4, <4 x i1> %1, <4 x i32> undef)
17   call void @llvm.masked.store.v4i32(<4 x i32> %2, <4 x i32>* %dest, i32 4, <4 x i1> %1)
18   ret void
21 define void @foo_sext_v4i32_v4i8(<4 x i32> *%dest, <4 x i32> *%mask, <4 x i8> *%src) {
22 ; CHECK-LABEL: foo_sext_v4i32_v4i8:
23 ; CHECK:       @ %bb.0: @ %entry
24 ; CHECK-NEXT:    .pad #4
25 ; CHECK-NEXT:    sub sp, #4
26 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
27 ; CHECK-NEXT:    movs r3, #0
28 ; CHECK-NEXT:    vcmp.s32 gt, q0, zr
29 ; CHECK-NEXT:    @ implicit-def: $q0
30 ; CHECK-NEXT:    vmrs r12, p0
31 ; CHECK-NEXT:    and r1, r12, #1
32 ; CHECK-NEXT:    rsbs r1, r1, #0
33 ; CHECK-NEXT:    bfi r3, r1, #0, #1
34 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
35 ; CHECK-NEXT:    rsbs r1, r1, #0
36 ; CHECK-NEXT:    bfi r3, r1, #1, #1
37 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
38 ; CHECK-NEXT:    rsbs r1, r1, #0
39 ; CHECK-NEXT:    bfi r3, r1, #2, #1
40 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
41 ; CHECK-NEXT:    rsbs r1, r1, #0
42 ; CHECK-NEXT:    bfi r3, r1, #3, #1
43 ; CHECK-NEXT:    and r1, r3, #15
44 ; CHECK-NEXT:    lsls r3, r1, #31
45 ; CHECK-NEXT:    itt ne
46 ; CHECK-NEXT:    ldrbne r3, [r2]
47 ; CHECK-NEXT:    vmovne.32 q0[0], r3
48 ; CHECK-NEXT:    lsls r3, r1, #30
49 ; CHECK-NEXT:    itt mi
50 ; CHECK-NEXT:    ldrbmi r3, [r2, #1]
51 ; CHECK-NEXT:    vmovmi.32 q0[1], r3
52 ; CHECK-NEXT:    lsls r3, r1, #29
53 ; CHECK-NEXT:    itt mi
54 ; CHECK-NEXT:    ldrbmi r3, [r2, #2]
55 ; CHECK-NEXT:    vmovmi.32 q0[2], r3
56 ; CHECK-NEXT:    lsls r1, r1, #28
57 ; CHECK-NEXT:    itt mi
58 ; CHECK-NEXT:    ldrbmi r1, [r2, #3]
59 ; CHECK-NEXT:    vmovmi.32 q0[3], r1
60 ; CHECK-NEXT:    vmovlb.s8 q0, q0
61 ; CHECK-NEXT:    vmovlb.s16 q0, q0
62 ; CHECK-NEXT:    vpst
63 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
64 ; CHECK-NEXT:    add sp, #4
65 ; CHECK-NEXT:    bx lr
66 entry:
67   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
68   %1 = icmp sgt <4 x i32> %0, zeroinitializer
69   %2 = call <4 x i8> @llvm.masked.load.v4i8(<4 x i8>* %src, i32 1, <4 x i1> %1, <4 x i8> undef)
70   %3 = sext <4 x i8> %2 to <4 x i32>
71   call void @llvm.masked.store.v4i32(<4 x i32> %3, <4 x i32>* %dest, i32 4, <4 x i1> %1)
72   ret void
75 define void @foo_sext_v4i32_v4i16(<4 x i32> *%dest, <4 x i32> *%mask, <4 x i16> *%src) {
76 ; CHECK-LABEL: foo_sext_v4i32_v4i16:
77 ; CHECK:       @ %bb.0: @ %entry
78 ; CHECK-NEXT:    .pad #4
79 ; CHECK-NEXT:    sub sp, #4
80 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
81 ; CHECK-NEXT:    movs r3, #0
82 ; CHECK-NEXT:    vcmp.s32 gt, q0, zr
83 ; CHECK-NEXT:    @ implicit-def: $q0
84 ; CHECK-NEXT:    vmrs r12, p0
85 ; CHECK-NEXT:    and r1, r12, #1
86 ; CHECK-NEXT:    rsbs r1, r1, #0
87 ; CHECK-NEXT:    bfi r3, r1, #0, #1
88 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
89 ; CHECK-NEXT:    rsbs r1, r1, #0
90 ; CHECK-NEXT:    bfi r3, r1, #1, #1
91 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
92 ; CHECK-NEXT:    rsbs r1, r1, #0
93 ; CHECK-NEXT:    bfi r3, r1, #2, #1
94 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
95 ; CHECK-NEXT:    rsbs r1, r1, #0
96 ; CHECK-NEXT:    bfi r3, r1, #3, #1
97 ; CHECK-NEXT:    and r1, r3, #15
98 ; CHECK-NEXT:    lsls r3, r1, #31
99 ; CHECK-NEXT:    itt ne
100 ; CHECK-NEXT:    ldrhne r3, [r2]
101 ; CHECK-NEXT:    vmovne.32 q0[0], r3
102 ; CHECK-NEXT:    lsls r3, r1, #30
103 ; CHECK-NEXT:    itt mi
104 ; CHECK-NEXT:    ldrhmi r3, [r2, #2]
105 ; CHECK-NEXT:    vmovmi.32 q0[1], r3
106 ; CHECK-NEXT:    lsls r3, r1, #29
107 ; CHECK-NEXT:    itt mi
108 ; CHECK-NEXT:    ldrhmi r3, [r2, #4]
109 ; CHECK-NEXT:    vmovmi.32 q0[2], r3
110 ; CHECK-NEXT:    lsls r1, r1, #28
111 ; CHECK-NEXT:    itt mi
112 ; CHECK-NEXT:    ldrhmi r1, [r2, #6]
113 ; CHECK-NEXT:    vmovmi.32 q0[3], r1
114 ; CHECK-NEXT:    vmovlb.s16 q0, q0
115 ; CHECK-NEXT:    vpst
116 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
117 ; CHECK-NEXT:    add sp, #4
118 ; CHECK-NEXT:    bx lr
119 entry:
120   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
121   %1 = icmp sgt <4 x i32> %0, zeroinitializer
122   %2 = call <4 x i16> @llvm.masked.load.v4i16(<4 x i16>* %src, i32 2, <4 x i1> %1, <4 x i16> undef)
123   %3 = sext <4 x i16> %2 to <4 x i32>
124   call void @llvm.masked.store.v4i32(<4 x i32> %3, <4 x i32>* %dest, i32 4, <4 x i1> %1)
125   ret void
128 define void @foo_zext_v4i32_v4i8(<4 x i32> *%dest, <4 x i32> *%mask, <4 x i8> *%src) {
129 ; CHECK-LABEL: foo_zext_v4i32_v4i8:
130 ; CHECK:       @ %bb.0: @ %entry
131 ; CHECK-NEXT:    .pad #4
132 ; CHECK-NEXT:    sub sp, #4
133 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
134 ; CHECK-NEXT:    movs r3, #0
135 ; CHECK-NEXT:    vmov.i32 q1, #0xff
136 ; CHECK-NEXT:    vcmp.s32 gt, q0, zr
137 ; CHECK-NEXT:    @ implicit-def: $q0
138 ; CHECK-NEXT:    vmrs r12, p0
139 ; CHECK-NEXT:    and r1, r12, #1
140 ; CHECK-NEXT:    rsbs r1, r1, #0
141 ; CHECK-NEXT:    bfi r3, r1, #0, #1
142 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
143 ; CHECK-NEXT:    rsbs r1, r1, #0
144 ; CHECK-NEXT:    bfi r3, r1, #1, #1
145 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
146 ; CHECK-NEXT:    rsbs r1, r1, #0
147 ; CHECK-NEXT:    bfi r3, r1, #2, #1
148 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
149 ; CHECK-NEXT:    rsbs r1, r1, #0
150 ; CHECK-NEXT:    bfi r3, r1, #3, #1
151 ; CHECK-NEXT:    and r1, r3, #15
152 ; CHECK-NEXT:    lsls r3, r1, #31
153 ; CHECK-NEXT:    itt ne
154 ; CHECK-NEXT:    ldrbne r3, [r2]
155 ; CHECK-NEXT:    vmovne.32 q0[0], r3
156 ; CHECK-NEXT:    lsls r3, r1, #30
157 ; CHECK-NEXT:    itt mi
158 ; CHECK-NEXT:    ldrbmi r3, [r2, #1]
159 ; CHECK-NEXT:    vmovmi.32 q0[1], r3
160 ; CHECK-NEXT:    lsls r3, r1, #29
161 ; CHECK-NEXT:    itt mi
162 ; CHECK-NEXT:    ldrbmi r3, [r2, #2]
163 ; CHECK-NEXT:    vmovmi.32 q0[2], r3
164 ; CHECK-NEXT:    lsls r1, r1, #28
165 ; CHECK-NEXT:    itt mi
166 ; CHECK-NEXT:    ldrbmi r1, [r2, #3]
167 ; CHECK-NEXT:    vmovmi.32 q0[3], r1
168 ; CHECK-NEXT:    vand q0, q0, q1
169 ; CHECK-NEXT:    vpst
170 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
171 ; CHECK-NEXT:    add sp, #4
172 ; CHECK-NEXT:    bx lr
173 entry:
174   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
175   %1 = icmp sgt <4 x i32> %0, zeroinitializer
176   %2 = call <4 x i8> @llvm.masked.load.v4i8(<4 x i8>* %src, i32 1, <4 x i1> %1, <4 x i8> undef)
177   %3 = zext <4 x i8> %2 to <4 x i32>
178   call void @llvm.masked.store.v4i32(<4 x i32> %3, <4 x i32>* %dest, i32 4, <4 x i1> %1)
179   ret void
182 define void @foo_zext_v4i32_v4i16(<4 x i32> *%dest, <4 x i32> *%mask, <4 x i16> *%src) {
183 ; CHECK-LABEL: foo_zext_v4i32_v4i16:
184 ; CHECK:       @ %bb.0: @ %entry
185 ; CHECK-NEXT:    .pad #4
186 ; CHECK-NEXT:    sub sp, #4
187 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
188 ; CHECK-NEXT:    movs r3, #0
189 ; CHECK-NEXT:    vcmp.s32 gt, q0, zr
190 ; CHECK-NEXT:    @ implicit-def: $q0
191 ; CHECK-NEXT:    vmrs r12, p0
192 ; CHECK-NEXT:    and r1, r12, #1
193 ; CHECK-NEXT:    rsbs r1, r1, #0
194 ; CHECK-NEXT:    bfi r3, r1, #0, #1
195 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
196 ; CHECK-NEXT:    rsbs r1, r1, #0
197 ; CHECK-NEXT:    bfi r3, r1, #1, #1
198 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
199 ; CHECK-NEXT:    rsbs r1, r1, #0
200 ; CHECK-NEXT:    bfi r3, r1, #2, #1
201 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
202 ; CHECK-NEXT:    rsbs r1, r1, #0
203 ; CHECK-NEXT:    bfi r3, r1, #3, #1
204 ; CHECK-NEXT:    and r1, r3, #15
205 ; CHECK-NEXT:    lsls r3, r1, #31
206 ; CHECK-NEXT:    itt ne
207 ; CHECK-NEXT:    ldrhne r3, [r2]
208 ; CHECK-NEXT:    vmovne.32 q0[0], r3
209 ; CHECK-NEXT:    lsls r3, r1, #30
210 ; CHECK-NEXT:    itt mi
211 ; CHECK-NEXT:    ldrhmi r3, [r2, #2]
212 ; CHECK-NEXT:    vmovmi.32 q0[1], r3
213 ; CHECK-NEXT:    lsls r3, r1, #29
214 ; CHECK-NEXT:    itt mi
215 ; CHECK-NEXT:    ldrhmi r3, [r2, #4]
216 ; CHECK-NEXT:    vmovmi.32 q0[2], r3
217 ; CHECK-NEXT:    lsls r1, r1, #28
218 ; CHECK-NEXT:    itt mi
219 ; CHECK-NEXT:    ldrhmi r1, [r2, #6]
220 ; CHECK-NEXT:    vmovmi.32 q0[3], r1
221 ; CHECK-NEXT:    vmovlb.u16 q0, q0
222 ; CHECK-NEXT:    vpst
223 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
224 ; CHECK-NEXT:    add sp, #4
225 ; CHECK-NEXT:    bx lr
226 entry:
227   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
228   %1 = icmp sgt <4 x i32> %0, zeroinitializer
229   %2 = call <4 x i16> @llvm.masked.load.v4i16(<4 x i16>* %src, i32 2, <4 x i1> %1, <4 x i16> undef)
230   %3 = zext <4 x i16> %2 to <4 x i32>
231   call void @llvm.masked.store.v4i32(<4 x i32> %3, <4 x i32>* %dest, i32 4, <4 x i1> %1)
232   ret void
235 define void @foo_v8i16_v8i16(<8 x i16> *%dest, <8 x i16> *%mask, <8 x i16> *%src) {
236 ; CHECK-LABEL: foo_v8i16_v8i16:
237 ; CHECK:       @ %bb.0: @ %entry
238 ; CHECK-NEXT:    vldrh.u16 q0, [r1]
239 ; CHECK-NEXT:    vptt.s16 gt, q0, zr
240 ; CHECK-NEXT:    vldrht.u16 q0, [r2]
241 ; CHECK-NEXT:    vstrht.16 q0, [r0]
242 ; CHECK-NEXT:    bx lr
243 entry:
244   %0 = load <8 x i16>, <8 x i16>* %mask, align 2
245   %1 = icmp sgt <8 x i16> %0, zeroinitializer
246   %2 = call <8 x i16> @llvm.masked.load.v8i16(<8 x i16>* %src, i32 2, <8 x i1> %1, <8 x i16> undef)
247   call void @llvm.masked.store.v8i16(<8 x i16> %2, <8 x i16>* %dest, i32 2, <8 x i1> %1)
248   ret void
251 define void @foo_sext_v8i16_v8i8(<8 x i16> *%dest, <8 x i16> *%mask, <8 x i8> *%src) {
252 ; CHECK-LABEL: foo_sext_v8i16_v8i8:
253 ; CHECK:       @ %bb.0: @ %entry
254 ; CHECK-NEXT:    .pad #8
255 ; CHECK-NEXT:    sub sp, #8
256 ; CHECK-NEXT:    vldrh.u16 q0, [r1]
257 ; CHECK-NEXT:    movs r3, #0
258 ; CHECK-NEXT:    vcmp.s16 gt, q0, zr
259 ; CHECK-NEXT:    @ implicit-def: $q0
260 ; CHECK-NEXT:    vmrs r12, p0
261 ; CHECK-NEXT:    and r1, r12, #1
262 ; CHECK-NEXT:    rsbs r1, r1, #0
263 ; CHECK-NEXT:    bfi r3, r1, #0, #1
264 ; CHECK-NEXT:    ubfx r1, r12, #2, #1
265 ; CHECK-NEXT:    rsbs r1, r1, #0
266 ; CHECK-NEXT:    bfi r3, r1, #1, #1
267 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
268 ; CHECK-NEXT:    rsbs r1, r1, #0
269 ; CHECK-NEXT:    bfi r3, r1, #2, #1
270 ; CHECK-NEXT:    ubfx r1, r12, #6, #1
271 ; CHECK-NEXT:    rsbs r1, r1, #0
272 ; CHECK-NEXT:    bfi r3, r1, #3, #1
273 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
274 ; CHECK-NEXT:    rsbs r1, r1, #0
275 ; CHECK-NEXT:    bfi r3, r1, #4, #1
276 ; CHECK-NEXT:    ubfx r1, r12, #10, #1
277 ; CHECK-NEXT:    rsbs r1, r1, #0
278 ; CHECK-NEXT:    bfi r3, r1, #5, #1
279 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
280 ; CHECK-NEXT:    rsbs r1, r1, #0
281 ; CHECK-NEXT:    bfi r3, r1, #6, #1
282 ; CHECK-NEXT:    ubfx r1, r12, #14, #1
283 ; CHECK-NEXT:    rsbs r1, r1, #0
284 ; CHECK-NEXT:    bfi r3, r1, #7, #1
285 ; CHECK-NEXT:    uxtb r1, r3
286 ; CHECK-NEXT:    lsls r3, r3, #31
287 ; CHECK-NEXT:    itt ne
288 ; CHECK-NEXT:    ldrbne r3, [r2]
289 ; CHECK-NEXT:    vmovne.16 q0[0], r3
290 ; CHECK-NEXT:    lsls r3, r1, #30
291 ; CHECK-NEXT:    itt mi
292 ; CHECK-NEXT:    ldrbmi r3, [r2, #1]
293 ; CHECK-NEXT:    vmovmi.16 q0[1], r3
294 ; CHECK-NEXT:    lsls r3, r1, #29
295 ; CHECK-NEXT:    itt mi
296 ; CHECK-NEXT:    ldrbmi r3, [r2, #2]
297 ; CHECK-NEXT:    vmovmi.16 q0[2], r3
298 ; CHECK-NEXT:    lsls r3, r1, #28
299 ; CHECK-NEXT:    itt mi
300 ; CHECK-NEXT:    ldrbmi r3, [r2, #3]
301 ; CHECK-NEXT:    vmovmi.16 q0[3], r3
302 ; CHECK-NEXT:    lsls r3, r1, #27
303 ; CHECK-NEXT:    itt mi
304 ; CHECK-NEXT:    ldrbmi r3, [r2, #4]
305 ; CHECK-NEXT:    vmovmi.16 q0[4], r3
306 ; CHECK-NEXT:    lsls r3, r1, #26
307 ; CHECK-NEXT:    itt mi
308 ; CHECK-NEXT:    ldrbmi r3, [r2, #5]
309 ; CHECK-NEXT:    vmovmi.16 q0[5], r3
310 ; CHECK-NEXT:    lsls r3, r1, #25
311 ; CHECK-NEXT:    itt mi
312 ; CHECK-NEXT:    ldrbmi r3, [r2, #6]
313 ; CHECK-NEXT:    vmovmi.16 q0[6], r3
314 ; CHECK-NEXT:    lsls r1, r1, #24
315 ; CHECK-NEXT:    itt mi
316 ; CHECK-NEXT:    ldrbmi r1, [r2, #7]
317 ; CHECK-NEXT:    vmovmi.16 q0[7], r1
318 ; CHECK-NEXT:    vmovlb.s8 q0, q0
319 ; CHECK-NEXT:    vpst
320 ; CHECK-NEXT:    vstrht.16 q0, [r0]
321 ; CHECK-NEXT:    add sp, #8
322 ; CHECK-NEXT:    bx lr
323 entry:
324   %0 = load <8 x i16>, <8 x i16>* %mask, align 2
325   %1 = icmp sgt <8 x i16> %0, zeroinitializer
326   %2 = call <8 x i8> @llvm.masked.load.v8i8(<8 x i8>* %src, i32 1, <8 x i1> %1, <8 x i8> undef)
327   %3 = sext <8 x i8> %2 to <8 x i16>
328   call void @llvm.masked.store.v8i16(<8 x i16> %3, <8 x i16>* %dest, i32 2, <8 x i1> %1)
329   ret void
332 define void @foo_zext_v8i16_v8i8(<8 x i16> *%dest, <8 x i16> *%mask, <8 x i8> *%src) {
333 ; CHECK-LABEL: foo_zext_v8i16_v8i8:
334 ; CHECK:       @ %bb.0: @ %entry
335 ; CHECK-NEXT:    .pad #8
336 ; CHECK-NEXT:    sub sp, #8
337 ; CHECK-NEXT:    vldrh.u16 q0, [r1]
338 ; CHECK-NEXT:    movs r3, #0
339 ; CHECK-NEXT:    vcmp.s16 gt, q0, zr
340 ; CHECK-NEXT:    @ implicit-def: $q0
341 ; CHECK-NEXT:    vmrs r12, p0
342 ; CHECK-NEXT:    and r1, r12, #1
343 ; CHECK-NEXT:    rsbs r1, r1, #0
344 ; CHECK-NEXT:    bfi r3, r1, #0, #1
345 ; CHECK-NEXT:    ubfx r1, r12, #2, #1
346 ; CHECK-NEXT:    rsbs r1, r1, #0
347 ; CHECK-NEXT:    bfi r3, r1, #1, #1
348 ; CHECK-NEXT:    ubfx r1, r12, #4, #1
349 ; CHECK-NEXT:    rsbs r1, r1, #0
350 ; CHECK-NEXT:    bfi r3, r1, #2, #1
351 ; CHECK-NEXT:    ubfx r1, r12, #6, #1
352 ; CHECK-NEXT:    rsbs r1, r1, #0
353 ; CHECK-NEXT:    bfi r3, r1, #3, #1
354 ; CHECK-NEXT:    ubfx r1, r12, #8, #1
355 ; CHECK-NEXT:    rsbs r1, r1, #0
356 ; CHECK-NEXT:    bfi r3, r1, #4, #1
357 ; CHECK-NEXT:    ubfx r1, r12, #10, #1
358 ; CHECK-NEXT:    rsbs r1, r1, #0
359 ; CHECK-NEXT:    bfi r3, r1, #5, #1
360 ; CHECK-NEXT:    ubfx r1, r12, #12, #1
361 ; CHECK-NEXT:    rsbs r1, r1, #0
362 ; CHECK-NEXT:    bfi r3, r1, #6, #1
363 ; CHECK-NEXT:    ubfx r1, r12, #14, #1
364 ; CHECK-NEXT:    rsbs r1, r1, #0
365 ; CHECK-NEXT:    bfi r3, r1, #7, #1
366 ; CHECK-NEXT:    uxtb r1, r3
367 ; CHECK-NEXT:    lsls r3, r3, #31
368 ; CHECK-NEXT:    itt ne
369 ; CHECK-NEXT:    ldrbne r3, [r2]
370 ; CHECK-NEXT:    vmovne.16 q0[0], r3
371 ; CHECK-NEXT:    lsls r3, r1, #30
372 ; CHECK-NEXT:    itt mi
373 ; CHECK-NEXT:    ldrbmi r3, [r2, #1]
374 ; CHECK-NEXT:    vmovmi.16 q0[1], r3
375 ; CHECK-NEXT:    lsls r3, r1, #29
376 ; CHECK-NEXT:    itt mi
377 ; CHECK-NEXT:    ldrbmi r3, [r2, #2]
378 ; CHECK-NEXT:    vmovmi.16 q0[2], r3
379 ; CHECK-NEXT:    lsls r3, r1, #28
380 ; CHECK-NEXT:    itt mi
381 ; CHECK-NEXT:    ldrbmi r3, [r2, #3]
382 ; CHECK-NEXT:    vmovmi.16 q0[3], r3
383 ; CHECK-NEXT:    lsls r3, r1, #27
384 ; CHECK-NEXT:    itt mi
385 ; CHECK-NEXT:    ldrbmi r3, [r2, #4]
386 ; CHECK-NEXT:    vmovmi.16 q0[4], r3
387 ; CHECK-NEXT:    lsls r3, r1, #26
388 ; CHECK-NEXT:    itt mi
389 ; CHECK-NEXT:    ldrbmi r3, [r2, #5]
390 ; CHECK-NEXT:    vmovmi.16 q0[5], r3
391 ; CHECK-NEXT:    lsls r3, r1, #25
392 ; CHECK-NEXT:    itt mi
393 ; CHECK-NEXT:    ldrbmi r3, [r2, #6]
394 ; CHECK-NEXT:    vmovmi.16 q0[6], r3
395 ; CHECK-NEXT:    lsls r1, r1, #24
396 ; CHECK-NEXT:    itt mi
397 ; CHECK-NEXT:    ldrbmi r1, [r2, #7]
398 ; CHECK-NEXT:    vmovmi.16 q0[7], r1
399 ; CHECK-NEXT:    vmovlb.u8 q0, q0
400 ; CHECK-NEXT:    vpst
401 ; CHECK-NEXT:    vstrht.16 q0, [r0]
402 ; CHECK-NEXT:    add sp, #8
403 ; CHECK-NEXT:    bx lr
404 entry:
405   %0 = load <8 x i16>, <8 x i16>* %mask, align 2
406   %1 = icmp sgt <8 x i16> %0, zeroinitializer
407   %2 = call <8 x i8> @llvm.masked.load.v8i8(<8 x i8>* %src, i32 1, <8 x i1> %1, <8 x i8> undef)
408   %3 = zext <8 x i8> %2 to <8 x i16>
409   call void @llvm.masked.store.v8i16(<8 x i16> %3, <8 x i16>* %dest, i32 2, <8 x i1> %1)
410   ret void
413 define void @foo_v16i8_v16i8(<16 x i8> *%dest, <16 x i8> *%mask, <16 x i8> *%src) {
414 ; CHECK-LABEL: foo_v16i8_v16i8:
415 ; CHECK:       @ %bb.0: @ %entry
416 ; CHECK-NEXT:    vldrb.u8 q0, [r1]
417 ; CHECK-NEXT:    vptt.s8 gt, q0, zr
418 ; CHECK-NEXT:    vldrbt.u8 q0, [r2]
419 ; CHECK-NEXT:    vstrbt.8 q0, [r0]
420 ; CHECK-NEXT:    bx lr
421 entry:
422   %0 = load <16 x i8>, <16 x i8>* %mask, align 1
423   %1 = icmp sgt <16 x i8> %0, zeroinitializer
424   %2 = call <16 x i8> @llvm.masked.load.v16i8(<16 x i8>* %src, i32 1, <16 x i1> %1, <16 x i8> undef)
425   call void @llvm.masked.store.v16i8(<16 x i8> %2, <16 x i8>* %dest, i32 1, <16 x i1> %1)
426   ret void
429 define void @foo_trunc_v8i8_v8i16(<8 x i8> *%dest, <8 x i16> *%mask, <8 x i16> *%src) {
430 ; CHECK-LABEL: foo_trunc_v8i8_v8i16:
431 ; CHECK:       @ %bb.0: @ %entry
432 ; CHECK-NEXT:    .pad #8
433 ; CHECK-NEXT:    sub sp, #8
434 ; CHECK-NEXT:    vldrh.u16 q0, [r1]
435 ; CHECK-NEXT:    movs r3, #0
436 ; CHECK-NEXT:    vpt.s16 gt, q0, zr
437 ; CHECK-NEXT:    vldrht.u16 q0, [r2]
438 ; CHECK-NEXT:    vmrs r1, p0
439 ; CHECK-NEXT:    and r2, r1, #1
440 ; CHECK-NEXT:    rsbs r2, r2, #0
441 ; CHECK-NEXT:    bfi r3, r2, #0, #1
442 ; CHECK-NEXT:    ubfx r2, r1, #2, #1
443 ; CHECK-NEXT:    rsbs r2, r2, #0
444 ; CHECK-NEXT:    bfi r3, r2, #1, #1
445 ; CHECK-NEXT:    ubfx r2, r1, #4, #1
446 ; CHECK-NEXT:    rsbs r2, r2, #0
447 ; CHECK-NEXT:    bfi r3, r2, #2, #1
448 ; CHECK-NEXT:    ubfx r2, r1, #6, #1
449 ; CHECK-NEXT:    rsbs r2, r2, #0
450 ; CHECK-NEXT:    bfi r3, r2, #3, #1
451 ; CHECK-NEXT:    ubfx r2, r1, #8, #1
452 ; CHECK-NEXT:    rsbs r2, r2, #0
453 ; CHECK-NEXT:    bfi r3, r2, #4, #1
454 ; CHECK-NEXT:    ubfx r2, r1, #10, #1
455 ; CHECK-NEXT:    rsbs r2, r2, #0
456 ; CHECK-NEXT:    bfi r3, r2, #5, #1
457 ; CHECK-NEXT:    ubfx r2, r1, #12, #1
458 ; CHECK-NEXT:    ubfx r1, r1, #14, #1
459 ; CHECK-NEXT:    rsbs r2, r2, #0
460 ; CHECK-NEXT:    bfi r3, r2, #6, #1
461 ; CHECK-NEXT:    rsbs r1, r1, #0
462 ; CHECK-NEXT:    bfi r3, r1, #7, #1
463 ; CHECK-NEXT:    lsls r2, r3, #31
464 ; CHECK-NEXT:    uxtb r1, r3
465 ; CHECK-NEXT:    itt ne
466 ; CHECK-NEXT:    vmovne.u16 r2, q0[0]
467 ; CHECK-NEXT:    strbne r2, [r0]
468 ; CHECK-NEXT:    lsls r2, r1, #30
469 ; CHECK-NEXT:    itt mi
470 ; CHECK-NEXT:    vmovmi.u16 r2, q0[1]
471 ; CHECK-NEXT:    strbmi r2, [r0, #1]
472 ; CHECK-NEXT:    lsls r2, r1, #29
473 ; CHECK-NEXT:    itt mi
474 ; CHECK-NEXT:    vmovmi.u16 r2, q0[2]
475 ; CHECK-NEXT:    strbmi r2, [r0, #2]
476 ; CHECK-NEXT:    lsls r2, r1, #28
477 ; CHECK-NEXT:    itt mi
478 ; CHECK-NEXT:    vmovmi.u16 r2, q0[3]
479 ; CHECK-NEXT:    strbmi r2, [r0, #3]
480 ; CHECK-NEXT:    lsls r2, r1, #27
481 ; CHECK-NEXT:    itt mi
482 ; CHECK-NEXT:    vmovmi.u16 r2, q0[4]
483 ; CHECK-NEXT:    strbmi r2, [r0, #4]
484 ; CHECK-NEXT:    lsls r2, r1, #26
485 ; CHECK-NEXT:    itt mi
486 ; CHECK-NEXT:    vmovmi.u16 r2, q0[5]
487 ; CHECK-NEXT:    strbmi r2, [r0, #5]
488 ; CHECK-NEXT:    lsls r2, r1, #25
489 ; CHECK-NEXT:    itt mi
490 ; CHECK-NEXT:    vmovmi.u16 r2, q0[6]
491 ; CHECK-NEXT:    strbmi r2, [r0, #6]
492 ; CHECK-NEXT:    lsls r1, r1, #24
493 ; CHECK-NEXT:    itt mi
494 ; CHECK-NEXT:    vmovmi.u16 r1, q0[7]
495 ; CHECK-NEXT:    strbmi r1, [r0, #7]
496 ; CHECK-NEXT:    add sp, #8
497 ; CHECK-NEXT:    bx lr
498 entry:
499   %0 = load <8 x i16>, <8 x i16>* %mask, align 2
500   %1 = icmp sgt <8 x i16> %0, zeroinitializer
501   %2 = call <8 x i16> @llvm.masked.load.v8i16(<8 x i16>* %src, i32 2, <8 x i1> %1, <8 x i16> undef)
502   %3 = trunc <8 x i16> %2 to <8 x i8>
503   call void @llvm.masked.store.v8i8(<8 x i8> %3, <8 x i8>* %dest, i32 1, <8 x i1> %1)
504   ret void
507 define void @foo_trunc_v4i8_v4i32(<4 x i8> *%dest, <4 x i32> *%mask, <4 x i32> *%src) {
508 ; CHECK-LABEL: foo_trunc_v4i8_v4i32:
509 ; CHECK:       @ %bb.0: @ %entry
510 ; CHECK-NEXT:    .pad #4
511 ; CHECK-NEXT:    sub sp, #4
512 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
513 ; CHECK-NEXT:    movs r3, #0
514 ; CHECK-NEXT:    vpt.s32 gt, q0, zr
515 ; CHECK-NEXT:    vldrwt.u32 q0, [r2]
516 ; CHECK-NEXT:    vmrs r1, p0
517 ; CHECK-NEXT:    and r2, r1, #1
518 ; CHECK-NEXT:    rsbs r2, r2, #0
519 ; CHECK-NEXT:    bfi r3, r2, #0, #1
520 ; CHECK-NEXT:    ubfx r2, r1, #4, #1
521 ; CHECK-NEXT:    rsbs r2, r2, #0
522 ; CHECK-NEXT:    bfi r3, r2, #1, #1
523 ; CHECK-NEXT:    ubfx r2, r1, #8, #1
524 ; CHECK-NEXT:    ubfx r1, r1, #12, #1
525 ; CHECK-NEXT:    rsbs r2, r2, #0
526 ; CHECK-NEXT:    bfi r3, r2, #2, #1
527 ; CHECK-NEXT:    rsbs r1, r1, #0
528 ; CHECK-NEXT:    bfi r3, r1, #3, #1
529 ; CHECK-NEXT:    and r1, r3, #15
530 ; CHECK-NEXT:    lsls r2, r1, #31
531 ; CHECK-NEXT:    itt ne
532 ; CHECK-NEXT:    vmovne r2, s0
533 ; CHECK-NEXT:    strbne r2, [r0]
534 ; CHECK-NEXT:    lsls r2, r1, #30
535 ; CHECK-NEXT:    itt mi
536 ; CHECK-NEXT:    vmovmi r2, s1
537 ; CHECK-NEXT:    strbmi r2, [r0, #1]
538 ; CHECK-NEXT:    lsls r2, r1, #29
539 ; CHECK-NEXT:    itt mi
540 ; CHECK-NEXT:    vmovmi r2, s2
541 ; CHECK-NEXT:    strbmi r2, [r0, #2]
542 ; CHECK-NEXT:    lsls r1, r1, #28
543 ; CHECK-NEXT:    itt mi
544 ; CHECK-NEXT:    vmovmi r1, s3
545 ; CHECK-NEXT:    strbmi r1, [r0, #3]
546 ; CHECK-NEXT:    add sp, #4
547 ; CHECK-NEXT:    bx lr
548 entry:
549   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
550   %1 = icmp sgt <4 x i32> %0, zeroinitializer
551   %2 = call <4 x i32> @llvm.masked.load.v4i32(<4 x i32>* %src, i32 4, <4 x i1> %1, <4 x i32> undef)
552   %3 = trunc <4 x i32> %2 to <4 x i8>
553   call void @llvm.masked.store.v4i8(<4 x i8> %3, <4 x i8>* %dest, i32 1, <4 x i1> %1)
554   ret void
557 define void @foo_trunc_v4i16_v4i32(<4 x i16> *%dest, <4 x i32> *%mask, <4 x i32> *%src) {
558 ; CHECK-LABEL: foo_trunc_v4i16_v4i32:
559 ; CHECK:       @ %bb.0: @ %entry
560 ; CHECK-NEXT:    .pad #4
561 ; CHECK-NEXT:    sub sp, #4
562 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
563 ; CHECK-NEXT:    movs r3, #0
564 ; CHECK-NEXT:    vpt.s32 gt, q0, zr
565 ; CHECK-NEXT:    vldrwt.u32 q0, [r2]
566 ; CHECK-NEXT:    vmrs r1, p0
567 ; CHECK-NEXT:    and r2, r1, #1
568 ; CHECK-NEXT:    rsbs r2, r2, #0
569 ; CHECK-NEXT:    bfi r3, r2, #0, #1
570 ; CHECK-NEXT:    ubfx r2, r1, #4, #1
571 ; CHECK-NEXT:    rsbs r2, r2, #0
572 ; CHECK-NEXT:    bfi r3, r2, #1, #1
573 ; CHECK-NEXT:    ubfx r2, r1, #8, #1
574 ; CHECK-NEXT:    ubfx r1, r1, #12, #1
575 ; CHECK-NEXT:    rsbs r2, r2, #0
576 ; CHECK-NEXT:    bfi r3, r2, #2, #1
577 ; CHECK-NEXT:    rsbs r1, r1, #0
578 ; CHECK-NEXT:    bfi r3, r1, #3, #1
579 ; CHECK-NEXT:    and r1, r3, #15
580 ; CHECK-NEXT:    lsls r2, r1, #31
581 ; CHECK-NEXT:    itt ne
582 ; CHECK-NEXT:    vmovne r2, s0
583 ; CHECK-NEXT:    strhne r2, [r0]
584 ; CHECK-NEXT:    lsls r2, r1, #30
585 ; CHECK-NEXT:    itt mi
586 ; CHECK-NEXT:    vmovmi r2, s1
587 ; CHECK-NEXT:    strhmi r2, [r0, #2]
588 ; CHECK-NEXT:    lsls r2, r1, #29
589 ; CHECK-NEXT:    itt mi
590 ; CHECK-NEXT:    vmovmi r2, s2
591 ; CHECK-NEXT:    strhmi r2, [r0, #4]
592 ; CHECK-NEXT:    lsls r1, r1, #28
593 ; CHECK-NEXT:    itt mi
594 ; CHECK-NEXT:    vmovmi r1, s3
595 ; CHECK-NEXT:    strhmi r1, [r0, #6]
596 ; CHECK-NEXT:    add sp, #4
597 ; CHECK-NEXT:    bx lr
598 entry:
599   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
600   %1 = icmp sgt <4 x i32> %0, zeroinitializer
601   %2 = call <4 x i32> @llvm.masked.load.v4i32(<4 x i32>* %src, i32 4, <4 x i1> %1, <4 x i32> undef)
602   %3 = trunc <4 x i32> %2 to <4 x i16>
603   call void @llvm.masked.store.v4i16(<4 x i16> %3, <4 x i16>* %dest, i32 2, <4 x i1> %1)
604   ret void
607 define void @foo_v4f32_v4f32(<4 x float> *%dest, <4 x i32> *%mask, <4 x float> *%src) {
608 ; CHECK-LABEL: foo_v4f32_v4f32:
609 ; CHECK:       @ %bb.0: @ %entry
610 ; CHECK-NEXT:    vldrw.u32 q0, [r1]
611 ; CHECK-NEXT:    vptt.s32 gt, q0, zr
612 ; CHECK-NEXT:    vldrwt.u32 q0, [r2]
613 ; CHECK-NEXT:    vstrwt.32 q0, [r0]
614 ; CHECK-NEXT:    bx lr
615 entry:
616   %0 = load <4 x i32>, <4 x i32>* %mask, align 4
617   %1 = icmp sgt <4 x i32> %0, zeroinitializer
618   %2 = call <4 x float> @llvm.masked.load.v4f32(<4 x float>* %src, i32 4, <4 x i1> %1, <4 x float> undef)
619   call void @llvm.masked.store.v4f32(<4 x float> %2, <4 x float>* %dest, i32 4, <4 x i1> %1)
620   ret void
623 define void @foo_v8f16_v8f16(<8 x half> *%dest, <8 x i16> *%mask, <8 x half> *%src) {
624 ; CHECK-LABEL: foo_v8f16_v8f16:
625 ; CHECK:       @ %bb.0: @ %entry
626 ; CHECK-NEXT:    vldrh.u16 q0, [r1]
627 ; CHECK-NEXT:    vptt.s16 gt, q0, zr
628 ; CHECK-NEXT:    vldrht.u16 q0, [r2]
629 ; CHECK-NEXT:    vstrht.16 q0, [r0]
630 ; CHECK-NEXT:    bx lr
631 entry:
632   %0 = load <8 x i16>, <8 x i16>* %mask, align 2
633   %1 = icmp sgt <8 x i16> %0, zeroinitializer
634   %2 = call <8 x half> @llvm.masked.load.v8f16(<8 x half>* %src, i32 2, <8 x i1> %1, <8 x half> undef)
635   call void @llvm.masked.store.v8f16(<8 x half> %2, <8 x half>* %dest, i32 2, <8 x i1> %1)
636   ret void
639 declare void @llvm.masked.store.v4i32(<4 x i32>, <4 x i32>*, i32, <4 x i1>)
640 declare void @llvm.masked.store.v8i16(<8 x i16>, <8 x i16>*, i32, <8 x i1>)
641 declare void @llvm.masked.store.v16i8(<16 x i8>, <16 x i8>*, i32, <16 x i1>)
642 declare void @llvm.masked.store.v8f16(<8 x half>, <8 x half>*, i32, <8 x i1>)
643 declare void @llvm.masked.store.v4f32(<4 x float>, <4 x float>*, i32, <4 x i1>)
644 declare <16 x i8> @llvm.masked.load.v16i8(<16 x i8>*, i32, <16 x i1>, <16 x i8>)
645 declare <8 x i16> @llvm.masked.load.v8i16(<8 x i16>*, i32, <8 x i1>, <8 x i16>)
646 declare <4 x i32> @llvm.masked.load.v4i32(<4 x i32>*, i32, <4 x i1>, <4 x i32>)
647 declare <4 x float> @llvm.masked.load.v4f32(<4 x float>*, i32, <4 x i1>, <4 x float>)
648 declare <8 x half> @llvm.masked.load.v8f16(<8 x half>*, i32, <8 x i1>, <8 x half>)
650 declare void @llvm.masked.store.v8i8(<8 x i8>, <8 x i8>*, i32, <8 x i1>)
651 declare void @llvm.masked.store.v4i8(<4 x i8>, <4 x i8>*, i32, <4 x i1>)
652 declare void @llvm.masked.store.v4i16(<4 x i16>, <4 x i16>*, i32, <4 x i1>)
653 declare <4 x i16> @llvm.masked.load.v4i16(<4 x i16>*, i32, <4 x i1>, <4 x i16>)
654 declare <4 x i8> @llvm.masked.load.v4i8(<4 x i8>*, i32, <4 x i1>, <4 x i8>)
655 declare <8 x i8> @llvm.masked.load.v8i8(<8 x i8>*, i32, <8 x i1>, <8 x i8>)