1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=alderlake -verify-machineinstrs| FileCheck %s --check-prefixes=AVX,ADL
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=sapphirerapids -verify-machineinstrs | FileCheck %s --check-prefixes=AVX,SPR
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=icelake-server -verify-machineinstrs | FileCheck %s --check-prefixes=AVX512
6 define <2 x i64> @foo_reg_128(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2, <2 x i64> %3, <2 x i64> %4, <2 x i64> %5) {
7 ; AVX-LABEL: foo_reg_128:
9 ; AVX-NEXT: {vex} vpdpwssd %xmm2, %xmm1, %xmm0
10 ; AVX-NEXT: vpmaddwd %xmm3, %xmm1, %xmm2
11 ; AVX-NEXT: vpaddd %xmm2, %xmm0, %xmm0
12 ; AVX-NEXT: vpmaddwd %xmm4, %xmm1, %xmm2
13 ; AVX-NEXT: vpaddd %xmm2, %xmm0, %xmm0
14 ; AVX-NEXT: vpmaddwd %xmm5, %xmm1, %xmm1
15 ; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0
18 ; AVX512-LABEL: foo_reg_128:
20 ; AVX512-NEXT: vpdpwssd %xmm2, %xmm1, %xmm0
21 ; AVX512-NEXT: vpmaddwd %xmm3, %xmm1, %xmm2
22 ; AVX512-NEXT: vpaddd %xmm2, %xmm0, %xmm0
23 ; AVX512-NEXT: vpmaddwd %xmm4, %xmm1, %xmm2
24 ; AVX512-NEXT: vpaddd %xmm2, %xmm0, %xmm0
25 ; AVX512-NEXT: vpmaddwd %xmm5, %xmm1, %xmm1
26 ; AVX512-NEXT: vpaddd %xmm1, %xmm0, %xmm0
28 %7 = bitcast <2 x i64> %0 to <4 x i32>
29 %8 = bitcast <2 x i64> %1 to <4 x i32>
30 %9 = bitcast <2 x i64> %2 to <4 x i32>
31 %10 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %7, <4 x i32> %8, <4 x i32> %9)
32 %11 = bitcast <2 x i64> %3 to <4 x i32>
33 %12 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %10, <4 x i32> %8, <4 x i32> %11)
34 %13 = bitcast <2 x i64> %4 to <4 x i32>
35 %14 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %12, <4 x i32> %8, <4 x i32> %13)
36 %15 = bitcast <2 x i64> %5 to <4 x i32>
37 %16 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %14, <4 x i32> %8, <4 x i32> %15)
38 %17 = bitcast <4 x i32> %16 to <2 x i64>
42 declare <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32>, <4 x i32>, <4 x i32>) #1
44 define <2 x i64> @foo_128(i32 %0, <2 x i64> %1, <2 x i64> %2, ptr %3) {
47 ; AVX-NEXT: testl %edi, %edi
48 ; AVX-NEXT: jle .LBB1_6
50 ; AVX-NEXT: movl %edi, %edx
51 ; AVX-NEXT: movl %edx, %eax
52 ; AVX-NEXT: andl $3, %eax
53 ; AVX-NEXT: cmpl $4, %edi
54 ; AVX-NEXT: jae .LBB1_7
56 ; AVX-NEXT: xorl %ecx, %ecx
57 ; AVX-NEXT: jmp .LBB1_3
59 ; AVX-NEXT: andl $-4, %edx
60 ; AVX-NEXT: leaq 48(%rsi), %rdi
61 ; AVX-NEXT: xorl %ecx, %ecx
62 ; AVX-NEXT: .p2align 4, 0x90
63 ; AVX-NEXT: .LBB1_8: # =>This Inner Loop Header: Depth=1
64 ; AVX-NEXT: {vex} vpdpwssd -48(%rdi), %xmm1, %xmm0
65 ; AVX-NEXT: vpmaddwd -32(%rdi), %xmm1, %xmm2
66 ; AVX-NEXT: vpaddd %xmm2, %xmm0, %xmm0
67 ; AVX-NEXT: vpmaddwd -16(%rdi), %xmm1, %xmm2
68 ; AVX-NEXT: vpaddd %xmm2, %xmm0, %xmm0
69 ; AVX-NEXT: vpmaddwd (%rdi), %xmm1, %xmm2
70 ; AVX-NEXT: vpaddd %xmm2, %xmm0, %xmm0
71 ; AVX-NEXT: addq $4, %rcx
72 ; AVX-NEXT: addq $64, %rdi
73 ; AVX-NEXT: cmpq %rcx, %rdx
74 ; AVX-NEXT: jne .LBB1_8
76 ; AVX-NEXT: testq %rax, %rax
77 ; AVX-NEXT: je .LBB1_6
78 ; AVX-NEXT: # %bb.4: # %.preheader
79 ; AVX-NEXT: shlq $4, %rcx
80 ; AVX-NEXT: addq %rcx, %rsi
81 ; AVX-NEXT: shll $4, %eax
82 ; AVX-NEXT: xorl %ecx, %ecx
83 ; AVX-NEXT: .p2align 4, 0x90
84 ; AVX-NEXT: .LBB1_5: # =>This Inner Loop Header: Depth=1
85 ; AVX-NEXT: {vex} vpdpwssd (%rsi,%rcx), %xmm1, %xmm0
86 ; AVX-NEXT: addq $16, %rcx
87 ; AVX-NEXT: cmpq %rcx, %rax
88 ; AVX-NEXT: jne .LBB1_5
92 ; AVX512-LABEL: foo_128:
94 ; AVX512-NEXT: testl %edi, %edi
95 ; AVX512-NEXT: jle .LBB1_6
96 ; AVX512-NEXT: # %bb.1:
97 ; AVX512-NEXT: movl %edi, %edx
98 ; AVX512-NEXT: movl %edx, %eax
99 ; AVX512-NEXT: andl $3, %eax
100 ; AVX512-NEXT: cmpl $4, %edi
101 ; AVX512-NEXT: jae .LBB1_7
102 ; AVX512-NEXT: # %bb.2:
103 ; AVX512-NEXT: xorl %ecx, %ecx
104 ; AVX512-NEXT: jmp .LBB1_3
105 ; AVX512-NEXT: .LBB1_7:
106 ; AVX512-NEXT: andl $-4, %edx
107 ; AVX512-NEXT: leaq 48(%rsi), %rdi
108 ; AVX512-NEXT: xorl %ecx, %ecx
109 ; AVX512-NEXT: .p2align 4, 0x90
110 ; AVX512-NEXT: .LBB1_8: # =>This Inner Loop Header: Depth=1
111 ; AVX512-NEXT: vpdpwssd -48(%rdi), %xmm1, %xmm0
112 ; AVX512-NEXT: vpmaddwd -32(%rdi), %xmm1, %xmm2
113 ; AVX512-NEXT: vpaddd %xmm2, %xmm0, %xmm0
114 ; AVX512-NEXT: vpmaddwd -16(%rdi), %xmm1, %xmm2
115 ; AVX512-NEXT: vpaddd %xmm2, %xmm0, %xmm0
116 ; AVX512-NEXT: vpmaddwd (%rdi), %xmm1, %xmm2
117 ; AVX512-NEXT: vpaddd %xmm2, %xmm0, %xmm0
118 ; AVX512-NEXT: addq $4, %rcx
119 ; AVX512-NEXT: addq $64, %rdi
120 ; AVX512-NEXT: cmpq %rcx, %rdx
121 ; AVX512-NEXT: jne .LBB1_8
122 ; AVX512-NEXT: .LBB1_3:
123 ; AVX512-NEXT: testq %rax, %rax
124 ; AVX512-NEXT: je .LBB1_6
125 ; AVX512-NEXT: # %bb.4: # %.preheader
126 ; AVX512-NEXT: shlq $4, %rcx
127 ; AVX512-NEXT: addq %rcx, %rsi
128 ; AVX512-NEXT: shll $4, %eax
129 ; AVX512-NEXT: xorl %ecx, %ecx
130 ; AVX512-NEXT: .p2align 4, 0x90
131 ; AVX512-NEXT: .LBB1_5: # =>This Inner Loop Header: Depth=1
132 ; AVX512-NEXT: vpdpwssd (%rsi,%rcx), %xmm1, %xmm0
133 ; AVX512-NEXT: addq $16, %rcx
134 ; AVX512-NEXT: cmpq %rcx, %rax
135 ; AVX512-NEXT: jne .LBB1_5
136 ; AVX512-NEXT: .LBB1_6:
138 %5 = icmp sgt i32 %0, 0
139 br i1 %5, label %6, label %33
142 %7 = bitcast <2 x i64> %2 to <8 x i16>
143 %8 = bitcast <2 x i64> %1 to <4 x i32>
144 %9 = zext i32 %0 to i64
146 %11 = icmp ult i32 %0, 4
147 br i1 %11, label %14, label %12
150 %13 = and i64 %9, 4294967292
153 14: ; preds = %35, %6
154 %15 = phi <4 x i32> [ undef, %6 ], [ %57, %35 ]
155 %16 = phi i64 [ 0, %6 ], [ %58, %35 ]
156 %17 = phi <4 x i32> [ %8, %6 ], [ %57, %35 ]
157 %18 = icmp eq i64 %10, 0
158 br i1 %18, label %30, label %19
160 19: ; preds = %14, %19
161 %20 = phi i64 [ %27, %19 ], [ %16, %14 ]
162 %21 = phi <4 x i32> [ %26, %19 ], [ %17, %14 ]
163 %22 = phi i64 [ %28, %19 ], [ 0, %14 ]
164 %23 = getelementptr inbounds <2 x i64>, ptr %3, i64 %20
165 %24 = load <8 x i16>, ptr %23, align 16
166 %25 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %7, <8 x i16> %24)
167 %26 = add <4 x i32> %25, %21
168 %27 = add nuw nsw i64 %20, 1
170 %29 = icmp eq i64 %28, %10
171 br i1 %29, label %30, label %19
173 30: ; preds = %19, %14
174 %31 = phi <4 x i32> [ %15, %14 ], [ %26, %19 ]
175 %32 = bitcast <4 x i32> %31 to <2 x i64>
178 33: ; preds = %30, %4
179 %34 = phi <2 x i64> [ %32, %30 ], [ %1, %4 ]
182 35: ; preds = %35, %12
183 %36 = phi i64 [ 0, %12 ], [ %58, %35 ]
184 %37 = phi <4 x i32> [ %8, %12 ], [ %57, %35 ]
185 %38 = phi i64 [ 0, %12 ], [ %59, %35 ]
186 %39 = getelementptr inbounds <2 x i64>, ptr %3, i64 %36
187 %40 = load <8 x i16>, ptr %39, align 16
188 %41 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %7, <8 x i16> %40)
189 %42 = add <4 x i32> %41, %37
190 %43 = or disjoint i64 %36, 1
191 %44 = getelementptr inbounds <2 x i64>, ptr %3, i64 %43
192 %45 = load <8 x i16>, ptr %44, align 16
193 %46 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %7, <8 x i16> %45)
194 %47 = add <4 x i32> %46, %42
195 %48 = or disjoint i64 %36, 2
196 %49 = getelementptr inbounds <2 x i64>, ptr %3, i64 %48
197 %50 = load <8 x i16>, ptr %49, align 16
198 %51 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %7, <8 x i16> %50)
199 %52 = add <4 x i32> %51, %47
200 %53 = or disjoint i64 %36, 3
201 %54 = getelementptr inbounds <2 x i64>, ptr %3, i64 %53
202 %55 = load <8 x i16>, ptr %54, align 16
203 %56 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %7, <8 x i16> %55)
204 %57 = add <4 x i32> %56, %52
205 %58 = add nuw nsw i64 %36, 4
207 %60 = icmp eq i64 %59, %13
208 br i1 %60, label %14, label %35
211 define void @bar_128(i32 %0, ptr %1, <2 x i64> %2, ptr %3) {
212 ; AVX-LABEL: bar_128:
214 ; AVX-NEXT: testl %edi, %edi
215 ; AVX-NEXT: jle .LBB2_5
217 ; AVX-NEXT: movl %edi, %eax
218 ; AVX-NEXT: cmpl $1, %edi
219 ; AVX-NEXT: jne .LBB2_6
221 ; AVX-NEXT: xorl %ecx, %ecx
222 ; AVX-NEXT: jmp .LBB2_3
224 ; AVX-NEXT: movl %eax, %edi
225 ; AVX-NEXT: andl $-2, %edi
226 ; AVX-NEXT: movl $16, %r8d
227 ; AVX-NEXT: xorl %ecx, %ecx
228 ; AVX-NEXT: .p2align 4, 0x90
229 ; AVX-NEXT: .LBB2_7: # =>This Inner Loop Header: Depth=1
230 ; AVX-NEXT: vmovdqa (%rsi,%r8), %xmm1
231 ; AVX-NEXT: vpmaddwd -16(%rdx,%r8), %xmm0, %xmm2
232 ; AVX-NEXT: vpaddd -16(%rsi,%r8), %xmm2, %xmm2
233 ; AVX-NEXT: vmovdqa %xmm2, -16(%rsi,%r8)
234 ; AVX-NEXT: vpmaddwd (%rdx,%r8), %xmm0, %xmm2
235 ; AVX-NEXT: vpaddd %xmm2, %xmm1, %xmm1
236 ; AVX-NEXT: vmovdqa %xmm1, (%rsi,%r8)
237 ; AVX-NEXT: addq $2, %rcx
238 ; AVX-NEXT: addq $32, %r8
239 ; AVX-NEXT: cmpq %rcx, %rdi
240 ; AVX-NEXT: jne .LBB2_7
242 ; AVX-NEXT: testb $1, %al
243 ; AVX-NEXT: je .LBB2_5
245 ; AVX-NEXT: shlq $4, %rcx
246 ; AVX-NEXT: vmovdqa (%rsi,%rcx), %xmm1
247 ; AVX-NEXT: {vex} vpdpwssd (%rdx,%rcx), %xmm0, %xmm1
248 ; AVX-NEXT: vmovdqa %xmm1, (%rsi,%rcx)
252 ; AVX512-LABEL: bar_128:
254 ; AVX512-NEXT: testl %edi, %edi
255 ; AVX512-NEXT: jle .LBB2_5
256 ; AVX512-NEXT: # %bb.1:
257 ; AVX512-NEXT: movl %edi, %eax
258 ; AVX512-NEXT: cmpl $1, %edi
259 ; AVX512-NEXT: jne .LBB2_6
260 ; AVX512-NEXT: # %bb.2:
261 ; AVX512-NEXT: xorl %ecx, %ecx
262 ; AVX512-NEXT: jmp .LBB2_3
263 ; AVX512-NEXT: .LBB2_6:
264 ; AVX512-NEXT: movl %eax, %edi
265 ; AVX512-NEXT: andl $-2, %edi
266 ; AVX512-NEXT: movl $16, %r8d
267 ; AVX512-NEXT: xorl %ecx, %ecx
268 ; AVX512-NEXT: .p2align 4, 0x90
269 ; AVX512-NEXT: .LBB2_7: # =>This Inner Loop Header: Depth=1
270 ; AVX512-NEXT: vmovdqa (%rsi,%r8), %xmm1
271 ; AVX512-NEXT: vpmaddwd -16(%rdx,%r8), %xmm0, %xmm2
272 ; AVX512-NEXT: vpaddd -16(%rsi,%r8), %xmm2, %xmm2
273 ; AVX512-NEXT: vmovdqa %xmm2, -16(%rsi,%r8)
274 ; AVX512-NEXT: vpmaddwd (%rdx,%r8), %xmm0, %xmm2
275 ; AVX512-NEXT: vpaddd %xmm2, %xmm1, %xmm1
276 ; AVX512-NEXT: vmovdqa %xmm1, (%rsi,%r8)
277 ; AVX512-NEXT: addq $2, %rcx
278 ; AVX512-NEXT: addq $32, %r8
279 ; AVX512-NEXT: cmpq %rcx, %rdi
280 ; AVX512-NEXT: jne .LBB2_7
281 ; AVX512-NEXT: .LBB2_3:
282 ; AVX512-NEXT: testb $1, %al
283 ; AVX512-NEXT: je .LBB2_5
284 ; AVX512-NEXT: # %bb.4:
285 ; AVX512-NEXT: shlq $4, %rcx
286 ; AVX512-NEXT: vpmaddwd (%rdx,%rcx), %xmm0, %xmm0
287 ; AVX512-NEXT: vpaddd (%rsi,%rcx), %xmm0, %xmm0
288 ; AVX512-NEXT: vmovdqa %xmm0, (%rsi,%rcx)
289 ; AVX512-NEXT: .LBB2_5:
291 %5 = icmp sgt i32 %0, 0
292 br i1 %5, label %6, label %22
295 %7 = bitcast <2 x i64> %2 to <4 x i32>
296 %8 = zext i32 %0 to i64
298 %10 = icmp eq i32 %0, 1
299 br i1 %10, label %13, label %11
302 %12 = and i64 %8, 4294967294
305 13: ; preds = %23, %6
306 %14 = phi i64 [ 0, %6 ], [ %37, %23 ]
307 %15 = icmp eq i64 %9, 0
308 br i1 %15, label %22, label %16
311 %17 = getelementptr inbounds <2 x i64>, ptr %3, i64 %14
312 %18 = load <4 x i32>, ptr %17, align 16
313 %19 = getelementptr inbounds <2 x i64>, ptr %1, i64 %14
314 %20 = load <4 x i32>, ptr %19, align 16
315 %21 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %20, <4 x i32> %7, <4 x i32> %18)
316 store <4 x i32> %21, ptr %19, align 16
319 22: ; preds = %16, %13, %4
322 23: ; preds = %23, %11
323 %24 = phi i64 [ 0, %11 ], [ %37, %23 ]
324 %25 = phi i64 [ 0, %11 ], [ %38, %23 ]
325 %26 = getelementptr inbounds <2 x i64>, ptr %3, i64 %24
326 %27 = load <4 x i32>, ptr %26, align 16
327 %28 = getelementptr inbounds <2 x i64>, ptr %1, i64 %24
328 %29 = load <4 x i32>, ptr %28, align 16
329 %30 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %29, <4 x i32> %7, <4 x i32> %27)
330 store <4 x i32> %30, ptr %28, align 16
331 %31 = or disjoint i64 %24, 1
332 %32 = getelementptr inbounds <2 x i64>, ptr %3, i64 %31
333 %33 = load <4 x i32>, ptr %32, align 16
334 %34 = getelementptr inbounds <2 x i64>, ptr %1, i64 %31
335 %35 = load <4 x i32>, ptr %34, align 16
336 %36 = tail call <4 x i32> @llvm.x86.avx512.vpdpwssd.128(<4 x i32> %35, <4 x i32> %7, <4 x i32> %33)
337 store <4 x i32> %36, ptr %34, align 16
338 %37 = add nuw nsw i64 %24, 2
340 %39 = icmp eq i64 %38, %12
341 br i1 %39, label %13, label %23
344 declare <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16>, <8 x i16>) #1
346 define <4 x i64> @foo_reg_256(<4 x i64> %0, <4 x i64> %1, <4 x i64> %2, <4 x i64> %3, <4 x i64> %4, <4 x i64> %5) {
347 ; AVX-LABEL: foo_reg_256:
349 ; AVX-NEXT: {vex} vpdpwssd %ymm2, %ymm1, %ymm0
350 ; AVX-NEXT: vpmaddwd %ymm3, %ymm1, %ymm2
351 ; AVX-NEXT: vpaddd %ymm2, %ymm0, %ymm0
352 ; AVX-NEXT: vpmaddwd %ymm4, %ymm1, %ymm2
353 ; AVX-NEXT: vpaddd %ymm2, %ymm0, %ymm0
354 ; AVX-NEXT: vpmaddwd %ymm5, %ymm1, %ymm1
355 ; AVX-NEXT: vpaddd %ymm1, %ymm0, %ymm0
358 ; AVX512-LABEL: foo_reg_256:
360 ; AVX512-NEXT: vpdpwssd %ymm2, %ymm1, %ymm0
361 ; AVX512-NEXT: vpmaddwd %ymm3, %ymm1, %ymm2
362 ; AVX512-NEXT: vpaddd %ymm2, %ymm0, %ymm0
363 ; AVX512-NEXT: vpmaddwd %ymm4, %ymm1, %ymm2
364 ; AVX512-NEXT: vpaddd %ymm2, %ymm0, %ymm0
365 ; AVX512-NEXT: vpmaddwd %ymm5, %ymm1, %ymm1
366 ; AVX512-NEXT: vpaddd %ymm1, %ymm0, %ymm0
368 %7 = bitcast <4 x i64> %0 to <8 x i32>
369 %8 = bitcast <4 x i64> %1 to <8 x i32>
370 %9 = bitcast <4 x i64> %2 to <8 x i32>
371 %10 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %7, <8 x i32> %8, <8 x i32> %9)
372 %11 = bitcast <4 x i64> %3 to <8 x i32>
373 %12 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %10, <8 x i32> %8, <8 x i32> %11)
374 %13 = bitcast <4 x i64> %4 to <8 x i32>
375 %14 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %12, <8 x i32> %8, <8 x i32> %13)
376 %15 = bitcast <4 x i64> %5 to <8 x i32>
377 %16 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %14, <8 x i32> %8, <8 x i32> %15)
378 %17 = bitcast <8 x i32> %16 to <4 x i64>
382 ; __m256i foo(int cnt, __m256i c, __m256i b, __m256i *p) {
383 ; for (int i = 0; i < cnt; ++i) {
385 ; __m256i m = _mm256_madd_epi16 (b, a);
386 ; c = _mm256_add_epi32(m, c);
391 define <4 x i64> @foo_256(i32 %0, <4 x i64> %1, <4 x i64> %2, ptr %3) {
392 ; AVX-LABEL: foo_256:
394 ; AVX-NEXT: testl %edi, %edi
395 ; AVX-NEXT: jle .LBB4_6
397 ; AVX-NEXT: movl %edi, %edx
398 ; AVX-NEXT: movl %edx, %eax
399 ; AVX-NEXT: andl $3, %eax
400 ; AVX-NEXT: cmpl $4, %edi
401 ; AVX-NEXT: jae .LBB4_7
403 ; AVX-NEXT: xorl %ecx, %ecx
404 ; AVX-NEXT: jmp .LBB4_3
406 ; AVX-NEXT: andl $-4, %edx
407 ; AVX-NEXT: leaq 96(%rsi), %rdi
408 ; AVX-NEXT: xorl %ecx, %ecx
409 ; AVX-NEXT: .p2align 4, 0x90
410 ; AVX-NEXT: .LBB4_8: # =>This Inner Loop Header: Depth=1
411 ; AVX-NEXT: {vex} vpdpwssd -96(%rdi), %ymm1, %ymm0
412 ; AVX-NEXT: vpmaddwd -64(%rdi), %ymm1, %ymm2
413 ; AVX-NEXT: vpaddd %ymm2, %ymm0, %ymm0
414 ; AVX-NEXT: vpmaddwd -32(%rdi), %ymm1, %ymm2
415 ; AVX-NEXT: vpaddd %ymm2, %ymm0, %ymm0
416 ; AVX-NEXT: vpmaddwd (%rdi), %ymm1, %ymm2
417 ; AVX-NEXT: vpaddd %ymm2, %ymm0, %ymm0
418 ; AVX-NEXT: addq $4, %rcx
419 ; AVX-NEXT: subq $-128, %rdi
420 ; AVX-NEXT: cmpq %rcx, %rdx
421 ; AVX-NEXT: jne .LBB4_8
423 ; AVX-NEXT: testq %rax, %rax
424 ; AVX-NEXT: je .LBB4_6
425 ; AVX-NEXT: # %bb.4: # %.preheader
426 ; AVX-NEXT: shlq $5, %rcx
427 ; AVX-NEXT: addq %rcx, %rsi
428 ; AVX-NEXT: shll $5, %eax
429 ; AVX-NEXT: xorl %ecx, %ecx
430 ; AVX-NEXT: .p2align 4, 0x90
431 ; AVX-NEXT: .LBB4_5: # =>This Inner Loop Header: Depth=1
432 ; AVX-NEXT: {vex} vpdpwssd (%rsi,%rcx), %ymm1, %ymm0
433 ; AVX-NEXT: addq $32, %rcx
434 ; AVX-NEXT: cmpq %rcx, %rax
435 ; AVX-NEXT: jne .LBB4_5
439 ; AVX512-LABEL: foo_256:
441 ; AVX512-NEXT: testl %edi, %edi
442 ; AVX512-NEXT: jle .LBB4_6
443 ; AVX512-NEXT: # %bb.1:
444 ; AVX512-NEXT: movl %edi, %edx
445 ; AVX512-NEXT: movl %edx, %eax
446 ; AVX512-NEXT: andl $3, %eax
447 ; AVX512-NEXT: cmpl $4, %edi
448 ; AVX512-NEXT: jae .LBB4_7
449 ; AVX512-NEXT: # %bb.2:
450 ; AVX512-NEXT: xorl %ecx, %ecx
451 ; AVX512-NEXT: jmp .LBB4_3
452 ; AVX512-NEXT: .LBB4_7:
453 ; AVX512-NEXT: andl $-4, %edx
454 ; AVX512-NEXT: leaq 96(%rsi), %rdi
455 ; AVX512-NEXT: xorl %ecx, %ecx
456 ; AVX512-NEXT: .p2align 4, 0x90
457 ; AVX512-NEXT: .LBB4_8: # =>This Inner Loop Header: Depth=1
458 ; AVX512-NEXT: vpdpwssd -96(%rdi), %ymm1, %ymm0
459 ; AVX512-NEXT: vpmaddwd -64(%rdi), %ymm1, %ymm2
460 ; AVX512-NEXT: vpaddd %ymm2, %ymm0, %ymm0
461 ; AVX512-NEXT: vpmaddwd -32(%rdi), %ymm1, %ymm2
462 ; AVX512-NEXT: vpaddd %ymm2, %ymm0, %ymm0
463 ; AVX512-NEXT: vpmaddwd (%rdi), %ymm1, %ymm2
464 ; AVX512-NEXT: vpaddd %ymm2, %ymm0, %ymm0
465 ; AVX512-NEXT: addq $4, %rcx
466 ; AVX512-NEXT: subq $-128, %rdi
467 ; AVX512-NEXT: cmpq %rcx, %rdx
468 ; AVX512-NEXT: jne .LBB4_8
469 ; AVX512-NEXT: .LBB4_3:
470 ; AVX512-NEXT: testq %rax, %rax
471 ; AVX512-NEXT: je .LBB4_6
472 ; AVX512-NEXT: # %bb.4: # %.preheader
473 ; AVX512-NEXT: shlq $5, %rcx
474 ; AVX512-NEXT: addq %rcx, %rsi
475 ; AVX512-NEXT: shll $5, %eax
476 ; AVX512-NEXT: xorl %ecx, %ecx
477 ; AVX512-NEXT: .p2align 4, 0x90
478 ; AVX512-NEXT: .LBB4_5: # =>This Inner Loop Header: Depth=1
479 ; AVX512-NEXT: vpdpwssd (%rsi,%rcx), %ymm1, %ymm0
480 ; AVX512-NEXT: addq $32, %rcx
481 ; AVX512-NEXT: cmpq %rcx, %rax
482 ; AVX512-NEXT: jne .LBB4_5
483 ; AVX512-NEXT: .LBB4_6:
485 %5 = icmp sgt i32 %0, 0
486 br i1 %5, label %6, label %33
489 %7 = bitcast <4 x i64> %2 to <16 x i16>
490 %8 = bitcast <4 x i64> %1 to <8 x i32>
491 %9 = zext i32 %0 to i64
493 %11 = icmp ult i32 %0, 4
494 br i1 %11, label %14, label %12
497 %13 = and i64 %9, 4294967292
500 14: ; preds = %35, %6
501 %15 = phi <8 x i32> [ undef, %6 ], [ %57, %35 ]
502 %16 = phi i64 [ 0, %6 ], [ %58, %35 ]
503 %17 = phi <8 x i32> [ %8, %6 ], [ %57, %35 ]
504 %18 = icmp eq i64 %10, 0
505 br i1 %18, label %30, label %19
507 19: ; preds = %14, %19
508 %20 = phi i64 [ %27, %19 ], [ %16, %14 ]
509 %21 = phi <8 x i32> [ %26, %19 ], [ %17, %14 ]
510 %22 = phi i64 [ %28, %19 ], [ 0, %14 ]
511 %23 = getelementptr inbounds <4 x i64>, ptr %3, i64 %20
512 %24 = load <16 x i16>, ptr %23, align 32
513 %25 = tail call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %7, <16 x i16> %24)
514 %26 = add <8 x i32> %25, %21
515 %27 = add nuw nsw i64 %20, 1
517 %29 = icmp eq i64 %28, %10
518 br i1 %29, label %30, label %19
520 30: ; preds = %19, %14
521 %31 = phi <8 x i32> [ %15, %14 ], [ %26, %19 ]
522 %32 = bitcast <8 x i32> %31 to <4 x i64>
525 33: ; preds = %30, %4
526 %34 = phi <4 x i64> [ %32, %30 ], [ %1, %4 ]
529 35: ; preds = %35, %12
530 %36 = phi i64 [ 0, %12 ], [ %58, %35 ]
531 %37 = phi <8 x i32> [ %8, %12 ], [ %57, %35 ]
532 %38 = phi i64 [ 0, %12 ], [ %59, %35 ]
533 %39 = getelementptr inbounds <4 x i64>, ptr %3, i64 %36
534 %40 = load <16 x i16>, ptr %39, align 32
535 %41 = tail call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %7, <16 x i16> %40)
536 %42 = add <8 x i32> %41, %37
537 %43 = or disjoint i64 %36, 1
538 %44 = getelementptr inbounds <4 x i64>, ptr %3, i64 %43
539 %45 = load <16 x i16>, ptr %44, align 32
540 %46 = tail call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %7, <16 x i16> %45)
541 %47 = add <8 x i32> %46, %42
542 %48 = or disjoint i64 %36, 2
543 %49 = getelementptr inbounds <4 x i64>, ptr %3, i64 %48
544 %50 = load <16 x i16>, ptr %49, align 32
545 %51 = tail call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %7, <16 x i16> %50)
546 %52 = add <8 x i32> %51, %47
547 %53 = or disjoint i64 %36, 3
548 %54 = getelementptr inbounds <4 x i64>, ptr %3, i64 %53
549 %55 = load <16 x i16>, ptr %54, align 32
550 %56 = tail call <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16> %7, <16 x i16> %55)
551 %57 = add <8 x i32> %56, %52
552 %58 = add nuw nsw i64 %36, 4
554 %60 = icmp eq i64 %59, %13
555 br i1 %60, label %14, label %35
557 declare <8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16>, <16 x i16>)
559 ; void bar(int cnt, __m256i *c, __m256i b, __m256i *p) {
560 ; for (int i = 0; i < cnt; ++i) {
562 ; c[i] = _mm256_dpwssd_epi32(c[i], b, a);
565 define void @bar_256(i32 %0, ptr %1, <4 x i64> %2, ptr %3) {
566 ; AVX-LABEL: bar_256:
568 ; AVX-NEXT: testl %edi, %edi
569 ; AVX-NEXT: jle .LBB5_5
571 ; AVX-NEXT: movl %edi, %eax
572 ; AVX-NEXT: cmpl $1, %edi
573 ; AVX-NEXT: jne .LBB5_6
575 ; AVX-NEXT: xorl %ecx, %ecx
576 ; AVX-NEXT: jmp .LBB5_3
578 ; AVX-NEXT: movl %eax, %edi
579 ; AVX-NEXT: andl $-2, %edi
580 ; AVX-NEXT: movl $32, %r8d
581 ; AVX-NEXT: xorl %ecx, %ecx
582 ; AVX-NEXT: .p2align 4, 0x90
583 ; AVX-NEXT: .LBB5_7: # =>This Inner Loop Header: Depth=1
584 ; AVX-NEXT: vmovdqa (%rsi,%r8), %ymm1
585 ; AVX-NEXT: vpmaddwd -32(%rdx,%r8), %ymm0, %ymm2
586 ; AVX-NEXT: vpaddd -32(%rsi,%r8), %ymm2, %ymm2
587 ; AVX-NEXT: vmovdqa %ymm2, -32(%rsi,%r8)
588 ; AVX-NEXT: vpmaddwd (%rdx,%r8), %ymm0, %ymm2
589 ; AVX-NEXT: vpaddd %ymm2, %ymm1, %ymm1
590 ; AVX-NEXT: vmovdqa %ymm1, (%rsi,%r8)
591 ; AVX-NEXT: addq $2, %rcx
592 ; AVX-NEXT: addq $64, %r8
593 ; AVX-NEXT: cmpq %rcx, %rdi
594 ; AVX-NEXT: jne .LBB5_7
596 ; AVX-NEXT: testb $1, %al
597 ; AVX-NEXT: je .LBB5_5
599 ; AVX-NEXT: shlq $5, %rcx
600 ; AVX-NEXT: vmovdqa (%rsi,%rcx), %ymm1
601 ; AVX-NEXT: {vex} vpdpwssd (%rdx,%rcx), %ymm0, %ymm1
602 ; AVX-NEXT: vmovdqa %ymm1, (%rsi,%rcx)
604 ; AVX-NEXT: vzeroupper
607 ; AVX512-LABEL: bar_256:
609 ; AVX512-NEXT: testl %edi, %edi
610 ; AVX512-NEXT: jle .LBB5_5
611 ; AVX512-NEXT: # %bb.1:
612 ; AVX512-NEXT: movl %edi, %eax
613 ; AVX512-NEXT: cmpl $1, %edi
614 ; AVX512-NEXT: jne .LBB5_6
615 ; AVX512-NEXT: # %bb.2:
616 ; AVX512-NEXT: xorl %ecx, %ecx
617 ; AVX512-NEXT: jmp .LBB5_3
618 ; AVX512-NEXT: .LBB5_6:
619 ; AVX512-NEXT: movl %eax, %edi
620 ; AVX512-NEXT: andl $-2, %edi
621 ; AVX512-NEXT: movl $32, %r8d
622 ; AVX512-NEXT: xorl %ecx, %ecx
623 ; AVX512-NEXT: .p2align 4, 0x90
624 ; AVX512-NEXT: .LBB5_7: # =>This Inner Loop Header: Depth=1
625 ; AVX512-NEXT: vmovdqa (%rsi,%r8), %ymm1
626 ; AVX512-NEXT: vpmaddwd -32(%rdx,%r8), %ymm0, %ymm2
627 ; AVX512-NEXT: vpaddd -32(%rsi,%r8), %ymm2, %ymm2
628 ; AVX512-NEXT: vmovdqa %ymm2, -32(%rsi,%r8)
629 ; AVX512-NEXT: vpmaddwd (%rdx,%r8), %ymm0, %ymm2
630 ; AVX512-NEXT: vpaddd %ymm2, %ymm1, %ymm1
631 ; AVX512-NEXT: vmovdqa %ymm1, (%rsi,%r8)
632 ; AVX512-NEXT: addq $2, %rcx
633 ; AVX512-NEXT: addq $64, %r8
634 ; AVX512-NEXT: cmpq %rcx, %rdi
635 ; AVX512-NEXT: jne .LBB5_7
636 ; AVX512-NEXT: .LBB5_3:
637 ; AVX512-NEXT: testb $1, %al
638 ; AVX512-NEXT: je .LBB5_5
639 ; AVX512-NEXT: # %bb.4:
640 ; AVX512-NEXT: shlq $5, %rcx
641 ; AVX512-NEXT: vpmaddwd (%rdx,%rcx), %ymm0, %ymm0
642 ; AVX512-NEXT: vpaddd (%rsi,%rcx), %ymm0, %ymm0
643 ; AVX512-NEXT: vmovdqa %ymm0, (%rsi,%rcx)
644 ; AVX512-NEXT: .LBB5_5:
645 ; AVX512-NEXT: vzeroupper
647 %5 = icmp sgt i32 %0, 0
648 br i1 %5, label %6, label %22
651 %7 = bitcast <4 x i64> %2 to <8 x i32>
652 %8 = zext i32 %0 to i64
654 %10 = icmp eq i32 %0, 1
655 br i1 %10, label %13, label %11
658 %12 = and i64 %8, 4294967294
661 13: ; preds = %23, %6
662 %14 = phi i64 [ 0, %6 ], [ %37, %23 ]
663 %15 = icmp eq i64 %9, 0
664 br i1 %15, label %22, label %16
667 %17 = getelementptr inbounds <4 x i64>, ptr %3, i64 %14
668 %18 = load <8 x i32>, ptr %17, align 32
669 %19 = getelementptr inbounds <4 x i64>, ptr %1, i64 %14
670 %20 = load <8 x i32>, ptr %19, align 32
671 %21 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %20, <8 x i32> %7, <8 x i32> %18)
672 store <8 x i32> %21, ptr %19, align 32
675 22: ; preds = %16, %13, %4
678 23: ; preds = %23, %11
679 %24 = phi i64 [ 0, %11 ], [ %37, %23 ]
680 %25 = phi i64 [ 0, %11 ], [ %38, %23 ]
681 %26 = getelementptr inbounds <4 x i64>, ptr %3, i64 %24
682 %27 = load <8 x i32>, ptr %26, align 32
683 %28 = getelementptr inbounds <4 x i64>, ptr %1, i64 %24
684 %29 = load <8 x i32>, ptr %28, align 32
685 %30 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %29, <8 x i32> %7, <8 x i32> %27)
686 store <8 x i32> %30, ptr %28, align 32
687 %31 = or disjoint i64 %24, 1
688 %32 = getelementptr inbounds <4 x i64>, ptr %3, i64 %31
689 %33 = load <8 x i32>, ptr %32, align 32
690 %34 = getelementptr inbounds <4 x i64>, ptr %1, i64 %31
691 %35 = load <8 x i32>, ptr %34, align 32
692 %36 = tail call <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32> %35, <8 x i32> %7, <8 x i32> %33)
693 store <8 x i32> %36, ptr %34, align 32
694 %37 = add nuw nsw i64 %24, 2
696 %39 = icmp eq i64 %38, %12
697 br i1 %39, label %13, label %23
699 declare <8 x i32> @llvm.x86.avx512.vpdpwssd.256(<8 x i32>, <8 x i32>, <8 x i32>)
700 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: