]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/masked_gather_scatter.ll
Vendor import of llvm trunk r306325:
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / masked_gather_scatter.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu  -mattr=+avx512f < %s | FileCheck %s --check-prefix=ALL --check-prefix=KNL_64
3 ; RUN: llc -mtriple=i386-unknown-linux-gnu  -mattr=+avx512f < %s | FileCheck %s --check-prefix=ALL --check-prefix=KNL_32
4 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu  -mattr=+avx512vl -mattr=+avx512dq < %s | FileCheck %s --check-prefix=ALL --check-prefix=SKX
5 ; RUN: llc -mtriple=i386-unknown-linux-gnu  -mattr=+avx512vl -mattr=+avx512dq < %s | FileCheck %s --check-prefix=ALL --check-prefix=SKX_32
6 ; RUN: opt -mtriple=x86_64-apple-darwin -scalarize-masked-mem-intrin -mcpu=corei7-avx -S < %s | FileCheck %s -check-prefix=SCALAR
7 ; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu -mcpu=skx < %s -o /dev/null
8
9 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10 target triple = "x86_64-unknown-linux-gnu"
11
12
13 ; SCALAR-LABEL: test1
14 ; SCALAR:      extractelement <16 x float*>
15 ; SCALAR-NEXT: load float
16 ; SCALAR-NEXT: insertelement <16 x float>
17 ; SCALAR-NEXT: extractelement <16 x float*>
18 ; SCALAR-NEXT: load float
19
20 define <16 x float> @test1(float* %base, <16 x i32> %ind) {
21 ; KNL_64-LABEL: test1:
22 ; KNL_64:       # BB#0:
23 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
24 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
25 ; KNL_64-NEXT:    vmovaps %zmm1, %zmm0
26 ; KNL_64-NEXT:    retq
27 ;
28 ; KNL_32-LABEL: test1:
29 ; KNL_32:       # BB#0:
30 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
31 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
32 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
33 ; KNL_32-NEXT:    vmovaps %zmm1, %zmm0
34 ; KNL_32-NEXT:    retl
35 ;
36 ; SKX-LABEL: test1:
37 ; SKX:       # BB#0:
38 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
39 ; SKX-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
40 ; SKX-NEXT:    vmovaps %zmm1, %zmm0
41 ; SKX-NEXT:    retq
42 ;
43 ; SKX_32-LABEL: test1:
44 ; SKX_32:       # BB#0:
45 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
46 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
47 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
48 ; SKX_32-NEXT:    vmovaps %zmm1, %zmm0
49 ; SKX_32-NEXT:    retl
50
51   %broadcast.splatinsert = insertelement <16 x float*> undef, float* %base, i32 0
52   %broadcast.splat = shufflevector <16 x float*> %broadcast.splatinsert, <16 x float*> undef, <16 x i32> zeroinitializer
53
54   %sext_ind = sext <16 x i32> %ind to <16 x i64>
55   %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind
56
57   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef)
58   ret <16 x float>%res
59 }
60
61 declare <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*>, i32, <16 x i1>, <16 x i32>)
62 declare <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*>, i32, <16 x i1>, <16 x float>)
63 declare <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> , i32, <8 x i1> , <8 x i32> )
64
65
66 ; SCALAR-LABEL: test2
67 ; SCALAR:      extractelement <16 x float*>
68 ; SCALAR-NEXT: load float
69 ; SCALAR-NEXT: insertelement <16 x float>
70 ; SCALAR-NEXT: br label %else
71 ; SCALAR: else:
72 ; SCALAR-NEXT:  %res.phi.else = phi
73 ; SCALAR-NEXT:  %Mask1 = extractelement <16 x i1> %imask, i32 1
74 ; SCALAR-NEXT:  %ToLoad1 = icmp eq i1 %Mask1, true
75 ; SCALAR-NEXT:  br i1 %ToLoad1, label %cond.load1, label %else2
76
77 define <16 x float> @test2(float* %base, <16 x i32> %ind, i16 %mask) {
78 ; KNL_64-LABEL: test2:
79 ; KNL_64:       # BB#0:
80 ; KNL_64-NEXT:    kmovw %esi, %k1
81 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
82 ; KNL_64-NEXT:    vmovaps %zmm1, %zmm0
83 ; KNL_64-NEXT:    retq
84 ;
85 ; KNL_32-LABEL: test2:
86 ; KNL_32:       # BB#0:
87 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
88 ; KNL_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
89 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
90 ; KNL_32-NEXT:    vmovaps %zmm1, %zmm0
91 ; KNL_32-NEXT:    retl
92 ;
93 ; SKX-LABEL: test2:
94 ; SKX:       # BB#0:
95 ; SKX-NEXT:    kmovw %esi, %k1
96 ; SKX-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
97 ; SKX-NEXT:    vmovaps %zmm1, %zmm0
98 ; SKX-NEXT:    retq
99 ;
100 ; SKX_32-LABEL: test2:
101 ; SKX_32:       # BB#0:
102 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
103 ; SKX_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
104 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
105 ; SKX_32-NEXT:    vmovaps %zmm1, %zmm0
106 ; SKX_32-NEXT:    retl
107
108   %broadcast.splatinsert = insertelement <16 x float*> undef, float* %base, i32 0
109   %broadcast.splat = shufflevector <16 x float*> %broadcast.splatinsert, <16 x float*> undef, <16 x i32> zeroinitializer
110
111   %sext_ind = sext <16 x i32> %ind to <16 x i64>
112   %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind
113   %imask = bitcast i16 %mask to <16 x i1>
114   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> %imask, <16 x float>undef)
115   ret <16 x float> %res
116 }
117
118 define <16 x i32> @test3(i32* %base, <16 x i32> %ind, i16 %mask) {
119 ; KNL_64-LABEL: test3:
120 ; KNL_64:       # BB#0:
121 ; KNL_64-NEXT:    kmovw %esi, %k1
122 ; KNL_64-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm1 {%k1}
123 ; KNL_64-NEXT:    vmovdqa64 %zmm1, %zmm0
124 ; KNL_64-NEXT:    retq
125 ;
126 ; KNL_32-LABEL: test3:
127 ; KNL_32:       # BB#0:
128 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
129 ; KNL_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
130 ; KNL_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k1}
131 ; KNL_32-NEXT:    vmovdqa64 %zmm1, %zmm0
132 ; KNL_32-NEXT:    retl
133 ;
134 ; SKX-LABEL: test3:
135 ; SKX:       # BB#0:
136 ; SKX-NEXT:    kmovw %esi, %k1
137 ; SKX-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm1 {%k1}
138 ; SKX-NEXT:    vmovdqa64 %zmm1, %zmm0
139 ; SKX-NEXT:    retq
140 ;
141 ; SKX_32-LABEL: test3:
142 ; SKX_32:       # BB#0:
143 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
144 ; SKX_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
145 ; SKX_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k1}
146 ; SKX_32-NEXT:    vmovdqa64 %zmm1, %zmm0
147 ; SKX_32-NEXT:    retl
148
149   %broadcast.splatinsert = insertelement <16 x i32*> undef, i32* %base, i32 0
150   %broadcast.splat = shufflevector <16 x i32*> %broadcast.splatinsert, <16 x i32*> undef, <16 x i32> zeroinitializer
151
152   %sext_ind = sext <16 x i32> %ind to <16 x i64>
153   %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i64> %sext_ind
154   %imask = bitcast i16 %mask to <16 x i1>
155   %res = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef)
156   ret <16 x i32> %res
157 }
158
159
160 define <16 x i32> @test4(i32* %base, <16 x i32> %ind, i16 %mask) {
161 ; KNL_64-LABEL: test4:
162 ; KNL_64:       # BB#0:
163 ; KNL_64-NEXT:    kmovw %esi, %k1
164 ; KNL_64-NEXT:    kmovw %k1, %k2
165 ; KNL_64-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm1 {%k2}
166 ; KNL_64-NEXT:    vmovdqa64 %zmm1, %zmm2
167 ; KNL_64-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm2 {%k1}
168 ; KNL_64-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
169 ; KNL_64-NEXT:    retq
170 ;
171 ; KNL_32-LABEL: test4:
172 ; KNL_32:       # BB#0:
173 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
174 ; KNL_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
175 ; KNL_32-NEXT:    kmovw %k1, %k2
176 ; KNL_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k2}
177 ; KNL_32-NEXT:    vmovdqa64 %zmm1, %zmm2
178 ; KNL_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm2 {%k1}
179 ; KNL_32-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
180 ; KNL_32-NEXT:    retl
181 ;
182 ; SKX-LABEL: test4:
183 ; SKX:       # BB#0:
184 ; SKX-NEXT:    kmovw %esi, %k1
185 ; SKX-NEXT:    kmovw %k1, %k2
186 ; SKX-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm1 {%k2}
187 ; SKX-NEXT:    vmovdqa64 %zmm1, %zmm2
188 ; SKX-NEXT:    vpgatherdd (%rdi,%zmm0,4), %zmm2 {%k1}
189 ; SKX-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
190 ; SKX-NEXT:    retq
191 ;
192 ; SKX_32-LABEL: test4:
193 ; SKX_32:       # BB#0:
194 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
195 ; SKX_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
196 ; SKX_32-NEXT:    kmovw %k1, %k2
197 ; SKX_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm1 {%k2}
198 ; SKX_32-NEXT:    vmovdqa64 %zmm1, %zmm2
199 ; SKX_32-NEXT:    vpgatherdd (%eax,%zmm0,4), %zmm2 {%k1}
200 ; SKX_32-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
201 ; SKX_32-NEXT:    retl
202
203   %broadcast.splatinsert = insertelement <16 x i32*> undef, i32* %base, i32 0
204   %broadcast.splat = shufflevector <16 x i32*> %broadcast.splatinsert, <16 x i32*> undef, <16 x i32> zeroinitializer
205
206   %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i32> %ind
207   %imask = bitcast i16 %mask to <16 x i1>
208   %gt1 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef)
209   %gt2 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1)
210   %res = add <16 x i32> %gt1, %gt2
211   ret <16 x i32> %res
212 }
213
214
215 ; SCALAR-LABEL: test5
216 ; SCALAR:        %Mask0 = extractelement <16 x i1> %imask, i32 0
217 ; SCALAR-NEXT:   %ToStore0 = icmp eq i1 %Mask0, true
218 ; SCALAR-NEXT:   br i1 %ToStore0, label %cond.store, label %else
219 ; SCALAR: cond.store:
220 ; SCALAR-NEXT:  %Elt0 = extractelement <16 x i32> %val, i32 0
221 ; SCALAR-NEXT:  %Ptr0 = extractelement <16 x i32*> %gep.random, i32 0
222 ; SCALAR-NEXT:  store i32 %Elt0, i32* %Ptr0, align 4
223 ; SCALAR-NEXT:  br label %else
224 ; SCALAR: else:
225 ; SCALAR-NEXT: %Mask1 = extractelement <16 x i1> %imask, i32 1
226 ; SCALAR-NEXT:  %ToStore1 = icmp eq i1 %Mask1, true
227 ; SCALAR-NEXT:  br i1 %ToStore1, label %cond.store1, label %else2
228
229 define void @test5(i32* %base, <16 x i32> %ind, i16 %mask, <16 x i32>%val) {
230 ; KNL_64-LABEL: test5:
231 ; KNL_64:       # BB#0:
232 ; KNL_64-NEXT:    kmovw %esi, %k1
233 ; KNL_64-NEXT:    kmovw %k1, %k2
234 ; KNL_64-NEXT:    vpscatterdd %zmm1, (%rdi,%zmm0,4) {%k2}
235 ; KNL_64-NEXT:    vpscatterdd %zmm1, (%rdi,%zmm0,4) {%k1}
236 ; KNL_64-NEXT:    vzeroupper
237 ; KNL_64-NEXT:    retq
238 ;
239 ; KNL_32-LABEL: test5:
240 ; KNL_32:       # BB#0:
241 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
242 ; KNL_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
243 ; KNL_32-NEXT:    kmovw %k1, %k2
244 ; KNL_32-NEXT:    vpscatterdd %zmm1, (%eax,%zmm0,4) {%k2}
245 ; KNL_32-NEXT:    vpscatterdd %zmm1, (%eax,%zmm0,4) {%k1}
246 ; KNL_32-NEXT:    vzeroupper
247 ; KNL_32-NEXT:    retl
248 ;
249 ; SKX-LABEL: test5:
250 ; SKX:       # BB#0:
251 ; SKX-NEXT:    kmovw %esi, %k1
252 ; SKX-NEXT:    kmovw %k1, %k2
253 ; SKX-NEXT:    vpscatterdd %zmm1, (%rdi,%zmm0,4) {%k2}
254 ; SKX-NEXT:    vpscatterdd %zmm1, (%rdi,%zmm0,4) {%k1}
255 ; SKX-NEXT:    vzeroupper
256 ; SKX-NEXT:    retq
257 ;
258 ; SKX_32-LABEL: test5:
259 ; SKX_32:       # BB#0:
260 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
261 ; SKX_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
262 ; SKX_32-NEXT:    kmovw %k1, %k2
263 ; SKX_32-NEXT:    vpscatterdd %zmm1, (%eax,%zmm0,4) {%k2}
264 ; SKX_32-NEXT:    vpscatterdd %zmm1, (%eax,%zmm0,4) {%k1}
265 ; SKX_32-NEXT:    vzeroupper
266 ; SKX_32-NEXT:    retl
267
268   %broadcast.splatinsert = insertelement <16 x i32*> undef, i32* %base, i32 0
269   %broadcast.splat = shufflevector <16 x i32*> %broadcast.splatinsert, <16 x i32*> undef, <16 x i32> zeroinitializer
270
271   %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i32> %ind
272   %imask = bitcast i16 %mask to <16 x i1>
273   call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask)
274   call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask)
275   ret void
276 }
277
278 declare void @llvm.masked.scatter.v8i32.v8p0i32(<8 x i32> , <8 x i32*> , i32 , <8 x i1> )
279 declare void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32> , <16 x i32*> , i32 , <16 x i1> )
280
281
282 ; SCALAR-LABEL: test6
283 ; SCALAR:        store i32 %Elt0, i32* %Ptr01, align 4
284 ; SCALAR-NEXT:   %Elt1 = extractelement <8 x i32> %a1, i32 1
285 ; SCALAR-NEXT:   %Ptr12 = extractelement <8 x i32*> %ptr, i32 1
286 ; SCALAR-NEXT:   store i32 %Elt1, i32* %Ptr12, align 4
287 ; SCALAR-NEXT:   %Elt2 = extractelement <8 x i32> %a1, i32 2
288 ; SCALAR-NEXT:   %Ptr23 = extractelement <8 x i32*> %ptr, i32 2
289 ; SCALAR-NEXT:   store i32 %Elt2, i32* %Ptr23, align 4
290
291 define <8 x i32> @test6(<8 x i32>%a1, <8 x i32*> %ptr) {
292 ; KNL_64-LABEL: test6:
293 ; KNL_64:       # BB#0:
294 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
295 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k2
296 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
297 ; KNL_64-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
298 ; KNL_64-NEXT:    vmovdqa %ymm2, %ymm0
299 ; KNL_64-NEXT:    retq
300 ;
301 ; KNL_32-LABEL: test6:
302 ; KNL_32:       # BB#0:
303 ; KNL_32-NEXT:    vpmovsxdq %ymm1, %zmm2
304 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
305 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k2
306 ; KNL_32-NEXT:    vpgatherqd (,%zmm2), %ymm1 {%k2}
307 ; KNL_32-NEXT:    vpscatterqd %ymm0, (,%zmm2) {%k1}
308 ; KNL_32-NEXT:    vmovdqa %ymm1, %ymm0
309 ; KNL_32-NEXT:    retl
310 ;
311 ; SKX-LABEL: test6:
312 ; SKX:       # BB#0:
313 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
314 ; SKX-NEXT:    kxnorw %k0, %k0, %k2
315 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
316 ; SKX-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
317 ; SKX-NEXT:    vmovdqa %ymm2, %ymm0
318 ; SKX-NEXT:    retq
319 ;
320 ; SKX_32-LABEL: test6:
321 ; SKX_32:       # BB#0:
322 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
323 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k2
324 ; SKX_32-NEXT:    vpgatherdd (,%ymm1), %ymm2 {%k2}
325 ; SKX_32-NEXT:    vpscatterdd %ymm0, (,%ymm1) {%k1}
326 ; SKX_32-NEXT:    vmovdqa %ymm2, %ymm0
327 ; SKX_32-NEXT:    retl
328
329   %a = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef)
330
331   call void @llvm.masked.scatter.v8i32.v8p0i32(<8 x i32> %a1, <8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>)
332   ret <8 x i32>%a
333 }
334
335 define <8 x i32> @test7(i32* %base, <8 x i32> %ind, i8 %mask) {
336 ;
337 ; KNL_64-LABEL: test7:
338 ; KNL_64:       # BB#0:
339 ; KNL_64-NEXT:    kmovw %esi, %k1
340 ; KNL_64-NEXT:    vpmovsxdq %ymm0, %zmm0
341 ; KNL_64-NEXT:    kmovw %k1, %k2
342 ; KNL_64-NEXT:    vpgatherqd (%rdi,%zmm0,4), %ymm1 {%k2}
343 ; KNL_64-NEXT:    vmovdqa %ymm1, %ymm2
344 ; KNL_64-NEXT:    vpgatherqd (%rdi,%zmm0,4), %ymm2 {%k1}
345 ; KNL_64-NEXT:    vpaddd %ymm2, %ymm1, %ymm0
346 ; KNL_64-NEXT:    retq
347 ;
348 ; KNL_32-LABEL: test7:
349 ; KNL_32:       # BB#0:
350 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
351 ; KNL_32-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
352 ; KNL_32-NEXT:    kmovw %ecx, %k1
353 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm0
354 ; KNL_32-NEXT:    kmovw %k1, %k2
355 ; KNL_32-NEXT:    vpgatherqd (%eax,%zmm0,4), %ymm1 {%k2}
356 ; KNL_32-NEXT:    vmovdqa %ymm1, %ymm2
357 ; KNL_32-NEXT:    vpgatherqd (%eax,%zmm0,4), %ymm2 {%k1}
358 ; KNL_32-NEXT:    vpaddd %ymm2, %ymm1, %ymm0
359 ; KNL_32-NEXT:    retl
360 ;
361 ; SKX-LABEL: test7:
362 ; SKX:       # BB#0:
363 ; SKX-NEXT:    kmovw %esi, %k1
364 ; SKX-NEXT:    kmovw %k1, %k2
365 ; SKX-NEXT:    vpgatherdd (%rdi,%ymm0,4), %ymm1 {%k2}
366 ; SKX-NEXT:    vmovdqa %ymm1, %ymm2
367 ; SKX-NEXT:    vpgatherdd (%rdi,%ymm0,4), %ymm2 {%k1}
368 ; SKX-NEXT:    vpaddd %ymm2, %ymm1, %ymm0
369 ; SKX-NEXT:    retq
370 ;
371 ; SKX_32-LABEL: test7:
372 ; SKX_32:       # BB#0:
373 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
374 ; SKX_32-NEXT:    kmovb {{[0-9]+}}(%esp), %k1
375 ; SKX_32-NEXT:    kmovw %k1, %k2
376 ; SKX_32-NEXT:    vpgatherdd (%eax,%ymm0,4), %ymm1 {%k2}
377 ; SKX_32-NEXT:    vmovdqa %ymm1, %ymm2
378 ; SKX_32-NEXT:    vpgatherdd (%eax,%ymm0,4), %ymm2 {%k1}
379 ; SKX_32-NEXT:    vpaddd %ymm2, %ymm1, %ymm0
380 ; SKX_32-NEXT:    retl
381
382   %broadcast.splatinsert = insertelement <8 x i32*> undef, i32* %base, i32 0
383   %broadcast.splat = shufflevector <8 x i32*> %broadcast.splatinsert, <8 x i32*> undef, <8 x i32> zeroinitializer
384
385   %gep.random = getelementptr i32, <8 x i32*> %broadcast.splat, <8 x i32> %ind
386   %imask = bitcast i8 %mask to <8 x i1>
387   %gt1 = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>undef)
388   %gt2 = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>%gt1)
389   %res = add <8 x i32> %gt1, %gt2
390   ret <8 x i32> %res
391 }
392
393 ; No uniform base in this case, index <8 x i64> contains addresses,
394 ; each gather call will be split into two
395 define <16 x i32> @test8(<16 x i32*> %ptr.random, <16 x i32> %ind, i16 %mask) {
396 ; KNL_64-LABEL: test8:
397 ; KNL_64:       # BB#0:
398 ; KNL_64-NEXT:    kmovw %edi, %k1
399 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
400 ; KNL_64-NEXT:    kmovw %k2, %k3
401 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k3}
402 ; KNL_64-NEXT:    kmovw %k1, %k3
403 ; KNL_64-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k3}
404 ; KNL_64-NEXT:    vinserti64x4 $1, %ymm2, %zmm3, %zmm4
405 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
406 ; KNL_64-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k1}
407 ; KNL_64-NEXT:    vinserti64x4 $1, %ymm2, %zmm3, %zmm0
408 ; KNL_64-NEXT:    vpaddd %zmm0, %zmm4, %zmm0
409 ; KNL_64-NEXT:    retq
410 ;
411 ; KNL_32-LABEL: test8:
412 ; KNL_32:       # BB#0:
413 ; KNL_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
414 ; KNL_32-NEXT:    kmovw %k1, %k2
415 ; KNL_32-NEXT:    vpgatherdd (,%zmm0), %zmm1 {%k2}
416 ; KNL_32-NEXT:    vmovdqa64 %zmm1, %zmm2
417 ; KNL_32-NEXT:    vpgatherdd (,%zmm0), %zmm2 {%k1}
418 ; KNL_32-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
419 ; KNL_32-NEXT:    retl
420 ;
421 ; SKX-LABEL: test8:
422 ; SKX:       # BB#0:
423 ; SKX-NEXT:    kmovw %edi, %k1
424 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
425 ; SKX-NEXT:    kmovw %k2, %k3
426 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k3}
427 ; SKX-NEXT:    kmovw %k1, %k3
428 ; SKX-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k3}
429 ; SKX-NEXT:    vinserti32x8 $1, %ymm2, %zmm3, %zmm4
430 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
431 ; SKX-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k1}
432 ; SKX-NEXT:    vinserti32x8 $1, %ymm2, %zmm3, %zmm0
433 ; SKX-NEXT:    vpaddd %zmm0, %zmm4, %zmm0
434 ; SKX-NEXT:    retq
435 ;
436 ; SKX_32-LABEL: test8:
437 ; SKX_32:       # BB#0:
438 ; SKX_32-NEXT:    kmovw {{[0-9]+}}(%esp), %k1
439 ; SKX_32-NEXT:    kmovw %k1, %k2
440 ; SKX_32-NEXT:    vpgatherdd (,%zmm0), %zmm1 {%k2}
441 ; SKX_32-NEXT:    vmovdqa64 %zmm1, %zmm2
442 ; SKX_32-NEXT:    vpgatherdd (,%zmm0), %zmm2 {%k1}
443 ; SKX_32-NEXT:    vpaddd %zmm2, %zmm1, %zmm0
444 ; SKX_32-NEXT:    retl
445
446   %imask = bitcast i16 %mask to <16 x i1>
447   %gt1 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>undef)
448   %gt2 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1)
449   %res = add <16 x i32> %gt1, %gt2
450   ret <16 x i32> %res
451 }
452
453 %struct.RT = type { i8, [10 x [20 x i32]], i8 }
454 %struct.ST = type { i32, double, %struct.RT }
455
456 ; Masked gather for agregate types
457 ; Test9 and Test10 should give the same result (scalar and vector indices in GEP)
458
459
460 define <8 x i32> @test9(%struct.ST* %base, <8 x i64> %ind1, <8 x i32>%ind5) {
461 ; KNL_64-LABEL: test9:
462 ; KNL_64:       # BB#0: # %entry
463 ; KNL_64-NEXT:    vpbroadcastq %rdi, %zmm2
464 ; KNL_64-NEXT:    vpbroadcastq {{.*}}(%rip), %zmm3
465 ; KNL_64-NEXT:    vpmuludq %zmm3, %zmm0, %zmm4
466 ; KNL_64-NEXT:    vpsrlq $32, %zmm0, %zmm0
467 ; KNL_64-NEXT:    vpmuludq %zmm3, %zmm0, %zmm0
468 ; KNL_64-NEXT:    vpsllq $32, %zmm0, %zmm0
469 ; KNL_64-NEXT:    vpaddq %zmm2, %zmm0, %zmm0
470 ; KNL_64-NEXT:    vpmovsxdq %ymm1, %zmm1
471 ; KNL_64-NEXT:    vpmuldq {{.*}}(%rip){1to8}, %zmm1, %zmm1
472 ; KNL_64-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
473 ; KNL_64-NEXT:    vpaddq %zmm0, %zmm4, %zmm0
474 ; KNL_64-NEXT:    vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm1
475 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
476 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
477 ; KNL_64-NEXT:    retq
478 ;
479 ; KNL_32-LABEL: test9:
480 ; KNL_32:       # BB#0: # %entry
481 ; KNL_32-NEXT:    vpbroadcastd {{[0-9]+}}(%esp), %ymm2
482 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm3
483 ; KNL_32-NEXT:    vpmulld %ymm3, %ymm1, %ymm1
484 ; KNL_32-NEXT:    vpmovqd %zmm0, %ymm0
485 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm3
486 ; KNL_32-NEXT:    vpmulld %ymm3, %ymm0, %ymm0
487 ; KNL_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
488 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm1
489 ; KNL_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
490 ; KNL_32-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
491 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm1
492 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
493 ; KNL_32-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
494 ; KNL_32-NEXT:    retl
495 ;
496 ; SKX-LABEL: test9:
497 ; SKX:       # BB#0: # %entry
498 ; SKX-NEXT:    vpbroadcastq %rdi, %zmm2
499 ; SKX-NEXT:    vpmullq {{.*}}(%rip){1to8}, %zmm0, %zmm0
500 ; SKX-NEXT:    vpmovsxdq %ymm1, %zmm1
501 ; SKX-NEXT:    vpmullq {{.*}}(%rip){1to8}, %zmm1, %zmm1
502 ; SKX-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
503 ; SKX-NEXT:    vpaddq %zmm0, %zmm2, %zmm0
504 ; SKX-NEXT:    vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm1
505 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
506 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
507 ; SKX-NEXT:    retq
508 ;
509 ; SKX_32-LABEL: test9:
510 ; SKX_32:       # BB#0: # %entry
511 ; SKX_32-NEXT:    vpmulld {{\.LCPI.*}}{1to8}, %ymm1, %ymm1
512 ; SKX_32-NEXT:    vpmovqd %zmm0, %ymm0
513 ; SKX_32-NEXT:    vpmulld {{\.LCPI.*}}{1to8}, %ymm0, %ymm0
514 ; SKX_32-NEXT:    vpaddd {{[0-9]+}}(%esp){1to8}, %ymm0, %ymm0
515 ; SKX_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
516 ; SKX_32-NEXT:    vpaddd {{\.LCPI.*}}{1to8}, %ymm0, %ymm1
517 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
518 ; SKX_32-NEXT:    vpgatherdd (,%ymm1), %ymm0 {%k1}
519 ; SKX_32-NEXT:    retl
520 entry:
521   %broadcast.splatinsert = insertelement <8 x %struct.ST*> undef, %struct.ST* %base, i32 0
522   %broadcast.splat = shufflevector <8 x %struct.ST*> %broadcast.splatinsert, <8 x %struct.ST*> undef, <8 x i32> zeroinitializer
523
524   %arrayidx = getelementptr  %struct.ST, <8 x %struct.ST*> %broadcast.splat, <8 x i64> %ind1, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>, <8 x i32><i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, <8 x i32> %ind5, <8 x i64> <i64 13, i64 13, i64 13, i64 13, i64 13, i64 13, i64 13, i64 13>
525   %res = call <8 x i32 >  @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef)
526   ret <8 x i32> %res
527 }
528
529 define <8 x i32> @test10(%struct.ST* %base, <8 x i64> %i1, <8 x i32>%ind5) {
530 ; KNL_64-LABEL: test10:
531 ; KNL_64:       # BB#0: # %entry
532 ; KNL_64-NEXT:    vpbroadcastq %rdi, %zmm2
533 ; KNL_64-NEXT:    vpbroadcastq {{.*}}(%rip), %zmm3
534 ; KNL_64-NEXT:    vpmuludq %zmm3, %zmm0, %zmm4
535 ; KNL_64-NEXT:    vpsrlq $32, %zmm0, %zmm0
536 ; KNL_64-NEXT:    vpmuludq %zmm3, %zmm0, %zmm0
537 ; KNL_64-NEXT:    vpsllq $32, %zmm0, %zmm0
538 ; KNL_64-NEXT:    vpaddq %zmm2, %zmm0, %zmm0
539 ; KNL_64-NEXT:    vpmovsxdq %ymm1, %zmm1
540 ; KNL_64-NEXT:    vpmuldq {{.*}}(%rip){1to8}, %zmm1, %zmm1
541 ; KNL_64-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
542 ; KNL_64-NEXT:    vpaddq %zmm0, %zmm4, %zmm0
543 ; KNL_64-NEXT:    vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm1
544 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
545 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
546 ; KNL_64-NEXT:    retq
547 ;
548 ; KNL_32-LABEL: test10:
549 ; KNL_32:       # BB#0: # %entry
550 ; KNL_32-NEXT:    vpbroadcastd {{[0-9]+}}(%esp), %ymm2
551 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm3
552 ; KNL_32-NEXT:    vpmulld %ymm3, %ymm1, %ymm1
553 ; KNL_32-NEXT:    vpmovqd %zmm0, %ymm0
554 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm3
555 ; KNL_32-NEXT:    vpmulld %ymm3, %ymm0, %ymm0
556 ; KNL_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
557 ; KNL_32-NEXT:    vpbroadcastd {{\.LCPI.*}}, %ymm1
558 ; KNL_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
559 ; KNL_32-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
560 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm1
561 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
562 ; KNL_32-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
563 ; KNL_32-NEXT:    retl
564 ;
565 ; SKX-LABEL: test10:
566 ; SKX:       # BB#0: # %entry
567 ; SKX-NEXT:    vpbroadcastq %rdi, %zmm2
568 ; SKX-NEXT:    vpmullq {{.*}}(%rip){1to8}, %zmm0, %zmm0
569 ; SKX-NEXT:    vpmovsxdq %ymm1, %zmm1
570 ; SKX-NEXT:    vpmullq {{.*}}(%rip){1to8}, %zmm1, %zmm1
571 ; SKX-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
572 ; SKX-NEXT:    vpaddq %zmm0, %zmm2, %zmm0
573 ; SKX-NEXT:    vpaddq {{.*}}(%rip){1to8}, %zmm0, %zmm1
574 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
575 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm0 {%k1}
576 ; SKX-NEXT:    retq
577 ;
578 ; SKX_32-LABEL: test10:
579 ; SKX_32:       # BB#0: # %entry
580 ; SKX_32-NEXT:    vpmulld {{\.LCPI.*}}{1to8}, %ymm1, %ymm1
581 ; SKX_32-NEXT:    vpmovqd %zmm0, %ymm0
582 ; SKX_32-NEXT:    vpmulld {{\.LCPI.*}}{1to8}, %ymm0, %ymm0
583 ; SKX_32-NEXT:    vpaddd {{[0-9]+}}(%esp){1to8}, %ymm0, %ymm0
584 ; SKX_32-NEXT:    vpaddd %ymm1, %ymm0, %ymm0
585 ; SKX_32-NEXT:    vpaddd {{\.LCPI.*}}{1to8}, %ymm0, %ymm1
586 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
587 ; SKX_32-NEXT:    vpgatherdd (,%ymm1), %ymm0 {%k1}
588 ; SKX_32-NEXT:    retl
589 entry:
590   %broadcast.splatinsert = insertelement <8 x %struct.ST*> undef, %struct.ST* %base, i32 0
591   %broadcast.splat = shufflevector <8 x %struct.ST*> %broadcast.splatinsert, <8 x %struct.ST*> undef, <8 x i32> zeroinitializer
592
593   %arrayidx = getelementptr  %struct.ST, <8 x %struct.ST*> %broadcast.splat, <8 x i64> %i1, i32 2, i32 1, <8 x i32> %ind5, i64 13
594   %res = call <8 x i32 >  @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef)
595   ret <8 x i32> %res
596 }
597
598 ; Splat index in GEP, requires broadcast
599 define <16 x float> @test11(float* %base, i32 %ind) {
600 ; KNL_64-LABEL: test11:
601 ; KNL_64:       # BB#0:
602 ; KNL_64-NEXT:    vpbroadcastd %esi, %zmm1
603 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
604 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm1,4), %zmm0 {%k1}
605 ; KNL_64-NEXT:    retq
606 ;
607 ; KNL_32-LABEL: test11:
608 ; KNL_32:       # BB#0:
609 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
610 ; KNL_32-NEXT:    vbroadcastss {{[0-9]+}}(%esp), %zmm1
611 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
612 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm1,4), %zmm0 {%k1}
613 ; KNL_32-NEXT:    retl
614 ;
615 ; SKX-LABEL: test11:
616 ; SKX:       # BB#0:
617 ; SKX-NEXT:    vpbroadcastd %esi, %zmm1
618 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
619 ; SKX-NEXT:    vgatherdps (%rdi,%zmm1,4), %zmm0 {%k1}
620 ; SKX-NEXT:    retq
621 ;
622 ; SKX_32-LABEL: test11:
623 ; SKX_32:       # BB#0:
624 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
625 ; SKX_32-NEXT:    vbroadcastss {{[0-9]+}}(%esp), %zmm1
626 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
627 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm1,4), %zmm0 {%k1}
628 ; SKX_32-NEXT:    retl
629
630   %broadcast.splatinsert = insertelement <16 x float*> undef, float* %base, i32 0
631   %broadcast.splat = shufflevector <16 x float*> %broadcast.splatinsert, <16 x float*> undef, <16 x i32> zeroinitializer
632
633   %gep.random = getelementptr float, <16 x float*> %broadcast.splat, i32 %ind
634
635   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef)
636   ret <16 x float>%res
637 }
638
639 ; We are checking the uniform base here. It is taken directly from input to vgatherdps
640 define <16 x float> @test12(float* %base, <16 x i32> %ind) {
641 ; KNL_64-LABEL: test12:
642 ; KNL_64:       # BB#0:
643 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
644 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
645 ; KNL_64-NEXT:    vmovaps %zmm1, %zmm0
646 ; KNL_64-NEXT:    retq
647 ;
648 ; KNL_32-LABEL: test12:
649 ; KNL_32:       # BB#0:
650 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
651 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
652 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
653 ; KNL_32-NEXT:    vmovaps %zmm1, %zmm0
654 ; KNL_32-NEXT:    retl
655 ;
656 ; SKX-LABEL: test12:
657 ; SKX:       # BB#0:
658 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
659 ; SKX-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
660 ; SKX-NEXT:    vmovaps %zmm1, %zmm0
661 ; SKX-NEXT:    retq
662 ;
663 ; SKX_32-LABEL: test12:
664 ; SKX_32:       # BB#0:
665 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
666 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
667 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
668 ; SKX_32-NEXT:    vmovaps %zmm1, %zmm0
669 ; SKX_32-NEXT:    retl
670
671   %sext_ind = sext <16 x i32> %ind to <16 x i64>
672   %gep.random = getelementptr float, float *%base, <16 x i64> %sext_ind
673
674   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef)
675   ret <16 x float>%res
676 }
677
678 ; The same as the previous, but the mask is undefined
679 define <16 x float> @test13(float* %base, <16 x i32> %ind) {
680 ; KNL_64-LABEL: test13:
681 ; KNL_64:       # BB#0:
682 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
683 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
684 ; KNL_64-NEXT:    vmovaps %zmm1, %zmm0
685 ; KNL_64-NEXT:    retq
686 ;
687 ; KNL_32-LABEL: test13:
688 ; KNL_32:       # BB#0:
689 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
690 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
691 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
692 ; KNL_32-NEXT:    vmovaps %zmm1, %zmm0
693 ; KNL_32-NEXT:    retl
694 ;
695 ; SKX-LABEL: test13:
696 ; SKX:       # BB#0:
697 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
698 ; SKX-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
699 ; SKX-NEXT:    vmovaps %zmm1, %zmm0
700 ; SKX-NEXT:    retq
701 ;
702 ; SKX_32-LABEL: test13:
703 ; SKX_32:       # BB#0:
704 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
705 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
706 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
707 ; SKX_32-NEXT:    vmovaps %zmm1, %zmm0
708 ; SKX_32-NEXT:    retl
709
710   %sext_ind = sext <16 x i32> %ind to <16 x i64>
711   %gep.random = getelementptr float, float *%base, <16 x i64> %sext_ind
712
713   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef)
714   ret <16 x float>%res
715 }
716
717 ; The base pointer is not splat, can't find unform base
718 define <16 x float> @test14(float* %base, i32 %ind, <16 x float*> %vec) {
719 ; KNL_64-LABEL: test14:
720 ; KNL_64:       # BB#0:
721 ; KNL_64-NEXT:    vpinsrq $1, %rdi, %xmm0, %xmm0
722 ; KNL_64-NEXT:    vpbroadcastq %xmm0, %zmm0
723 ; KNL_64-NEXT:    vmovd %esi, %xmm1
724 ; KNL_64-NEXT:    vpbroadcastd %xmm1, %ymm1
725 ; KNL_64-NEXT:    vpmovsxdq %ymm1, %zmm1
726 ; KNL_64-NEXT:    vpsllq $2, %zmm1, %zmm1
727 ; KNL_64-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
728 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
729 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
730 ; KNL_64-NEXT:    vgatherqps (,%zmm0), %ymm1 {%k2}
731 ; KNL_64-NEXT:    vgatherqps (,%zmm0), %ymm2 {%k1}
732 ; KNL_64-NEXT:    vinsertf64x4 $1, %ymm1, %zmm2, %zmm0
733 ; KNL_64-NEXT:    retq
734 ;
735 ; KNL_32-LABEL: test14:
736 ; KNL_32:       # BB#0:
737 ; KNL_32-NEXT:    vpinsrd $1, {{[0-9]+}}(%esp), %xmm0, %xmm0
738 ; KNL_32-NEXT:    vpbroadcastd %xmm0, %zmm0
739 ; KNL_32-NEXT:    vpslld $2, {{[0-9]+}}(%esp){1to16}, %zmm1
740 ; KNL_32-NEXT:    vpaddd %zmm1, %zmm0, %zmm1
741 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
742 ; KNL_32-NEXT:    vgatherdps (,%zmm1), %zmm0 {%k1}
743 ; KNL_32-NEXT:    retl
744 ;
745 ; SKX-LABEL: test14:
746 ; SKX:       # BB#0:
747 ; SKX-NEXT:    vpinsrq $1, %rdi, %xmm0, %xmm0
748 ; SKX-NEXT:    vpbroadcastq %xmm0, %zmm0
749 ; SKX-NEXT:    vpbroadcastd %esi, %ymm1
750 ; SKX-NEXT:    vpmovsxdq %ymm1, %zmm1
751 ; SKX-NEXT:    vpsllq $2, %zmm1, %zmm1
752 ; SKX-NEXT:    vpaddq %zmm1, %zmm0, %zmm0
753 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
754 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
755 ; SKX-NEXT:    vgatherqps (,%zmm0), %ymm1 {%k2}
756 ; SKX-NEXT:    vgatherqps (,%zmm0), %ymm2 {%k1}
757 ; SKX-NEXT:    vinsertf32x8 $1, %ymm1, %zmm2, %zmm0
758 ; SKX-NEXT:    retq
759 ;
760 ; SKX_32-LABEL: test14:
761 ; SKX_32:       # BB#0:
762 ; SKX_32-NEXT:    vpinsrd $1, {{[0-9]+}}(%esp), %xmm0, %xmm0
763 ; SKX_32-NEXT:    vpbroadcastd %xmm0, %zmm0
764 ; SKX_32-NEXT:    vpslld $2, {{[0-9]+}}(%esp){1to16}, %zmm1
765 ; SKX_32-NEXT:    vpaddd %zmm1, %zmm0, %zmm1
766 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
767 ; SKX_32-NEXT:    vgatherdps (,%zmm1), %zmm0 {%k1}
768 ; SKX_32-NEXT:    retl
769
770   %broadcast.splatinsert = insertelement <16 x float*> %vec, float* %base, i32 1
771   %broadcast.splat = shufflevector <16 x float*> %broadcast.splatinsert, <16 x float*> undef, <16 x i32> zeroinitializer
772
773   %gep.random = getelementptr float, <16 x float*> %broadcast.splat, i32 %ind
774
775   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef)
776   ret <16 x float>%res
777 }
778
779 declare <4 x float> @llvm.masked.gather.v4f32.v4p0f32(<4 x float*>, i32, <4 x i1>, <4 x float>)
780 declare <4 x double> @llvm.masked.gather.v4f64.v4p0f64(<4 x double*>, i32, <4 x i1>, <4 x double>)
781 declare <2 x double> @llvm.masked.gather.v2f64.v2p0f64(<2 x double*>, i32, <2 x i1>, <2 x double>)
782
783 ; Gather smaller than existing instruction
784 define <4 x float> @test15(float* %base, <4 x i32> %ind, <4 x i1> %mask) {
785 ;
786 ; KNL_64-LABEL: test15:
787 ; KNL_64:       # BB#0:
788 ; KNL_64-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
789 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
790 ; KNL_64-NEXT:    vpxor %ymm2, %ymm2, %ymm2
791 ; KNL_64-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm2[4,5,6,7]
792 ; KNL_64-NEXT:    vpmovsxdq %ymm0, %zmm2
793 ; KNL_64-NEXT:    vpslld $31, %ymm1, %ymm0
794 ; KNL_64-NEXT:    vptestmd %zmm0, %zmm0, %k1
795 ; KNL_64-NEXT:    vgatherqps (%rdi,%zmm2,4), %ymm0 {%k1}
796 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<kill>
797 ; KNL_64-NEXT:    vzeroupper
798 ; KNL_64-NEXT:    retq
799 ;
800 ; KNL_32-LABEL: test15:
801 ; KNL_32:       # BB#0:
802 ; KNL_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
803 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
804 ; KNL_32-NEXT:    vpxor %ymm2, %ymm2, %ymm2
805 ; KNL_32-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm2[4,5,6,7]
806 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
807 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm2
808 ; KNL_32-NEXT:    vpslld $31, %ymm1, %ymm0
809 ; KNL_32-NEXT:    vptestmd %zmm0, %zmm0, %k1
810 ; KNL_32-NEXT:    vgatherqps (%eax,%zmm2,4), %ymm0 {%k1}
811 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<kill>
812 ; KNL_32-NEXT:    vzeroupper
813 ; KNL_32-NEXT:    retl
814 ;
815 ; SKX-LABEL: test15:
816 ; SKX:       # BB#0:
817 ; SKX-NEXT:    vpslld $31, %xmm1, %xmm1
818 ; SKX-NEXT:    vptestmd %xmm1, %xmm1, %k1
819 ; SKX-NEXT:    vgatherdps (%rdi,%xmm0,4), %xmm1 {%k1}
820 ; SKX-NEXT:    vmovaps %xmm1, %xmm0
821 ; SKX-NEXT:    retq
822 ;
823 ; SKX_32-LABEL: test15:
824 ; SKX_32:       # BB#0:
825 ; SKX_32-NEXT:    vpslld $31, %xmm1, %xmm1
826 ; SKX_32-NEXT:    vptestmd %xmm1, %xmm1, %k1
827 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
828 ; SKX_32-NEXT:    vgatherdps (%eax,%xmm0,4), %xmm1 {%k1}
829 ; SKX_32-NEXT:    vmovaps %xmm1, %xmm0
830 ; SKX_32-NEXT:    retl
831
832   %sext_ind = sext <4 x i32> %ind to <4 x i64>
833   %gep.random = getelementptr float, float* %base, <4 x i64> %sext_ind
834   %res = call <4 x float> @llvm.masked.gather.v4f32.v4p0f32(<4 x float*> %gep.random, i32 4, <4 x i1> %mask, <4 x float> undef)
835   ret <4 x float>%res
836 }
837
838 ; Gather smaller than existing instruction
839 define <4 x double> @test16(double* %base, <4 x i32> %ind, <4 x i1> %mask, <4 x double> %src0) {
840 ;
841 ; KNL_64-LABEL: test16:
842 ; KNL_64:       # BB#0:
843 ; KNL_64-NEXT:    # kill: %YMM2<def> %YMM2<kill> %ZMM2<def>
844 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
845 ; KNL_64-NEXT:    vpslld $31, %xmm1, %xmm1
846 ; KNL_64-NEXT:    vpsrad $31, %xmm1, %xmm1
847 ; KNL_64-NEXT:    vpmovsxdq %xmm1, %ymm1
848 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
849 ; KNL_64-NEXT:    vinserti64x4 $0, %ymm1, %zmm3, %zmm1
850 ; KNL_64-NEXT:    vpmovsxdq %ymm0, %zmm0
851 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
852 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
853 ; KNL_64-NEXT:    vgatherqpd (%rdi,%zmm0,8), %zmm2 {%k1}
854 ; KNL_64-NEXT:    vmovapd %ymm2, %ymm0
855 ; KNL_64-NEXT:    retq
856 ;
857 ; KNL_32-LABEL: test16:
858 ; KNL_32:       # BB#0:
859 ; KNL_32-NEXT:    # kill: %YMM2<def> %YMM2<kill> %ZMM2<def>
860 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
861 ; KNL_32-NEXT:    vpslld $31, %xmm1, %xmm1
862 ; KNL_32-NEXT:    vpsrad $31, %xmm1, %xmm1
863 ; KNL_32-NEXT:    vpmovsxdq %xmm1, %ymm1
864 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
865 ; KNL_32-NEXT:    vinserti64x4 $0, %ymm1, %zmm3, %zmm1
866 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
867 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm0
868 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
869 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
870 ; KNL_32-NEXT:    vgatherqpd (%eax,%zmm0,8), %zmm2 {%k1}
871 ; KNL_32-NEXT:    vmovapd %ymm2, %ymm0
872 ; KNL_32-NEXT:    retl
873 ;
874 ; SKX-LABEL: test16:
875 ; SKX:       # BB#0:
876 ; SKX-NEXT:    vpslld $31, %xmm1, %xmm1
877 ; SKX-NEXT:    vptestmd %xmm1, %xmm1, %k1
878 ; SKX-NEXT:    vgatherdpd (%rdi,%xmm0,8), %ymm2 {%k1}
879 ; SKX-NEXT:    vmovapd %ymm2, %ymm0
880 ; SKX-NEXT:    retq
881 ;
882 ; SKX_32-LABEL: test16:
883 ; SKX_32:       # BB#0:
884 ; SKX_32-NEXT:    vpslld $31, %xmm1, %xmm1
885 ; SKX_32-NEXT:    vptestmd %xmm1, %xmm1, %k1
886 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
887 ; SKX_32-NEXT:    vgatherdpd (%eax,%xmm0,8), %ymm2 {%k1}
888 ; SKX_32-NEXT:    vmovapd %ymm2, %ymm0
889 ; SKX_32-NEXT:    retl
890
891   %sext_ind = sext <4 x i32> %ind to <4 x i64>
892   %gep.random = getelementptr double, double* %base, <4 x i64> %sext_ind
893   %res = call <4 x double> @llvm.masked.gather.v4f64.v4p0f64(<4 x double*> %gep.random, i32 4, <4 x i1> %mask, <4 x double> %src0)
894   ret <4 x double>%res
895 }
896
897 define <2 x double> @test17(double* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x double> %src0) {
898 ;
899 ; KNL_64-LABEL: test17:
900 ; KNL_64:       # BB#0:
901 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
902 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
903 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
904 ; KNL_64-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
905 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
906 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
907 ; KNL_64-NEXT:    vgatherqpd (%rdi,%zmm0,8), %zmm2 {%k1}
908 ; KNL_64-NEXT:    vmovapd %xmm2, %xmm0
909 ; KNL_64-NEXT:    vzeroupper
910 ; KNL_64-NEXT:    retq
911 ;
912 ; KNL_32-LABEL: test17:
913 ; KNL_32:       # BB#0:
914 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
915 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
916 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
917 ; KNL_32-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
918 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
919 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
920 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
921 ; KNL_32-NEXT:    vgatherqpd (%eax,%zmm0,8), %zmm2 {%k1}
922 ; KNL_32-NEXT:    vmovapd %xmm2, %xmm0
923 ; KNL_32-NEXT:    vzeroupper
924 ; KNL_32-NEXT:    retl
925 ;
926 ; SKX-LABEL: test17:
927 ; SKX:       # BB#0:
928 ; SKX-NEXT:    vpsllq $63, %xmm1, %xmm1
929 ; SKX-NEXT:    vptestmq %xmm1, %xmm1, %k1
930 ; SKX-NEXT:    vgatherqpd (%rdi,%xmm0,8), %xmm2 {%k1}
931 ; SKX-NEXT:    vmovapd %xmm2, %xmm0
932 ; SKX-NEXT:    retq
933 ;
934 ; SKX_32-LABEL: test17:
935 ; SKX_32:       # BB#0:
936 ; SKX_32-NEXT:    vpsllq $63, %xmm1, %xmm1
937 ; SKX_32-NEXT:    vptestmq %xmm1, %xmm1, %k1
938 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
939 ; SKX_32-NEXT:    vgatherqpd (%eax,%xmm0,8), %xmm2 {%k1}
940 ; SKX_32-NEXT:    vmovapd %xmm2, %xmm0
941 ; SKX_32-NEXT:    retl
942
943   %sext_ind = sext <2 x i32> %ind to <2 x i64>
944   %gep.random = getelementptr double, double* %base, <2 x i64> %sext_ind
945   %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0f64(<2 x double*> %gep.random, i32 4, <2 x i1> %mask, <2 x double> %src0)
946   ret <2 x double>%res
947 }
948
949 declare void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> , <4 x i32*> , i32 , <4 x i1> )
950 declare void @llvm.masked.scatter.v4f64.v4p0f64(<4 x double> , <4 x double*> , i32 , <4 x i1> )
951 declare void @llvm.masked.scatter.v2i64.v2p0i64(<2 x i64> , <2 x i64*> , i32 , <2 x i1> )
952 declare void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> , <2 x i32*> , i32 , <2 x i1> )
953 declare void @llvm.masked.scatter.v2f32.v2p0f32(<2 x float> , <2 x float*> , i32 , <2 x i1> )
954
955 define void @test18(<4 x i32>%a1, <4 x i32*> %ptr, <4 x i1>%mask) {
956 ;
957 ; KNL_64-LABEL: test18:
958 ; KNL_64:       # BB#0:
959 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
960 ; KNL_64-NEXT:    # kill: %YMM1<def> %YMM1<kill> %ZMM1<def>
961 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
962 ; KNL_64-NEXT:    vpxor %ymm3, %ymm3, %ymm3
963 ; KNL_64-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0,1,2,3],ymm3[4,5,6,7]
964 ; KNL_64-NEXT:    vpslld $31, %ymm2, %ymm2
965 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
966 ; KNL_64-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
967 ; KNL_64-NEXT:    vzeroupper
968 ; KNL_64-NEXT:    retq
969 ;
970 ; KNL_32-LABEL: test18:
971 ; KNL_32:       # BB#0:
972 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
973 ; KNL_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
974 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
975 ; KNL_32-NEXT:    vpxor %ymm3, %ymm3, %ymm3
976 ; KNL_32-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0,1,2,3],ymm3[4,5,6,7]
977 ; KNL_32-NEXT:    vpmovsxdq %ymm1, %zmm1
978 ; KNL_32-NEXT:    vpslld $31, %ymm2, %ymm2
979 ; KNL_32-NEXT:    vptestmd %zmm2, %zmm2, %k1
980 ; KNL_32-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
981 ; KNL_32-NEXT:    vzeroupper
982 ; KNL_32-NEXT:    retl
983 ;
984 ; SKX-LABEL: test18:
985 ; SKX:       # BB#0:
986 ; SKX-NEXT:    vpslld $31, %xmm2, %xmm2
987 ; SKX-NEXT:    vptestmd %xmm2, %xmm2, %k1
988 ; SKX-NEXT:    vpscatterqd %xmm0, (,%ymm1) {%k1}
989 ; SKX-NEXT:    vzeroupper
990 ; SKX-NEXT:    retq
991 ;
992 ; SKX_32-LABEL: test18:
993 ; SKX_32:       # BB#0:
994 ; SKX_32-NEXT:    vpslld $31, %xmm2, %xmm2
995 ; SKX_32-NEXT:    vptestmd %xmm2, %xmm2, %k1
996 ; SKX_32-NEXT:    vpscatterdd %xmm0, (,%xmm1) {%k1}
997 ; SKX_32-NEXT:    retl
998   call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> %a1, <4 x i32*> %ptr, i32 4, <4 x i1> %mask)
999   ret void
1000 }
1001
1002 define void @test19(<4 x double>%a1, double* %ptr, <4 x i1>%mask, <4 x i64> %ind) {
1003 ;
1004 ; KNL_64-LABEL: test19:
1005 ; KNL_64:       # BB#0:
1006 ; KNL_64-NEXT:    # kill: %YMM2<def> %YMM2<kill> %ZMM2<def>
1007 ; KNL_64-NEXT:    # kill: %YMM0<def> %YMM0<kill> %ZMM0<def>
1008 ; KNL_64-NEXT:    vpslld $31, %xmm1, %xmm1
1009 ; KNL_64-NEXT:    vpsrad $31, %xmm1, %xmm1
1010 ; KNL_64-NEXT:    vpmovsxdq %xmm1, %ymm1
1011 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1012 ; KNL_64-NEXT:    vinserti64x4 $0, %ymm1, %zmm3, %zmm1
1013 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
1014 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
1015 ; KNL_64-NEXT:    vscatterqpd %zmm0, (%rdi,%zmm2,8) {%k1}
1016 ; KNL_64-NEXT:    vzeroupper
1017 ; KNL_64-NEXT:    retq
1018 ;
1019 ; KNL_32-LABEL: test19:
1020 ; KNL_32:       # BB#0:
1021 ; KNL_32-NEXT:    # kill: %YMM2<def> %YMM2<kill> %ZMM2<def>
1022 ; KNL_32-NEXT:    # kill: %YMM0<def> %YMM0<kill> %ZMM0<def>
1023 ; KNL_32-NEXT:    vpslld $31, %xmm1, %xmm1
1024 ; KNL_32-NEXT:    vpsrad $31, %xmm1, %xmm1
1025 ; KNL_32-NEXT:    vpmovsxdq %xmm1, %ymm1
1026 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1027 ; KNL_32-NEXT:    vinserti64x4 $0, %ymm1, %zmm3, %zmm1
1028 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1029 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
1030 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
1031 ; KNL_32-NEXT:    vscatterqpd %zmm0, (%eax,%zmm2,8) {%k1}
1032 ; KNL_32-NEXT:    vzeroupper
1033 ; KNL_32-NEXT:    retl
1034 ;
1035 ; SKX-LABEL: test19:
1036 ; SKX:       # BB#0:
1037 ; SKX-NEXT:    vpslld $31, %xmm1, %xmm1
1038 ; SKX-NEXT:    vptestmd %xmm1, %xmm1, %k1
1039 ; SKX-NEXT:    vscatterqpd %ymm0, (%rdi,%ymm2,8) {%k1}
1040 ; SKX-NEXT:    vzeroupper
1041 ; SKX-NEXT:    retq
1042 ;
1043 ; SKX_32-LABEL: test19:
1044 ; SKX_32:       # BB#0:
1045 ; SKX_32-NEXT:    vpslld $31, %xmm1, %xmm1
1046 ; SKX_32-NEXT:    vptestmd %xmm1, %xmm1, %k1
1047 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1048 ; SKX_32-NEXT:    vscatterqpd %ymm0, (%eax,%ymm2,8) {%k1}
1049 ; SKX_32-NEXT:    vzeroupper
1050 ; SKX_32-NEXT:    retl
1051   %gep = getelementptr double, double* %ptr, <4 x i64> %ind
1052   call void @llvm.masked.scatter.v4f64.v4p0f64(<4 x double> %a1, <4 x double*> %gep, i32 8, <4 x i1> %mask)
1053   ret void
1054 }
1055
1056 ; Data type requires widening
1057 define void @test20(<2 x float>%a1, <2 x float*> %ptr, <2 x i1> %mask) {
1058 ;
1059 ; KNL_64-LABEL: test20:
1060 ; KNL_64:       # BB#0:
1061 ; KNL_64-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1062 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
1063 ; KNL_64-NEXT:    vinsertps {{.*#+}} xmm2 = xmm2[0,2],zero,zero
1064 ; KNL_64-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1065 ; KNL_64-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0,1,2,3],ymm3[4,5,6,7]
1066 ; KNL_64-NEXT:    vpslld $31, %ymm2, %ymm2
1067 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1068 ; KNL_64-NEXT:    vscatterqps %ymm0, (,%zmm1) {%k1}
1069 ; KNL_64-NEXT:    vzeroupper
1070 ; KNL_64-NEXT:    retq
1071 ;
1072 ; KNL_32-LABEL: test20:
1073 ; KNL_32:       # BB#0:
1074 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
1075 ; KNL_32-NEXT:    vinsertps {{.*#+}} xmm2 = xmm2[0,2],zero,zero
1076 ; KNL_32-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1077 ; KNL_32-NEXT:    vpblendd {{.*#+}} ymm2 = ymm2[0,1,2,3],ymm3[4,5,6,7]
1078 ; KNL_32-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1079 ; KNL_32-NEXT:    vpmovsxdq %ymm1, %zmm1
1080 ; KNL_32-NEXT:    vpslld $31, %ymm2, %ymm2
1081 ; KNL_32-NEXT:    vptestmd %zmm2, %zmm2, %k1
1082 ; KNL_32-NEXT:    vscatterqps %ymm0, (,%zmm1) {%k1}
1083 ; KNL_32-NEXT:    vzeroupper
1084 ; KNL_32-NEXT:    retl
1085 ;
1086 ; SKX-LABEL: test20:
1087 ; SKX:       # BB#0:
1088 ; SKX-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
1089 ; SKX-NEXT:    vpsllq $63, %xmm2, %xmm2
1090 ; SKX-NEXT:    vptestmq %xmm2, %xmm2, %k0
1091 ; SKX-NEXT:    kshiftlb $6, %k0, %k0
1092 ; SKX-NEXT:    kshiftrb $6, %k0, %k1
1093 ; SKX-NEXT:    vscatterqps %xmm0, (,%ymm1) {%k1}
1094 ; SKX-NEXT:    vzeroupper
1095 ; SKX-NEXT:    retq
1096 ;
1097 ; SKX_32-LABEL: test20:
1098 ; SKX_32:       # BB#0:
1099 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
1100 ; SKX_32-NEXT:    vpsllq $63, %xmm2, %xmm2
1101 ; SKX_32-NEXT:    vptestmq %xmm2, %xmm2, %k0
1102 ; SKX_32-NEXT:    kshiftlb $6, %k0, %k0
1103 ; SKX_32-NEXT:    kshiftrb $6, %k0, %k1
1104 ; SKX_32-NEXT:    vscatterdps %xmm0, (,%xmm1) {%k1}
1105 ; SKX_32-NEXT:    retl
1106   call void @llvm.masked.scatter.v2f32.v2p0f32(<2 x float> %a1, <2 x float*> %ptr, i32 4, <2 x i1> %mask)
1107   ret void
1108 }
1109
1110 ; Data type requires promotion
1111 define void @test21(<2 x i32>%a1, <2 x i32*> %ptr, <2 x i1>%mask) {
1112 ;
1113 ; KNL_64-LABEL: test21:
1114 ; KNL_64:       # BB#0:
1115 ; KNL_64-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1116 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1117 ; KNL_64-NEXT:    vinserti32x4 $0, %xmm2, %zmm3, %zmm2
1118 ; KNL_64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1119 ; KNL_64-NEXT:    vpsllq $63, %zmm2, %zmm2
1120 ; KNL_64-NEXT:    vptestmq %zmm2, %zmm2, %k1
1121 ; KNL_64-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
1122 ; KNL_64-NEXT:    vzeroupper
1123 ; KNL_64-NEXT:    retq
1124 ;
1125 ; KNL_32-LABEL: test21:
1126 ; KNL_32:       # BB#0:
1127 ; KNL_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1128 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1129 ; KNL_32-NEXT:    vinserti32x4 $0, %xmm2, %zmm3, %zmm2
1130 ; KNL_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1131 ; KNL_32-NEXT:    vpsllq $63, %zmm2, %zmm2
1132 ; KNL_32-NEXT:    vptestmq %zmm2, %zmm2, %k1
1133 ; KNL_32-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
1134 ; KNL_32-NEXT:    vzeroupper
1135 ; KNL_32-NEXT:    retl
1136 ;
1137 ; SKX-LABEL: test21:
1138 ; SKX:       # BB#0:
1139 ; SKX-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
1140 ; SKX-NEXT:    vpsllq $63, %xmm2, %xmm2
1141 ; SKX-NEXT:    vptestmq %xmm2, %xmm2, %k0
1142 ; SKX-NEXT:    kshiftlb $6, %k0, %k0
1143 ; SKX-NEXT:    kshiftrb $6, %k0, %k1
1144 ; SKX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1145 ; SKX-NEXT:    vpscatterqd %xmm0, (,%ymm1) {%k1}
1146 ; SKX-NEXT:    vzeroupper
1147 ; SKX-NEXT:    retq
1148 ;
1149 ; SKX_32-LABEL: test21:
1150 ; SKX_32:       # BB#0:
1151 ; SKX_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
1152 ; SKX_32-NEXT:    vpsllq $63, %xmm2, %xmm2
1153 ; SKX_32-NEXT:    vptestmq %xmm2, %xmm2, %k0
1154 ; SKX_32-NEXT:    kshiftlb $6, %k0, %k0
1155 ; SKX_32-NEXT:    kshiftrb $6, %k0, %k1
1156 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1157 ; SKX_32-NEXT:    vpscatterqd %xmm0, (,%ymm1) {%k1}
1158 ; SKX_32-NEXT:    vzeroupper
1159 ; SKX_32-NEXT:    retl
1160   call void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> %mask)
1161   ret void
1162 }
1163
1164 ; The result type requires widening
1165 declare <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*>, i32, <2 x i1>, <2 x float>)
1166
1167 define <2 x float> @test22(float* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x float> %src0) {
1168 ;
1169 ;
1170 ; KNL_64-LABEL: test22:
1171 ; KNL_64:       # BB#0:
1172 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
1173 ; KNL_64-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,2],zero,zero
1174 ; KNL_64-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1175 ; KNL_64-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm3[4,5,6,7]
1176 ; KNL_64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1177 ; KNL_64-NEXT:    vpmovsxdq %ymm0, %zmm0
1178 ; KNL_64-NEXT:    vpslld $31, %ymm1, %ymm1
1179 ; KNL_64-NEXT:    vptestmd %zmm1, %zmm1, %k1
1180 ; KNL_64-NEXT:    vgatherqps (%rdi,%zmm0,4), %ymm2 {%k1}
1181 ; KNL_64-NEXT:    vmovaps %xmm2, %xmm0
1182 ; KNL_64-NEXT:    vzeroupper
1183 ; KNL_64-NEXT:    retq
1184 ;
1185 ; KNL_32-LABEL: test22:
1186 ; KNL_32:       # BB#0:
1187 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
1188 ; KNL_32-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,2],zero,zero
1189 ; KNL_32-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1190 ; KNL_32-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm3[4,5,6,7]
1191 ; KNL_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1192 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1193 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm0
1194 ; KNL_32-NEXT:    vpslld $31, %ymm1, %ymm1
1195 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1196 ; KNL_32-NEXT:    vgatherqps (%eax,%zmm0,4), %ymm2 {%k1}
1197 ; KNL_32-NEXT:    vmovaps %xmm2, %xmm0
1198 ; KNL_32-NEXT:    vzeroupper
1199 ; KNL_32-NEXT:    retl
1200 ;
1201 ; SKX-LABEL: test22:
1202 ; SKX:       # BB#0:
1203 ; SKX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1204 ; SKX-NEXT:    vpsllq $63, %xmm1, %xmm1
1205 ; SKX-NEXT:    vptestmq %xmm1, %xmm1, %k0
1206 ; SKX-NEXT:    kshiftlb $6, %k0, %k0
1207 ; SKX-NEXT:    kshiftrb $6, %k0, %k1
1208 ; SKX-NEXT:    vgatherdps (%rdi,%xmm0,4), %xmm2 {%k1}
1209 ; SKX-NEXT:    vmovaps %xmm2, %xmm0
1210 ; SKX-NEXT:    retq
1211 ;
1212 ; SKX_32-LABEL: test22:
1213 ; SKX_32:       # BB#0:
1214 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1215 ; SKX_32-NEXT:    vpsllq $63, %xmm1, %xmm1
1216 ; SKX_32-NEXT:    vptestmq %xmm1, %xmm1, %k0
1217 ; SKX_32-NEXT:    kshiftlb $6, %k0, %k0
1218 ; SKX_32-NEXT:    kshiftrb $6, %k0, %k1
1219 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1220 ; SKX_32-NEXT:    vgatherdps (%eax,%xmm0,4), %xmm2 {%k1}
1221 ; SKX_32-NEXT:    vmovaps %xmm2, %xmm0
1222 ; SKX_32-NEXT:    retl
1223   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1224   %gep.random = getelementptr float, float* %base, <2 x i64> %sext_ind
1225   %res = call <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*> %gep.random, i32 4, <2 x i1> %mask, <2 x float> %src0)
1226   ret <2 x float>%res
1227 }
1228
1229 define <2 x float> @test22a(float* %base, <2 x i64> %ind, <2 x i1> %mask, <2 x float> %src0) {
1230 ; KNL_64-LABEL: test22a:
1231 ; KNL_64:       # BB#0:
1232 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
1233 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1234 ; KNL_64-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,2],zero,zero
1235 ; KNL_64-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1236 ; KNL_64-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm3[4,5,6,7]
1237 ; KNL_64-NEXT:    vpslld $31, %ymm1, %ymm1
1238 ; KNL_64-NEXT:    vptestmd %zmm1, %zmm1, %k1
1239 ; KNL_64-NEXT:    vgatherqps (%rdi,%zmm0,4), %ymm2 {%k1}
1240 ; KNL_64-NEXT:    vmovaps %xmm2, %xmm0
1241 ; KNL_64-NEXT:    vzeroupper
1242 ; KNL_64-NEXT:    retq
1243 ;
1244 ; KNL_32-LABEL: test22a:
1245 ; KNL_32:       # BB#0:
1246 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %YMM2<def>
1247 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1248 ; KNL_32-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,2],zero,zero
1249 ; KNL_32-NEXT:    vpxor %ymm3, %ymm3, %ymm3
1250 ; KNL_32-NEXT:    vpblendd {{.*#+}} ymm1 = ymm1[0,1,2,3],ymm3[4,5,6,7]
1251 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1252 ; KNL_32-NEXT:    vpslld $31, %ymm1, %ymm1
1253 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1254 ; KNL_32-NEXT:    vgatherqps (%eax,%zmm0,4), %ymm2 {%k1}
1255 ; KNL_32-NEXT:    vmovaps %xmm2, %xmm0
1256 ; KNL_32-NEXT:    vzeroupper
1257 ; KNL_32-NEXT:    retl
1258 ;
1259 ; SKX-LABEL: test22a:
1260 ; SKX:       # BB#0:
1261 ; SKX-NEXT:    vpsllq $63, %xmm1, %xmm1
1262 ; SKX-NEXT:    vptestmq %xmm1, %xmm1, %k1
1263 ; SKX-NEXT:    vgatherqps (%rdi,%xmm0,4), %xmm2 {%k1}
1264 ; SKX-NEXT:    vmovaps %xmm2, %xmm0
1265 ; SKX-NEXT:    retq
1266 ;
1267 ; SKX_32-LABEL: test22a:
1268 ; SKX_32:       # BB#0:
1269 ; SKX_32-NEXT:    vpsllq $63, %xmm1, %xmm1
1270 ; SKX_32-NEXT:    vptestmq %xmm1, %xmm1, %k1
1271 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1272 ; SKX_32-NEXT:    vgatherqps (%eax,%xmm0,4), %xmm2 {%k1}
1273 ; SKX_32-NEXT:    vmovaps %xmm2, %xmm0
1274 ; SKX_32-NEXT:    retl
1275   %gep.random = getelementptr float, float* %base, <2 x i64> %ind
1276   %res = call <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*> %gep.random, i32 4, <2 x i1> %mask, <2 x float> %src0)
1277   ret <2 x float>%res
1278 }
1279
1280 declare <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*>, i32, <2 x i1>, <2 x i32>)
1281 declare <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*>, i32, <2 x i1>, <2 x i64>)
1282
1283 define <2 x i32> @test23(i32* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x i32> %src0) {
1284 ;
1285 ; KNL_64-LABEL: test23:
1286 ; KNL_64:       # BB#0:
1287 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
1288 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1289 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1290 ; KNL_64-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
1291 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
1292 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
1293 ; KNL_64-NEXT:    vpgatherqq (%rdi,%zmm0,8), %zmm2 {%k1}
1294 ; KNL_64-NEXT:    vmovdqa %xmm2, %xmm0
1295 ; KNL_64-NEXT:    vzeroupper
1296 ; KNL_64-NEXT:    retq
1297 ;
1298 ; KNL_32-LABEL: test23:
1299 ; KNL_32:       # BB#0:
1300 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
1301 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1302 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1303 ; KNL_32-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
1304 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1305 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
1306 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
1307 ; KNL_32-NEXT:    vpgatherqq (%eax,%zmm0,8), %zmm2 {%k1}
1308 ; KNL_32-NEXT:    vmovdqa %xmm2, %xmm0
1309 ; KNL_32-NEXT:    vzeroupper
1310 ; KNL_32-NEXT:    retl
1311 ;
1312 ; SKX-LABEL: test23:
1313 ; SKX:       # BB#0:
1314 ; SKX-NEXT:    vpsllq $63, %xmm1, %xmm1
1315 ; SKX-NEXT:    vptestmq %xmm1, %xmm1, %k1
1316 ; SKX-NEXT:    vpshufd {{.*#+}} xmm1 = xmm2[0,2,2,3]
1317 ; SKX-NEXT:    vpgatherqd (%rdi,%xmm0,4), %xmm1 {%k1}
1318 ; SKX-NEXT:    vpmovsxdq %xmm1, %xmm0
1319 ; SKX-NEXT:    retq
1320 ;
1321 ; SKX_32-LABEL: test23:
1322 ; SKX_32:       # BB#0:
1323 ; SKX_32-NEXT:    vpsllq $63, %xmm1, %xmm1
1324 ; SKX_32-NEXT:    vptestmq %xmm1, %xmm1, %k1
1325 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1326 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm1 = xmm2[0,2,2,3]
1327 ; SKX_32-NEXT:    vpgatherqd (%eax,%xmm0,4), %xmm1 {%k1}
1328 ; SKX_32-NEXT:    vpmovsxdq %xmm1, %xmm0
1329 ; SKX_32-NEXT:    retl
1330   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1331   %gep.random = getelementptr i32, i32* %base, <2 x i64> %sext_ind
1332   %res = call <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*> %gep.random, i32 4, <2 x i1> %mask, <2 x i32> %src0)
1333   ret <2 x i32>%res
1334 }
1335
1336 define <2 x i32> @test24(i32* %base, <2 x i32> %ind) {
1337 ; KNL_64-LABEL: test24:
1338 ; KNL_64:       # BB#0:
1339 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1340 ; KNL_64-NEXT:    movb $3, %al
1341 ; KNL_64-NEXT:    kmovw %eax, %k1
1342 ; KNL_64-NEXT:    vpgatherqq (%rdi,%zmm0,8), %zmm1 {%k1}
1343 ; KNL_64-NEXT:    vmovdqa %xmm1, %xmm0
1344 ; KNL_64-NEXT:    vzeroupper
1345 ; KNL_64-NEXT:    retq
1346 ;
1347 ; KNL_32-LABEL: test24:
1348 ; KNL_32:       # BB#0:
1349 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1350 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1351 ; KNL_32-NEXT:    vpxord %zmm1, %zmm1, %zmm1
1352 ; KNL_32-NEXT:    vinserti32x4 $0, {{\.LCPI.*}}, %zmm1, %zmm1
1353 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
1354 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
1355 ; KNL_32-NEXT:    vpgatherqq (%eax,%zmm0,8), %zmm1 {%k1}
1356 ; KNL_32-NEXT:    vmovdqa %xmm1, %xmm0
1357 ; KNL_32-NEXT:    vzeroupper
1358 ; KNL_32-NEXT:    retl
1359 ;
1360 ; SKX-LABEL: test24:
1361 ; SKX:       # BB#0:
1362 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
1363 ; SKX-NEXT:    vpgatherqd (%rdi,%xmm0,4), %xmm1 {%k1}
1364 ; SKX-NEXT:    vpmovsxdq %xmm1, %xmm0
1365 ; SKX-NEXT:    retq
1366 ;
1367 ; SKX_32-LABEL: test24:
1368 ; SKX_32:       # BB#0:
1369 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1370 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
1371 ; SKX_32-NEXT:    vpgatherqd (%eax,%xmm0,4), %xmm1 {%k1}
1372 ; SKX_32-NEXT:    vpmovsxdq %xmm1, %xmm0
1373 ; SKX_32-NEXT:    retl
1374   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1375   %gep.random = getelementptr i32, i32* %base, <2 x i64> %sext_ind
1376   %res = call <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
1377   ret <2 x i32>%res
1378 }
1379
1380 define <2 x i64> @test25(i64* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x i64> %src0) {
1381 ;
1382 ; KNL_64-LABEL: test25:
1383 ; KNL_64:       # BB#0:
1384 ; KNL_64-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
1385 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1386 ; KNL_64-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1387 ; KNL_64-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
1388 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
1389 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
1390 ; KNL_64-NEXT:    vpgatherqq (%rdi,%zmm0,8), %zmm2 {%k1}
1391 ; KNL_64-NEXT:    vmovdqa %xmm2, %xmm0
1392 ; KNL_64-NEXT:    vzeroupper
1393 ; KNL_64-NEXT:    retq
1394 ;
1395 ; KNL_32-LABEL: test25:
1396 ; KNL_32:       # BB#0:
1397 ; KNL_32-NEXT:    # kill: %XMM2<def> %XMM2<kill> %ZMM2<def>
1398 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1399 ; KNL_32-NEXT:    vpxord %zmm3, %zmm3, %zmm3
1400 ; KNL_32-NEXT:    vinserti32x4 $0, %xmm1, %zmm3, %zmm1
1401 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1402 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
1403 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
1404 ; KNL_32-NEXT:    vpgatherqq (%eax,%zmm0,8), %zmm2 {%k1}
1405 ; KNL_32-NEXT:    vmovdqa %xmm2, %xmm0
1406 ; KNL_32-NEXT:    vzeroupper
1407 ; KNL_32-NEXT:    retl
1408 ;
1409 ; SKX-LABEL: test25:
1410 ; SKX:       # BB#0:
1411 ; SKX-NEXT:    vpsllq $63, %xmm1, %xmm1
1412 ; SKX-NEXT:    vptestmq %xmm1, %xmm1, %k1
1413 ; SKX-NEXT:    vpgatherqq (%rdi,%xmm0,8), %xmm2 {%k1}
1414 ; SKX-NEXT:    vmovdqa %xmm2, %xmm0
1415 ; SKX-NEXT:    retq
1416 ;
1417 ; SKX_32-LABEL: test25:
1418 ; SKX_32:       # BB#0:
1419 ; SKX_32-NEXT:    vpsllq $63, %xmm1, %xmm1
1420 ; SKX_32-NEXT:    vptestmq %xmm1, %xmm1, %k1
1421 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1422 ; SKX_32-NEXT:    vpgatherqq (%eax,%xmm0,8), %xmm2 {%k1}
1423 ; SKX_32-NEXT:    vmovdqa %xmm2, %xmm0
1424 ; SKX_32-NEXT:    retl
1425   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1426   %gep.random = getelementptr i64, i64* %base, <2 x i64> %sext_ind
1427   %res = call <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*> %gep.random, i32 8, <2 x i1> %mask, <2 x i64> %src0)
1428   ret <2 x i64>%res
1429 }
1430
1431 define <2 x i64> @test26(i64* %base, <2 x i32> %ind, <2 x i64> %src0) {
1432 ;
1433 ; KNL_64-LABEL: test26:
1434 ; KNL_64:       # BB#0:
1435 ; KNL_64-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1436 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1437 ; KNL_64-NEXT:    movb $3, %al
1438 ; KNL_64-NEXT:    kmovw %eax, %k1
1439 ; KNL_64-NEXT:    vpgatherqq (%rdi,%zmm0,8), %zmm1 {%k1}
1440 ; KNL_64-NEXT:    vmovdqa %xmm1, %xmm0
1441 ; KNL_64-NEXT:    vzeroupper
1442 ; KNL_64-NEXT:    retq
1443 ;
1444 ; KNL_32-LABEL: test26:
1445 ; KNL_32:       # BB#0:
1446 ; KNL_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1447 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %ZMM0<def>
1448 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1449 ; KNL_32-NEXT:    vpxord %zmm2, %zmm2, %zmm2
1450 ; KNL_32-NEXT:    vinserti32x4 $0, {{\.LCPI.*}}, %zmm2, %zmm2
1451 ; KNL_32-NEXT:    vpsllq $63, %zmm2, %zmm2
1452 ; KNL_32-NEXT:    vptestmq %zmm2, %zmm2, %k1
1453 ; KNL_32-NEXT:    vpgatherqq (%eax,%zmm0,8), %zmm1 {%k1}
1454 ; KNL_32-NEXT:    vmovdqa %xmm1, %xmm0
1455 ; KNL_32-NEXT:    vzeroupper
1456 ; KNL_32-NEXT:    retl
1457 ;
1458 ; SKX-LABEL: test26:
1459 ; SKX:       # BB#0:
1460 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
1461 ; SKX-NEXT:    vpgatherqq (%rdi,%xmm0,8), %xmm1 {%k1}
1462 ; SKX-NEXT:    vmovdqa %xmm1, %xmm0
1463 ; SKX-NEXT:    retq
1464 ;
1465 ; SKX_32-LABEL: test26:
1466 ; SKX_32:       # BB#0:
1467 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1468 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
1469 ; SKX_32-NEXT:    vpgatherqq (%eax,%xmm0,8), %xmm1 {%k1}
1470 ; SKX_32-NEXT:    vmovdqa %xmm1, %xmm0
1471 ; SKX_32-NEXT:    retl
1472   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1473   %gep.random = getelementptr i64, i64* %base, <2 x i64> %sext_ind
1474   %res = call <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*> %gep.random, i32 8, <2 x i1> <i1 true, i1 true>, <2 x i64> %src0)
1475   ret <2 x i64>%res
1476 }
1477
1478 ; Result type requires widening; all-ones mask
1479 define <2 x float> @test27(float* %base, <2 x i32> %ind) {
1480 ;
1481 ; KNL_64-LABEL: test27:
1482 ; KNL_64:       # BB#0:
1483 ; KNL_64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1484 ; KNL_64-NEXT:    vpmovsxdq %ymm0, %zmm1
1485 ; KNL_64-NEXT:    movb $3, %al
1486 ; KNL_64-NEXT:    kmovw %eax, %k1
1487 ; KNL_64-NEXT:    vgatherqps (%rdi,%zmm1,4), %ymm0 {%k1}
1488 ; KNL_64-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<kill>
1489 ; KNL_64-NEXT:    vzeroupper
1490 ; KNL_64-NEXT:    retq
1491 ;
1492 ; KNL_32-LABEL: test27:
1493 ; KNL_32:       # BB#0:
1494 ; KNL_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1495 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1496 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm1
1497 ; KNL_32-NEXT:    movb $3, %cl
1498 ; KNL_32-NEXT:    kmovw %ecx, %k1
1499 ; KNL_32-NEXT:    vgatherqps (%eax,%zmm1,4), %ymm0 {%k1}
1500 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<kill>
1501 ; KNL_32-NEXT:    vzeroupper
1502 ; KNL_32-NEXT:    retl
1503 ;
1504 ; SKX-LABEL: test27:
1505 ; SKX:       # BB#0:
1506 ; SKX-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,2,2,3]
1507 ; SKX-NEXT:    movb $3, %al
1508 ; SKX-NEXT:    kmovw %eax, %k1
1509 ; SKX-NEXT:    vgatherdps (%rdi,%xmm1,4), %xmm0 {%k1}
1510 ; SKX-NEXT:    retq
1511 ;
1512 ; SKX_32-LABEL: test27:
1513 ; SKX_32:       # BB#0:
1514 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm1 = xmm0[0,2,2,3]
1515 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1516 ; SKX_32-NEXT:    movb $3, %cl
1517 ; SKX_32-NEXT:    kmovw %ecx, %k1
1518 ; SKX_32-NEXT:    vgatherdps (%eax,%xmm1,4), %xmm0 {%k1}
1519 ; SKX_32-NEXT:    retl
1520   %sext_ind = sext <2 x i32> %ind to <2 x i64>
1521   %gep.random = getelementptr float, float* %base, <2 x i64> %sext_ind
1522   %res = call <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x float> undef)
1523   ret <2 x float>%res
1524 }
1525
1526 ; Data type requires promotion, mask is all-ones
1527 define void @test28(<2 x i32>%a1, <2 x i32*> %ptr) {
1528 ;
1529 ;
1530 ; KNL_64-LABEL: test28:
1531 ; KNL_64:       # BB#0:
1532 ; KNL_64-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1533 ; KNL_64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1534 ; KNL_64-NEXT:    movb $3, %al
1535 ; KNL_64-NEXT:    kmovw %eax, %k1
1536 ; KNL_64-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
1537 ; KNL_64-NEXT:    vzeroupper
1538 ; KNL_64-NEXT:    retq
1539 ;
1540 ; KNL_32-LABEL: test28:
1541 ; KNL_32:       # BB#0:
1542 ; KNL_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %ZMM1<def>
1543 ; KNL_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1544 ; KNL_32-NEXT:    vpxord %zmm2, %zmm2, %zmm2
1545 ; KNL_32-NEXT:    vinserti32x4 $0, {{\.LCPI.*}}, %zmm2, %zmm2
1546 ; KNL_32-NEXT:    vpsllq $63, %zmm2, %zmm2
1547 ; KNL_32-NEXT:    vptestmq %zmm2, %zmm2, %k1
1548 ; KNL_32-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k1}
1549 ; KNL_32-NEXT:    vzeroupper
1550 ; KNL_32-NEXT:    retl
1551 ;
1552 ; SKX-LABEL: test28:
1553 ; SKX:       # BB#0:
1554 ; SKX-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
1555 ; SKX-NEXT:    movb $3, %al
1556 ; SKX-NEXT:    kmovw %eax, %k1
1557 ; SKX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1558 ; SKX-NEXT:    vpscatterqd %xmm0, (,%ymm1) {%k1}
1559 ; SKX-NEXT:    vzeroupper
1560 ; SKX-NEXT:    retq
1561 ;
1562 ; SKX_32-LABEL: test28:
1563 ; SKX_32:       # BB#0:
1564 ; SKX_32-NEXT:    # kill: %XMM1<def> %XMM1<kill> %YMM1<def>
1565 ; SKX_32-NEXT:    movb $3, %al
1566 ; SKX_32-NEXT:    kmovw %eax, %k1
1567 ; SKX_32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
1568 ; SKX_32-NEXT:    vpscatterqd %xmm0, (,%ymm1) {%k1}
1569 ; SKX_32-NEXT:    vzeroupper
1570 ; SKX_32-NEXT:    retl
1571   call void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> <i1 true, i1 true>)
1572   ret void
1573 }
1574
1575
1576 ; SCALAR-LABEL: test29
1577 ; SCALAR:      extractelement <16 x float*>
1578 ; SCALAR-NEXT: load float
1579 ; SCALAR-NEXT: insertelement <16 x float>
1580 ; SCALAR-NEXT: extractelement <16 x float*>
1581 ; SCALAR-NEXT: load float
1582
1583 define <16 x float> @test29(float* %base, <16 x i32> %ind) {
1584 ; KNL_64-LABEL: test29:
1585 ; KNL_64:       # BB#0:
1586 ; KNL_64-NEXT:    movw $44, %ax
1587 ; KNL_64-NEXT:    kmovw %eax, %k1
1588 ; KNL_64-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
1589 ; KNL_64-NEXT:    vmovaps %zmm1, %zmm0
1590 ; KNL_64-NEXT:    retq
1591 ;
1592 ; KNL_32-LABEL: test29:
1593 ; KNL_32:       # BB#0:
1594 ; KNL_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1595 ; KNL_32-NEXT:    movw $44, %cx
1596 ; KNL_32-NEXT:    kmovw %ecx, %k1
1597 ; KNL_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
1598 ; KNL_32-NEXT:    vmovaps %zmm1, %zmm0
1599 ; KNL_32-NEXT:    retl
1600 ;
1601 ; SKX-LABEL: test29:
1602 ; SKX:       # BB#0:
1603 ; SKX-NEXT:    movw $44, %ax
1604 ; SKX-NEXT:    kmovw %eax, %k1
1605 ; SKX-NEXT:    vgatherdps (%rdi,%zmm0,4), %zmm1 {%k1}
1606 ; SKX-NEXT:    vmovaps %zmm1, %zmm0
1607 ; SKX-NEXT:    retq
1608 ;
1609 ; SKX_32-LABEL: test29:
1610 ; SKX_32:       # BB#0:
1611 ; SKX_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
1612 ; SKX_32-NEXT:    movw $44, %cx
1613 ; SKX_32-NEXT:    kmovw %ecx, %k1
1614 ; SKX_32-NEXT:    vgatherdps (%eax,%zmm0,4), %zmm1 {%k1}
1615 ; SKX_32-NEXT:    vmovaps %zmm1, %zmm0
1616 ; SKX_32-NEXT:    retl
1617
1618   %broadcast.splatinsert = insertelement <16 x float*> undef, float* %base, i32 0
1619   %broadcast.splat = shufflevector <16 x float*> %broadcast.splatinsert, <16 x float*> undef, <16 x i32> zeroinitializer
1620
1621   %sext_ind = sext <16 x i32> %ind to <16 x i64>
1622   %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind
1623
1624   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 false, i1 false, i1 true, i1 true, i1 false, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x float> undef)
1625   ret <16 x float>%res
1626 }
1627
1628 ; Check non-power-of-2 case. It should be scalarized.
1629 declare <3 x i32> @llvm.masked.gather.v3i32.v3p0i32(<3 x i32*>, i32, <3 x i1>, <3 x i32>)
1630 define <3 x i32> @test30(<3 x i32*> %base, <3 x i32> %ind, <3 x i1> %mask, <3 x i32> %src0) {
1631 ; ALL-LABEL: test30
1632 ; ALL-NOT:       gather
1633
1634   %sext_ind = sext <3 x i32> %ind to <3 x i64>
1635   %gep.random = getelementptr i32, <3 x i32*> %base, <3 x i64> %sext_ind
1636   %res = call <3 x i32> @llvm.masked.gather.v3i32.v3p0i32(<3 x i32*> %gep.random, i32 4, <3 x i1> %mask, <3 x i32> %src0)
1637   ret <3 x i32>%res
1638 }
1639
1640 declare <16 x float*> @llvm.masked.gather.v16p0f32.v16p0p0f32(<16 x float**>, i32, <16 x i1>, <16 x float*>)
1641
1642 ; KNL-LABEL: test31
1643 ; KNL: vpgatherqq
1644 ; KNL: vpgatherqq
1645 define <16 x float*> @test31(<16 x float**> %ptrs) {
1646 ; KNL_64-LABEL: test31:
1647 ; KNL_64:       # BB#0:
1648 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k1
1649 ; KNL_64-NEXT:    kxnorw %k0, %k0, %k2
1650 ; KNL_64-NEXT:    vpgatherqq (,%zmm0), %zmm2 {%k2}
1651 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k1
1652 ; KNL_64-NEXT:    vpgatherqq (,%zmm1), %zmm3 {%k1}
1653 ; KNL_64-NEXT:    vmovdqa64 %zmm2, %zmm0
1654 ; KNL_64-NEXT:    vmovdqa64 %zmm3, %zmm1
1655 ; KNL_64-NEXT:    retq
1656 ;
1657 ; KNL_32-LABEL: test31:
1658 ; KNL_32:       # BB#0:
1659 ; KNL_32-NEXT:    kxnorw %k0, %k0, %k1
1660 ; KNL_32-NEXT:    vpgatherdd (,%zmm0), %zmm1 {%k1}
1661 ; KNL_32-NEXT:    vmovdqa64 %zmm1, %zmm0
1662 ; KNL_32-NEXT:    retl
1663 ;
1664 ; SKX-LABEL: test31:
1665 ; SKX:       # BB#0:
1666 ; SKX-NEXT:    kxnorw %k0, %k0, %k1
1667 ; SKX-NEXT:    kxnorw %k0, %k0, %k2
1668 ; SKX-NEXT:    vpgatherqq (,%zmm0), %zmm2 {%k2}
1669 ; SKX-NEXT:    kshiftrw $8, %k1, %k1
1670 ; SKX-NEXT:    vpgatherqq (,%zmm1), %zmm3 {%k1}
1671 ; SKX-NEXT:    vmovdqa64 %zmm2, %zmm0
1672 ; SKX-NEXT:    vmovdqa64 %zmm3, %zmm1
1673 ; SKX-NEXT:    retq
1674 ;
1675 ; SKX_32-LABEL: test31:
1676 ; SKX_32:       # BB#0:
1677 ; SKX_32-NEXT:    kxnorw %k0, %k0, %k1
1678 ; SKX_32-NEXT:    vpgatherdd (,%zmm0), %zmm1 {%k1}
1679 ; SKX_32-NEXT:    vmovdqa64 %zmm1, %zmm0
1680 ; SKX_32-NEXT:    retl
1681
1682   %res = call <16 x float*> @llvm.masked.gather.v16p0f32.v16p0p0f32(<16 x float**> %ptrs, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float*> undef)
1683   ret <16 x float*>%res
1684 }
1685
1686 define <16 x i32> @test_gather_16i32(<16 x i32*> %ptrs, <16 x i1> %mask, <16 x i32> %src0)  {
1687 ; KNL_64-LABEL: test_gather_16i32:
1688 ; KNL_64:       # BB#0:
1689 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1690 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1691 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1692 ; KNL_64-NEXT:    vextracti64x4 $1, %zmm3, %ymm2
1693 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1694 ; KNL_64-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
1695 ; KNL_64-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k1}
1696 ; KNL_64-NEXT:    vinserti64x4 $1, %ymm2, %zmm3, %zmm0
1697 ; KNL_64-NEXT:    retq
1698 ;
1699 ; KNL_32-LABEL: test_gather_16i32:
1700 ; KNL_32:       # BB#0:
1701 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1702 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
1703 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1704 ; KNL_32-NEXT:    vpgatherdd (,%zmm0), %zmm2 {%k1}
1705 ; KNL_32-NEXT:    vmovdqa64 %zmm2, %zmm0
1706 ; KNL_32-NEXT:    retl
1707 ;
1708 ; SKX-LABEL: test_gather_16i32:
1709 ; SKX:       # BB#0:
1710 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
1711 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
1712 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
1713 ; SKX-NEXT:    vextracti32x8 $1, %zmm3, %ymm2
1714 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
1715 ; SKX-NEXT:    vpgatherqd (,%zmm1), %ymm2 {%k2}
1716 ; SKX-NEXT:    vpgatherqd (,%zmm0), %ymm3 {%k1}
1717 ; SKX-NEXT:    vinserti32x8 $1, %ymm2, %zmm3, %zmm0
1718 ; SKX-NEXT:    retq
1719 ;
1720 ; SKX_32-LABEL: test_gather_16i32:
1721 ; SKX_32:       # BB#0:
1722 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1723 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
1724 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1725 ; SKX_32-NEXT:    vpgatherdd (,%zmm0), %zmm2 {%k1}
1726 ; SKX_32-NEXT:    vmovdqa64 %zmm2, %zmm0
1727 ; SKX_32-NEXT:    retl
1728   %res = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptrs, i32 4, <16 x i1> %mask, <16 x i32> %src0)
1729   ret <16 x i32> %res
1730 }
1731 define <16 x i64> @test_gather_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i64> %src0)  {
1732 ; KNL_64-LABEL: test_gather_16i64:
1733 ; KNL_64:       # BB#0:
1734 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1735 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1736 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1737 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1738 ; KNL_64-NEXT:    vpgatherqq (,%zmm0), %zmm3 {%k1}
1739 ; KNL_64-NEXT:    vpgatherqq (,%zmm1), %zmm4 {%k2}
1740 ; KNL_64-NEXT:    vmovdqa64 %zmm3, %zmm0
1741 ; KNL_64-NEXT:    vmovdqa64 %zmm4, %zmm1
1742 ; KNL_64-NEXT:    retq
1743 ;
1744 ; KNL_32-LABEL: test_gather_16i64:
1745 ; KNL_32:       # BB#0:
1746 ; KNL_32-NEXT:    pushl %ebp
1747 ; KNL_32-NEXT:  .Lcfi0:
1748 ; KNL_32-NEXT:    .cfi_def_cfa_offset 8
1749 ; KNL_32-NEXT:  .Lcfi1:
1750 ; KNL_32-NEXT:    .cfi_offset %ebp, -8
1751 ; KNL_32-NEXT:    movl %esp, %ebp
1752 ; KNL_32-NEXT:  .Lcfi2:
1753 ; KNL_32-NEXT:    .cfi_def_cfa_register %ebp
1754 ; KNL_32-NEXT:    andl $-64, %esp
1755 ; KNL_32-NEXT:    subl $64, %esp
1756 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1757 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
1758 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1759 ; KNL_32-NEXT:    vmovdqa64 8(%ebp), %zmm1
1760 ; KNL_32-NEXT:    kshiftrw $8, %k1, %k2
1761 ; KNL_32-NEXT:    vpgatherdq (,%ymm0), %zmm2 {%k1}
1762 ; KNL_32-NEXT:    vextracti64x4 $1, %zmm0, %ymm0
1763 ; KNL_32-NEXT:    vpgatherdq (,%ymm0), %zmm1 {%k2}
1764 ; KNL_32-NEXT:    vmovdqa64 %zmm2, %zmm0
1765 ; KNL_32-NEXT:    movl %ebp, %esp
1766 ; KNL_32-NEXT:    popl %ebp
1767 ; KNL_32-NEXT:    retl
1768 ;
1769 ; SKX-LABEL: test_gather_16i64:
1770 ; SKX:       # BB#0:
1771 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
1772 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
1773 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
1774 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
1775 ; SKX-NEXT:    vpgatherqq (,%zmm0), %zmm3 {%k1}
1776 ; SKX-NEXT:    vpgatherqq (,%zmm1), %zmm4 {%k2}
1777 ; SKX-NEXT:    vmovdqa64 %zmm3, %zmm0
1778 ; SKX-NEXT:    vmovdqa64 %zmm4, %zmm1
1779 ; SKX-NEXT:    retq
1780 ;
1781 ; SKX_32-LABEL: test_gather_16i64:
1782 ; SKX_32:       # BB#0:
1783 ; SKX_32-NEXT:    pushl %ebp
1784 ; SKX_32-NEXT:  .Lcfi1:
1785 ; SKX_32-NEXT:    .cfi_def_cfa_offset 8
1786 ; SKX_32-NEXT:  .Lcfi2:
1787 ; SKX_32-NEXT:    .cfi_offset %ebp, -8
1788 ; SKX_32-NEXT:    movl %esp, %ebp
1789 ; SKX_32-NEXT:  .Lcfi3:
1790 ; SKX_32-NEXT:    .cfi_def_cfa_register %ebp
1791 ; SKX_32-NEXT:    andl $-64, %esp
1792 ; SKX_32-NEXT:    subl $64, %esp
1793 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1794 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
1795 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1796 ; SKX_32-NEXT:    vmovdqa64 8(%ebp), %zmm1
1797 ; SKX_32-NEXT:    kshiftrw $8, %k1, %k2
1798 ; SKX_32-NEXT:    vpgatherdq (,%ymm0), %zmm2 {%k1}
1799 ; SKX_32-NEXT:    vextracti32x8 $1, %zmm0, %ymm0
1800 ; SKX_32-NEXT:    vpgatherdq (,%ymm0), %zmm1 {%k2}
1801 ; SKX_32-NEXT:    vmovdqa64 %zmm2, %zmm0
1802 ; SKX_32-NEXT:    movl %ebp, %esp
1803 ; SKX_32-NEXT:    popl %ebp
1804 ; SKX_32-NEXT:    retl
1805   %res = call <16 x i64> @llvm.masked.gather.v16i64.v16p0i64(<16 x i64*> %ptrs, i32 4, <16 x i1> %mask, <16 x i64> %src0)
1806   ret <16 x i64> %res
1807 }
1808 declare <16 x i64> @llvm.masked.gather.v16i64.v16p0i64(<16 x i64*> %ptrs, i32, <16 x i1> %mask, <16 x i64> %src0)
1809 define <16 x float> @test_gather_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 x float> %src0)  {
1810 ; KNL_64-LABEL: test_gather_16f32:
1811 ; KNL_64:       # BB#0:
1812 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1813 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1814 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1815 ; KNL_64-NEXT:    vextractf64x4 $1, %zmm3, %ymm2
1816 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1817 ; KNL_64-NEXT:    vgatherqps (,%zmm1), %ymm2 {%k2}
1818 ; KNL_64-NEXT:    vgatherqps (,%zmm0), %ymm3 {%k1}
1819 ; KNL_64-NEXT:    vinsertf64x4 $1, %ymm2, %zmm3, %zmm0
1820 ; KNL_64-NEXT:    retq
1821 ;
1822 ; KNL_32-LABEL: test_gather_16f32:
1823 ; KNL_32:       # BB#0:
1824 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1825 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
1826 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1827 ; KNL_32-NEXT:    vgatherdps (,%zmm0), %zmm2 {%k1}
1828 ; KNL_32-NEXT:    vmovaps %zmm2, %zmm0
1829 ; KNL_32-NEXT:    retl
1830 ;
1831 ; SKX-LABEL: test_gather_16f32:
1832 ; SKX:       # BB#0:
1833 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
1834 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
1835 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
1836 ; SKX-NEXT:    vextractf32x8 $1, %zmm3, %ymm2
1837 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
1838 ; SKX-NEXT:    vgatherqps (,%zmm1), %ymm2 {%k2}
1839 ; SKX-NEXT:    vgatherqps (,%zmm0), %ymm3 {%k1}
1840 ; SKX-NEXT:    vinsertf32x8 $1, %ymm2, %zmm3, %zmm0
1841 ; SKX-NEXT:    retq
1842 ;
1843 ; SKX_32-LABEL: test_gather_16f32:
1844 ; SKX_32:       # BB#0:
1845 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1846 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
1847 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1848 ; SKX_32-NEXT:    vgatherdps (,%zmm0), %zmm2 {%k1}
1849 ; SKX_32-NEXT:    vmovaps %zmm2, %zmm0
1850 ; SKX_32-NEXT:    retl
1851   %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %ptrs, i32 4, <16 x i1> %mask, <16 x float> %src0)
1852   ret <16 x float> %res
1853 }
1854 define <16 x double> @test_gather_16f64(<16 x double*> %ptrs, <16 x i1> %mask, <16 x double> %src0)  {
1855 ; KNL_64-LABEL: test_gather_16f64:
1856 ; KNL_64:       # BB#0:
1857 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1858 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1859 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1860 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1861 ; KNL_64-NEXT:    vgatherqpd (,%zmm0), %zmm3 {%k1}
1862 ; KNL_64-NEXT:    vgatherqpd (,%zmm1), %zmm4 {%k2}
1863 ; KNL_64-NEXT:    vmovapd %zmm3, %zmm0
1864 ; KNL_64-NEXT:    vmovapd %zmm4, %zmm1
1865 ; KNL_64-NEXT:    retq
1866 ;
1867 ; KNL_32-LABEL: test_gather_16f64:
1868 ; KNL_32:       # BB#0:
1869 ; KNL_32-NEXT:    pushl %ebp
1870 ; KNL_32-NEXT:  .Lcfi3:
1871 ; KNL_32-NEXT:    .cfi_def_cfa_offset 8
1872 ; KNL_32-NEXT:  .Lcfi4:
1873 ; KNL_32-NEXT:    .cfi_offset %ebp, -8
1874 ; KNL_32-NEXT:    movl %esp, %ebp
1875 ; KNL_32-NEXT:  .Lcfi5:
1876 ; KNL_32-NEXT:    .cfi_def_cfa_register %ebp
1877 ; KNL_32-NEXT:    andl $-64, %esp
1878 ; KNL_32-NEXT:    subl $64, %esp
1879 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1880 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
1881 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1882 ; KNL_32-NEXT:    vmovapd 8(%ebp), %zmm1
1883 ; KNL_32-NEXT:    kshiftrw $8, %k1, %k2
1884 ; KNL_32-NEXT:    vgatherdpd (,%ymm0), %zmm2 {%k1}
1885 ; KNL_32-NEXT:    vextracti64x4 $1, %zmm0, %ymm0
1886 ; KNL_32-NEXT:    vgatherdpd (,%ymm0), %zmm1 {%k2}
1887 ; KNL_32-NEXT:    vmovapd %zmm2, %zmm0
1888 ; KNL_32-NEXT:    movl %ebp, %esp
1889 ; KNL_32-NEXT:    popl %ebp
1890 ; KNL_32-NEXT:    retl
1891 ;
1892 ; SKX-LABEL: test_gather_16f64:
1893 ; SKX:       # BB#0:
1894 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
1895 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
1896 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
1897 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
1898 ; SKX-NEXT:    vgatherqpd (,%zmm0), %zmm3 {%k1}
1899 ; SKX-NEXT:    vgatherqpd (,%zmm1), %zmm4 {%k2}
1900 ; SKX-NEXT:    vmovapd %zmm3, %zmm0
1901 ; SKX-NEXT:    vmovapd %zmm4, %zmm1
1902 ; SKX-NEXT:    retq
1903 ;
1904 ; SKX_32-LABEL: test_gather_16f64:
1905 ; SKX_32:       # BB#0:
1906 ; SKX_32-NEXT:    pushl %ebp
1907 ; SKX_32-NEXT:  .Lcfi4:
1908 ; SKX_32-NEXT:    .cfi_def_cfa_offset 8
1909 ; SKX_32-NEXT:  .Lcfi5:
1910 ; SKX_32-NEXT:    .cfi_offset %ebp, -8
1911 ; SKX_32-NEXT:    movl %esp, %ebp
1912 ; SKX_32-NEXT:  .Lcfi6:
1913 ; SKX_32-NEXT:    .cfi_def_cfa_register %ebp
1914 ; SKX_32-NEXT:    andl $-64, %esp
1915 ; SKX_32-NEXT:    subl $64, %esp
1916 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1917 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
1918 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1919 ; SKX_32-NEXT:    vmovapd 8(%ebp), %zmm1
1920 ; SKX_32-NEXT:    kshiftrw $8, %k1, %k2
1921 ; SKX_32-NEXT:    vgatherdpd (,%ymm0), %zmm2 {%k1}
1922 ; SKX_32-NEXT:    vextracti32x8 $1, %zmm0, %ymm0
1923 ; SKX_32-NEXT:    vgatherdpd (,%ymm0), %zmm1 {%k2}
1924 ; SKX_32-NEXT:    vmovapd %zmm2, %zmm0
1925 ; SKX_32-NEXT:    movl %ebp, %esp
1926 ; SKX_32-NEXT:    popl %ebp
1927 ; SKX_32-NEXT:    retl
1928   %res = call <16 x double> @llvm.masked.gather.v16f64.v16p0f64(<16 x double*> %ptrs, i32 4, <16 x i1> %mask, <16 x double> %src0)
1929   ret <16 x double> %res
1930 }
1931 declare <16 x double> @llvm.masked.gather.v16f64.v16p0f64(<16 x double*> %ptrs, i32, <16 x i1> %mask, <16 x double> %src0)
1932 define void @test_scatter_16i32(<16 x i32*> %ptrs, <16 x i1> %mask, <16 x i32> %src0)  {
1933 ; KNL_64-LABEL: test_scatter_16i32:
1934 ; KNL_64:       # BB#0:
1935 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1936 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1937 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1938 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1939 ; KNL_64-NEXT:    vpscatterqd %ymm3, (,%zmm0) {%k1}
1940 ; KNL_64-NEXT:    vextracti64x4 $1, %zmm3, %ymm0
1941 ; KNL_64-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k2}
1942 ; KNL_64-NEXT:    vzeroupper
1943 ; KNL_64-NEXT:    retq
1944 ;
1945 ; KNL_32-LABEL: test_scatter_16i32:
1946 ; KNL_32:       # BB#0:
1947 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1948 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
1949 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1950 ; KNL_32-NEXT:    vpscatterdd %zmm2, (,%zmm0) {%k1}
1951 ; KNL_32-NEXT:    vzeroupper
1952 ; KNL_32-NEXT:    retl
1953 ;
1954 ; SKX-LABEL: test_scatter_16i32:
1955 ; SKX:       # BB#0:
1956 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
1957 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
1958 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
1959 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
1960 ; SKX-NEXT:    vpscatterqd %ymm3, (,%zmm0) {%k1}
1961 ; SKX-NEXT:    vextracti32x8 $1, %zmm3, %ymm0
1962 ; SKX-NEXT:    vpscatterqd %ymm0, (,%zmm1) {%k2}
1963 ; SKX-NEXT:    vzeroupper
1964 ; SKX-NEXT:    retq
1965 ;
1966 ; SKX_32-LABEL: test_scatter_16i32:
1967 ; SKX_32:       # BB#0:
1968 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
1969 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
1970 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
1971 ; SKX_32-NEXT:    vpscatterdd %zmm2, (,%zmm0) {%k1}
1972 ; SKX_32-NEXT:    vzeroupper
1973 ; SKX_32-NEXT:    retl
1974   call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32> %src0, <16 x i32*> %ptrs, i32 4, <16 x i1> %mask)
1975   ret void
1976 }
1977 define void @test_scatter_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i64> %src0)  {
1978 ; KNL_64-LABEL: test_scatter_16i64:
1979 ; KNL_64:       # BB#0:
1980 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
1981 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
1982 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
1983 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
1984 ; KNL_64-NEXT:    vpscatterqq %zmm3, (,%zmm0) {%k1}
1985 ; KNL_64-NEXT:    vpscatterqq %zmm4, (,%zmm1) {%k2}
1986 ; KNL_64-NEXT:    vzeroupper
1987 ; KNL_64-NEXT:    retq
1988 ;
1989 ; KNL_32-LABEL: test_scatter_16i64:
1990 ; KNL_32:       # BB#0:
1991 ; KNL_32-NEXT:    pushl %ebp
1992 ; KNL_32-NEXT:  .Lcfi6:
1993 ; KNL_32-NEXT:    .cfi_def_cfa_offset 8
1994 ; KNL_32-NEXT:  .Lcfi7:
1995 ; KNL_32-NEXT:    .cfi_offset %ebp, -8
1996 ; KNL_32-NEXT:    movl %esp, %ebp
1997 ; KNL_32-NEXT:  .Lcfi8:
1998 ; KNL_32-NEXT:    .cfi_def_cfa_register %ebp
1999 ; KNL_32-NEXT:    andl $-64, %esp
2000 ; KNL_32-NEXT:    subl $64, %esp
2001 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2002 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
2003 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2004 ; KNL_32-NEXT:    vmovdqa64 8(%ebp), %zmm1
2005 ; KNL_32-NEXT:    kshiftrw $8, %k1, %k2
2006 ; KNL_32-NEXT:    vpscatterdq %zmm2, (,%ymm0) {%k1}
2007 ; KNL_32-NEXT:    vextracti64x4 $1, %zmm0, %ymm0
2008 ; KNL_32-NEXT:    vpscatterdq %zmm1, (,%ymm0) {%k2}
2009 ; KNL_32-NEXT:    movl %ebp, %esp
2010 ; KNL_32-NEXT:    popl %ebp
2011 ; KNL_32-NEXT:    vzeroupper
2012 ; KNL_32-NEXT:    retl
2013 ;
2014 ; SKX-LABEL: test_scatter_16i64:
2015 ; SKX:       # BB#0:
2016 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
2017 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
2018 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
2019 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
2020 ; SKX-NEXT:    vpscatterqq %zmm3, (,%zmm0) {%k1}
2021 ; SKX-NEXT:    vpscatterqq %zmm4, (,%zmm1) {%k2}
2022 ; SKX-NEXT:    vzeroupper
2023 ; SKX-NEXT:    retq
2024 ;
2025 ; SKX_32-LABEL: test_scatter_16i64:
2026 ; SKX_32:       # BB#0:
2027 ; SKX_32-NEXT:    pushl %ebp
2028 ; SKX_32-NEXT:  .Lcfi7:
2029 ; SKX_32-NEXT:    .cfi_def_cfa_offset 8
2030 ; SKX_32-NEXT:  .Lcfi8:
2031 ; SKX_32-NEXT:    .cfi_offset %ebp, -8
2032 ; SKX_32-NEXT:    movl %esp, %ebp
2033 ; SKX_32-NEXT:  .Lcfi9:
2034 ; SKX_32-NEXT:    .cfi_def_cfa_register %ebp
2035 ; SKX_32-NEXT:    andl $-64, %esp
2036 ; SKX_32-NEXT:    subl $64, %esp
2037 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2038 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
2039 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2040 ; SKX_32-NEXT:    vmovdqa64 8(%ebp), %zmm1
2041 ; SKX_32-NEXT:    kshiftrw $8, %k1, %k2
2042 ; SKX_32-NEXT:    vpscatterdq %zmm2, (,%ymm0) {%k1}
2043 ; SKX_32-NEXT:    vextracti32x8 $1, %zmm0, %ymm0
2044 ; SKX_32-NEXT:    vpscatterdq %zmm1, (,%ymm0) {%k2}
2045 ; SKX_32-NEXT:    movl %ebp, %esp
2046 ; SKX_32-NEXT:    popl %ebp
2047 ; SKX_32-NEXT:    vzeroupper
2048 ; SKX_32-NEXT:    retl
2049   call void @llvm.masked.scatter.v16i64.v16p0i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32 4, <16 x i1> %mask)
2050   ret void
2051 }
2052 declare void @llvm.masked.scatter.v16i64.v16p0i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32, <16 x i1> %mask)
2053 define void @test_scatter_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 x float> %src0)  {
2054 ; KNL_64-LABEL: test_scatter_16f32:
2055 ; KNL_64:       # BB#0:
2056 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
2057 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
2058 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
2059 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
2060 ; KNL_64-NEXT:    vscatterqps %ymm3, (,%zmm0) {%k1}
2061 ; KNL_64-NEXT:    vextractf64x4 $1, %zmm3, %ymm0
2062 ; KNL_64-NEXT:    vscatterqps %ymm0, (,%zmm1) {%k2}
2063 ; KNL_64-NEXT:    vzeroupper
2064 ; KNL_64-NEXT:    retq
2065 ;
2066 ; KNL_32-LABEL: test_scatter_16f32:
2067 ; KNL_32:       # BB#0:
2068 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2069 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
2070 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2071 ; KNL_32-NEXT:    vscatterdps %zmm2, (,%zmm0) {%k1}
2072 ; KNL_32-NEXT:    vzeroupper
2073 ; KNL_32-NEXT:    retl
2074 ;
2075 ; SKX-LABEL: test_scatter_16f32:
2076 ; SKX:       # BB#0:
2077 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
2078 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
2079 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
2080 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
2081 ; SKX-NEXT:    vscatterqps %ymm3, (,%zmm0) {%k1}
2082 ; SKX-NEXT:    vextractf32x8 $1, %zmm3, %ymm0
2083 ; SKX-NEXT:    vscatterqps %ymm0, (,%zmm1) {%k2}
2084 ; SKX-NEXT:    vzeroupper
2085 ; SKX-NEXT:    retq
2086 ;
2087 ; SKX_32-LABEL: test_scatter_16f32:
2088 ; SKX_32:       # BB#0:
2089 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2090 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
2091 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2092 ; SKX_32-NEXT:    vscatterdps %zmm2, (,%zmm0) {%k1}
2093 ; SKX_32-NEXT:    vzeroupper
2094 ; SKX_32-NEXT:    retl
2095   call void @llvm.masked.scatter.v16f32.v16p0f32(<16 x float> %src0, <16 x float*> %ptrs, i32 4, <16 x i1> %mask)
2096   ret void
2097 }
2098 declare void @llvm.masked.scatter.v16f32.v16p0f32(<16 x float> %src0, <16 x float*> %ptrs, i32, <16 x i1> %mask)
2099 define void @test_scatter_16f64(<16 x double*> %ptrs, <16 x i1> %mask, <16 x double> %src0)  {
2100 ; KNL_64-LABEL: test_scatter_16f64:
2101 ; KNL_64:       # BB#0:
2102 ; KNL_64-NEXT:    vpmovsxbd %xmm2, %zmm2
2103 ; KNL_64-NEXT:    vpslld $31, %zmm2, %zmm2
2104 ; KNL_64-NEXT:    vptestmd %zmm2, %zmm2, %k1
2105 ; KNL_64-NEXT:    kshiftrw $8, %k1, %k2
2106 ; KNL_64-NEXT:    vscatterqpd %zmm3, (,%zmm0) {%k1}
2107 ; KNL_64-NEXT:    vscatterqpd %zmm4, (,%zmm1) {%k2}
2108 ; KNL_64-NEXT:    vzeroupper
2109 ; KNL_64-NEXT:    retq
2110 ;
2111 ; KNL_32-LABEL: test_scatter_16f64:
2112 ; KNL_32:       # BB#0:
2113 ; KNL_32-NEXT:    pushl %ebp
2114 ; KNL_32-NEXT:  .Lcfi9:
2115 ; KNL_32-NEXT:    .cfi_def_cfa_offset 8
2116 ; KNL_32-NEXT:  .Lcfi10:
2117 ; KNL_32-NEXT:    .cfi_offset %ebp, -8
2118 ; KNL_32-NEXT:    movl %esp, %ebp
2119 ; KNL_32-NEXT:  .Lcfi11:
2120 ; KNL_32-NEXT:    .cfi_def_cfa_register %ebp
2121 ; KNL_32-NEXT:    andl $-64, %esp
2122 ; KNL_32-NEXT:    subl $64, %esp
2123 ; KNL_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2124 ; KNL_32-NEXT:    vpslld $31, %zmm1, %zmm1
2125 ; KNL_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2126 ; KNL_32-NEXT:    vmovapd 8(%ebp), %zmm1
2127 ; KNL_32-NEXT:    kshiftrw $8, %k1, %k2
2128 ; KNL_32-NEXT:    vscatterdpd %zmm2, (,%ymm0) {%k1}
2129 ; KNL_32-NEXT:    vextracti64x4 $1, %zmm0, %ymm0
2130 ; KNL_32-NEXT:    vscatterdpd %zmm1, (,%ymm0) {%k2}
2131 ; KNL_32-NEXT:    movl %ebp, %esp
2132 ; KNL_32-NEXT:    popl %ebp
2133 ; KNL_32-NEXT:    vzeroupper
2134 ; KNL_32-NEXT:    retl
2135 ;
2136 ; SKX-LABEL: test_scatter_16f64:
2137 ; SKX:       # BB#0:
2138 ; SKX-NEXT:    vpmovsxbd %xmm2, %zmm2
2139 ; SKX-NEXT:    vpslld $31, %zmm2, %zmm2
2140 ; SKX-NEXT:    vptestmd %zmm2, %zmm2, %k1
2141 ; SKX-NEXT:    kshiftrw $8, %k1, %k2
2142 ; SKX-NEXT:    vscatterqpd %zmm3, (,%zmm0) {%k1}
2143 ; SKX-NEXT:    vscatterqpd %zmm4, (,%zmm1) {%k2}
2144 ; SKX-NEXT:    vzeroupper
2145 ; SKX-NEXT:    retq
2146 ;
2147 ; SKX_32-LABEL: test_scatter_16f64:
2148 ; SKX_32:       # BB#0:
2149 ; SKX_32-NEXT:    pushl %ebp
2150 ; SKX_32-NEXT:  .Lcfi10:
2151 ; SKX_32-NEXT:    .cfi_def_cfa_offset 8
2152 ; SKX_32-NEXT:  .Lcfi11:
2153 ; SKX_32-NEXT:    .cfi_offset %ebp, -8
2154 ; SKX_32-NEXT:    movl %esp, %ebp
2155 ; SKX_32-NEXT:  .Lcfi12:
2156 ; SKX_32-NEXT:    .cfi_def_cfa_register %ebp
2157 ; SKX_32-NEXT:    andl $-64, %esp
2158 ; SKX_32-NEXT:    subl $64, %esp
2159 ; SKX_32-NEXT:    vpmovsxbd %xmm1, %zmm1
2160 ; SKX_32-NEXT:    vpslld $31, %zmm1, %zmm1
2161 ; SKX_32-NEXT:    vptestmd %zmm1, %zmm1, %k1
2162 ; SKX_32-NEXT:    vmovapd 8(%ebp), %zmm1
2163 ; SKX_32-NEXT:    kshiftrw $8, %k1, %k2
2164 ; SKX_32-NEXT:    vscatterdpd %zmm2, (,%ymm0) {%k1}
2165 ; SKX_32-NEXT:    vextracti32x8 $1, %zmm0, %ymm0
2166 ; SKX_32-NEXT:    vscatterdpd %zmm1, (,%ymm0) {%k2}
2167 ; SKX_32-NEXT:    movl %ebp, %esp
2168 ; SKX_32-NEXT:    popl %ebp
2169 ; SKX_32-NEXT:    vzeroupper
2170 ; SKX_32-NEXT:    retl
2171   call void @llvm.masked.scatter.v16f64.v16p0f64(<16 x double> %src0, <16 x double*> %ptrs, i32 4, <16 x i1> %mask)
2172   ret void
2173 }
2174 declare void @llvm.masked.scatter.v16f64.v16p0f64(<16 x double> %src0, <16 x double*> %ptrs, i32, <16 x i1> %mask)
2175
2176 define <4 x i64> @test_pr28312(<4 x i64*> %p1, <4 x i1> %k, <4 x i1> %k2,<4 x i64> %d) {
2177 ; KNL_64-LABEL: test_pr28312:
2178 ; KNL_64:       # BB#0:
2179 ; KNL_64-NEXT:    # kill: %YMM0<def> %YMM0<kill> %ZMM0<def>
2180 ; KNL_64-NEXT:    vpslld $31, %xmm1, %xmm1
2181 ; KNL_64-NEXT:    vpsrad $31, %xmm1, %xmm1
2182 ; KNL_64-NEXT:    vpmovsxdq %xmm1, %ymm1
2183 ; KNL_64-NEXT:    vpxord %zmm2, %zmm2, %zmm2
2184 ; KNL_64-NEXT:    vinserti64x4 $0, %ymm1, %zmm2, %zmm1
2185 ; KNL_64-NEXT:    vpsllq $63, %zmm1, %zmm1
2186 ; KNL_64-NEXT:    vptestmq %zmm1, %zmm1, %k1
2187 ; KNL_64-NEXT:    vpgatherqq (,%zmm0), %zmm1 {%k1}
2188 ; KNL_64-NEXT:    vpaddq %ymm1, %ymm1, %ymm0
2189 ; KNL_64-NEXT:    vpaddq %ymm0, %ymm1, %ymm0
2190 ; KNL_64-NEXT:    retq
2191 ;
2192 ; KNL_32-LABEL: test_pr28312:
2193 ; KNL_32:       # BB#0:
2194 ; KNL_32-NEXT:    pushl %ebp
2195 ; KNL_32-NEXT:  .Lcfi12:
2196 ; KNL_32-NEXT:    .cfi_def_cfa_offset 8
2197 ; KNL_32-NEXT:  .Lcfi13:
2198 ; KNL_32-NEXT:    .cfi_offset %ebp, -8
2199 ; KNL_32-NEXT:    movl %esp, %ebp
2200 ; KNL_32-NEXT:  .Lcfi14:
2201 ; KNL_32-NEXT:    .cfi_def_cfa_register %ebp
2202 ; KNL_32-NEXT:    andl $-32, %esp
2203 ; KNL_32-NEXT:    subl $32, %esp
2204 ; KNL_32-NEXT:    # kill: %XMM0<def> %XMM0<kill> %YMM0<def>
2205 ; KNL_32-NEXT:    vpslld $31, %xmm1, %xmm1
2206 ; KNL_32-NEXT:    vpsrad $31, %xmm1, %xmm1
2207 ; KNL_32-NEXT:    vpmovsxdq %xmm1, %ymm1
2208 ; KNL_32-NEXT:    vpxord %zmm2, %zmm2, %zmm2
2209 ; KNL_32-NEXT:    vinserti64x4 $0, %ymm1, %zmm2, %zmm1
2210 ; KNL_32-NEXT:    vpmovsxdq %ymm0, %zmm0
2211 ; KNL_32-NEXT:    vpsllq $63, %zmm1, %zmm1
2212 ; KNL_32-NEXT:    vptestmq %zmm1, %zmm1, %k1
2213 ; KNL_32-NEXT:    vpgatherqq (,%zmm0), %zmm1 {%k1}
2214 ; KNL_32-NEXT:    vpaddq %ymm1, %ymm1, %ymm0
2215 ; KNL_32-NEXT:    vpaddq %ymm0, %ymm1, %ymm0
2216 ; KNL_32-NEXT:    movl %ebp, %esp
2217 ; KNL_32-NEXT:    popl %ebp
2218 ; KNL_32-NEXT:    retl
2219 ;
2220 ; SKX-LABEL: test_pr28312:
2221 ; SKX:       # BB#0:
2222 ; SKX-NEXT:    vpslld $31, %xmm1, %xmm1
2223 ; SKX-NEXT:    vptestmd %xmm1, %xmm1, %k1
2224 ; SKX-NEXT:    vpgatherqq (,%ymm0), %ymm1 {%k1}
2225 ; SKX-NEXT:    vpaddq %ymm1, %ymm1, %ymm0
2226 ; SKX-NEXT:    vpaddq %ymm0, %ymm1, %ymm0
2227 ; SKX-NEXT:    retq
2228 ;
2229 ; SKX_32-LABEL: test_pr28312:
2230 ; SKX_32:       # BB#0:
2231 ; SKX_32-NEXT:    pushl %ebp
2232 ; SKX_32-NEXT:  .Lcfi13:
2233 ; SKX_32-NEXT:    .cfi_def_cfa_offset 8
2234 ; SKX_32-NEXT:  .Lcfi14:
2235 ; SKX_32-NEXT:    .cfi_offset %ebp, -8
2236 ; SKX_32-NEXT:    movl %esp, %ebp
2237 ; SKX_32-NEXT:  .Lcfi15:
2238 ; SKX_32-NEXT:    .cfi_def_cfa_register %ebp
2239 ; SKX_32-NEXT:    andl $-32, %esp
2240 ; SKX_32-NEXT:    subl $32, %esp
2241 ; SKX_32-NEXT:    vpslld $31, %xmm1, %xmm1
2242 ; SKX_32-NEXT:    vptestmd %xmm1, %xmm1, %k1
2243 ; SKX_32-NEXT:    vpgatherdq (,%xmm0), %ymm1 {%k1}
2244 ; SKX_32-NEXT:    vpaddq %ymm1, %ymm1, %ymm0
2245 ; SKX_32-NEXT:    vpaddq %ymm0, %ymm1, %ymm0
2246 ; SKX_32-NEXT:    movl %ebp, %esp
2247 ; SKX_32-NEXT:    popl %ebp
2248 ; SKX_32-NEXT:    retl
2249   %g1 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef)
2250   %g2 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef)
2251   %g3 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef)
2252   %a = add <4 x i64> %g1, %g2
2253   %b = add <4 x i64> %a, %g3
2254   ret <4 x i64> %b
2255 }
2256 declare <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*>, i32, <4 x i1>, <4 x i64>)