Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / X86 / avxvnni-combine.ll
blob158a1fdf44fc6ad0dbea92a07da7d1db2140f515
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:
8 ; AVX:       # %bb.0:
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
16 ; AVX-NEXT:    retq
18 ; AVX512-LABEL: foo_reg_128:
19 ; AVX512:       # %bb.0:
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
27 ; AVX512-NEXT:    retq
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>
39   ret <2 x i64> %17
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) {
45 ; AVX-LABEL: foo_128:
46 ; AVX:       # %bb.0:
47 ; AVX-NEXT:    testl %edi, %edi
48 ; AVX-NEXT:    jle .LBB1_6
49 ; AVX-NEXT:  # %bb.1:
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
55 ; AVX-NEXT:  # %bb.2:
56 ; AVX-NEXT:    xorl %ecx, %ecx
57 ; AVX-NEXT:    jmp .LBB1_3
58 ; AVX-NEXT:  .LBB1_7:
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
75 ; AVX-NEXT:  .LBB1_3:
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
89 ; AVX-NEXT:  .LBB1_6:
90 ; AVX-NEXT:    retq
92 ; AVX512-LABEL: foo_128:
93 ; AVX512:       # %bb.0:
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:
137 ; AVX512-NEXT:    retq
138   %5 = icmp sgt i32 %0, 0
139   br i1 %5, label %6, label %33
141 6:                                                ; preds = %4
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
145   %10 = and i64 %9, 3
146   %11 = icmp ult i32 %0, 4
147   br i1 %11, label %14, label %12
149 12:                                               ; preds = %6
150   %13 = and i64 %9, 4294967292
151   br label %35
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
169   %28 = add i64 %22, 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>
176   br label %33
178 33:                                               ; preds = %30, %4
179   %34 = phi <2 x i64> [ %32, %30 ], [ %1, %4 ]
180   ret <2 x i64> %34
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
206   %59 = add i64 %38, 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:
213 ; AVX:       # %bb.0:
214 ; AVX-NEXT:    testl %edi, %edi
215 ; AVX-NEXT:    jle .LBB2_5
216 ; AVX-NEXT:  # %bb.1:
217 ; AVX-NEXT:    movl %edi, %eax
218 ; AVX-NEXT:    cmpl $1, %edi
219 ; AVX-NEXT:    jne .LBB2_6
220 ; AVX-NEXT:  # %bb.2:
221 ; AVX-NEXT:    xorl %ecx, %ecx
222 ; AVX-NEXT:    jmp .LBB2_3
223 ; AVX-NEXT:  .LBB2_6:
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
241 ; AVX-NEXT:  .LBB2_3:
242 ; AVX-NEXT:    testb $1, %al
243 ; AVX-NEXT:    je .LBB2_5
244 ; AVX-NEXT:  # %bb.4:
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)
249 ; AVX-NEXT:  .LBB2_5:
250 ; AVX-NEXT:    retq
252 ; AVX512-LABEL: bar_128:
253 ; AVX512:       # %bb.0:
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:
290 ; AVX512-NEXT:    retq
291   %5 = icmp sgt i32 %0, 0
292   br i1 %5, label %6, label %22
294 6:                                                ; preds = %4
295   %7 = bitcast <2 x i64> %2 to <4 x i32>
296   %8 = zext i32 %0 to i64
297   %9 = and i64 %8, 1
298   %10 = icmp eq i32 %0, 1
299   br i1 %10, label %13, label %11
301 11:                                               ; preds = %6
302   %12 = and i64 %8, 4294967294
303   br label %23
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
310 16:                                               ; preds = %13
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
317   br label %22
319 22:                                               ; preds = %16, %13, %4
320   ret void
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
339   %38 = add i64 %25, 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:
348 ; AVX:       # %bb.0:
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
356 ; AVX-NEXT:    retq
358 ; AVX512-LABEL: foo_reg_256:
359 ; AVX512:       # %bb.0:
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
367 ; AVX512-NEXT:    retq
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>
379   ret <4 x i64> %17
382 ; __m256i foo(int cnt, __m256i c, __m256i b, __m256i *p) {
383 ;     for (int i = 0; i < cnt; ++i) {
384 ;         __m256i a = p[i];
385 ;         __m256i m = _mm256_madd_epi16 (b, a);
386 ;         c = _mm256_add_epi32(m, c);
387 ;     }
388 ;     return c;
389 ; }
391 define <4 x i64> @foo_256(i32 %0, <4 x i64> %1, <4 x i64> %2, ptr %3) {
392 ; AVX-LABEL: foo_256:
393 ; AVX:       # %bb.0:
394 ; AVX-NEXT:    testl %edi, %edi
395 ; AVX-NEXT:    jle .LBB4_6
396 ; AVX-NEXT:  # %bb.1:
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
402 ; AVX-NEXT:  # %bb.2:
403 ; AVX-NEXT:    xorl %ecx, %ecx
404 ; AVX-NEXT:    jmp .LBB4_3
405 ; AVX-NEXT:  .LBB4_7:
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
422 ; AVX-NEXT:  .LBB4_3:
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
436 ; AVX-NEXT:  .LBB4_6:
437 ; AVX-NEXT:    retq
439 ; AVX512-LABEL: foo_256:
440 ; AVX512:       # %bb.0:
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:
484 ; AVX512-NEXT:    retq
485   %5 = icmp sgt i32 %0, 0
486   br i1 %5, label %6, label %33
488 6:                                                ; preds = %4
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
492   %10 = and i64 %9, 3
493   %11 = icmp ult i32 %0, 4
494   br i1 %11, label %14, label %12
496 12:                                               ; preds = %6
497   %13 = and i64 %9, 4294967292
498   br label %35
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
516   %28 = add i64 %22, 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>
523   br label %33
525 33:                                               ; preds = %30, %4
526   %34 = phi <4 x i64> [ %32, %30 ], [ %1, %4 ]
527   ret <4 x i64> %34
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
553   %59 = add i64 %38, 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) {
561 ;         __m256i a = p[i];
562 ;         c[i] = _mm256_dpwssd_epi32(c[i], b, a);
563 ;     }
564 ; }
565 define void @bar_256(i32 %0, ptr %1, <4 x i64> %2, ptr %3) {
566 ; AVX-LABEL: bar_256:
567 ; AVX:       # %bb.0:
568 ; AVX-NEXT:    testl %edi, %edi
569 ; AVX-NEXT:    jle .LBB5_5
570 ; AVX-NEXT:  # %bb.1:
571 ; AVX-NEXT:    movl %edi, %eax
572 ; AVX-NEXT:    cmpl $1, %edi
573 ; AVX-NEXT:    jne .LBB5_6
574 ; AVX-NEXT:  # %bb.2:
575 ; AVX-NEXT:    xorl %ecx, %ecx
576 ; AVX-NEXT:    jmp .LBB5_3
577 ; AVX-NEXT:  .LBB5_6:
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
595 ; AVX-NEXT:  .LBB5_3:
596 ; AVX-NEXT:    testb $1, %al
597 ; AVX-NEXT:    je .LBB5_5
598 ; AVX-NEXT:  # %bb.4:
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)
603 ; AVX-NEXT:  .LBB5_5:
604 ; AVX-NEXT:    vzeroupper
605 ; AVX-NEXT:    retq
607 ; AVX512-LABEL: bar_256:
608 ; AVX512:       # %bb.0:
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
646 ; AVX512-NEXT:    retq
647   %5 = icmp sgt i32 %0, 0
648   br i1 %5, label %6, label %22
650 6:                                                ; preds = %4
651   %7 = bitcast <4 x i64> %2 to <8 x i32>
652   %8 = zext i32 %0 to i64
653   %9 = and i64 %8, 1
654   %10 = icmp eq i32 %0, 1
655   br i1 %10, label %13, label %11
657 11:                                               ; preds = %6
658   %12 = and i64 %8, 4294967294
659   br label %23
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
666 16:                                               ; preds = %13
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
673   br label %22
675 22:                                               ; preds = %16, %13, %4
676   ret void
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
695   %38 = add i64 %25, 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:
701 ; ADL: {{.*}}
702 ; SPR: {{.*}}