[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / X86 / pmaddubsw.ll
blob3422429009c8d72735d0bbadcb3d73568e76466a
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefix=SSE
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX,AVX1
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX256,AVX2
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefixes=AVX,AVX256,AVX512,AVX512F
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw | FileCheck %s --check-prefixes=AVX,AVX256,AVX512,AVX512BW
8 ; NOTE: We're testing with loads because ABI lowering creates a concat_vectors that extract_vector_elt creation can see through.
9 ; This would require the combine to recreate the concat_vectors.
10 define <8 x i16> @pmaddubsw_128(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
11 ; SSE-LABEL: pmaddubsw_128:
12 ; SSE:       # %bb.0:
13 ; SSE-NEXT:    movdqa (%rsi), %xmm0
14 ; SSE-NEXT:    pmaddubsw (%rdi), %xmm0
15 ; SSE-NEXT:    retq
17 ; AVX-LABEL: pmaddubsw_128:
18 ; AVX:       # %bb.0:
19 ; AVX-NEXT:    vmovdqa (%rsi), %xmm0
20 ; AVX-NEXT:    vpmaddubsw (%rdi), %xmm0, %xmm0
21 ; AVX-NEXT:    retq
22   %A = load <16 x i8>, <16 x i8>* %Aptr
23   %B = load <16 x i8>, <16 x i8>* %Bptr
24   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
25   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
26   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
27   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
28   %A_even_ext = sext <8 x i8> %A_even to <8 x i32>
29   %B_even_ext = zext <8 x i8> %B_even to <8 x i32>
30   %A_odd_ext = sext <8 x i8> %A_odd to <8 x i32>
31   %B_odd_ext = zext <8 x i8> %B_odd to <8 x i32>
32   %even_mul = mul <8 x i32> %A_even_ext, %B_even_ext
33   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
34   %add = add <8 x i32> %even_mul, %odd_mul
35   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
36   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
37   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
38   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
39   %trunc = trunc <8 x i32> %min to <8 x i16>
40   ret <8 x i16> %trunc
43 define <16 x i16> @pmaddubsw_256(<32 x i8>* %Aptr, <32 x i8>* %Bptr) {
44 ; SSE-LABEL: pmaddubsw_256:
45 ; SSE:       # %bb.0:
46 ; SSE-NEXT:    movdqa (%rsi), %xmm0
47 ; SSE-NEXT:    movdqa 16(%rsi), %xmm1
48 ; SSE-NEXT:    pmaddubsw (%rdi), %xmm0
49 ; SSE-NEXT:    pmaddubsw 16(%rdi), %xmm1
50 ; SSE-NEXT:    retq
52 ; AVX1-LABEL: pmaddubsw_256:
53 ; AVX1:       # %bb.0:
54 ; AVX1-NEXT:    vmovdqa (%rsi), %xmm0
55 ; AVX1-NEXT:    vmovdqa 16(%rsi), %xmm1
56 ; AVX1-NEXT:    vpmaddubsw 16(%rdi), %xmm1, %xmm1
57 ; AVX1-NEXT:    vpmaddubsw (%rdi), %xmm0, %xmm0
58 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
59 ; AVX1-NEXT:    retq
61 ; AVX256-LABEL: pmaddubsw_256:
62 ; AVX256:       # %bb.0:
63 ; AVX256-NEXT:    vmovdqa (%rsi), %ymm0
64 ; AVX256-NEXT:    vpmaddubsw (%rdi), %ymm0, %ymm0
65 ; AVX256-NEXT:    retq
66   %A = load <32 x i8>, <32 x i8>* %Aptr
67   %B = load <32 x i8>, <32 x i8>* %Bptr
68   %A_even = shufflevector <32 x i8> %A, <32 x i8> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
69   %A_odd = shufflevector <32 x i8> %A, <32 x i8> undef, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31>
70   %B_even = shufflevector <32 x i8> %B, <32 x i8> undef, <16 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30>
71   %B_odd = shufflevector <32 x i8> %B, <32 x i8> undef, <16 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31>
72   %A_even_ext = sext <16 x i8> %A_even to <16 x i32>
73   %B_even_ext = zext <16 x i8> %B_even to <16 x i32>
74   %A_odd_ext = sext <16 x i8> %A_odd to <16 x i32>
75   %B_odd_ext = zext <16 x i8> %B_odd to <16 x i32>
76   %even_mul = mul <16 x i32> %A_even_ext, %B_even_ext
77   %odd_mul = mul <16 x i32> %A_odd_ext, %B_odd_ext
78   %add = add <16 x i32> %even_mul, %odd_mul
79   %cmp_max = icmp sgt <16 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
80   %max = select <16 x i1> %cmp_max, <16 x i32> %add, <16 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
81   %cmp_min = icmp slt <16 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
82   %min = select <16 x i1> %cmp_min, <16 x i32> %max, <16 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
83   %trunc = trunc <16 x i32> %min to <16 x i16>
84   ret <16 x i16> %trunc
87 define <64 x i16> @pmaddubsw_512(<128 x i8>* %Aptr, <128 x i8>* %Bptr) {
88 ; SSE-LABEL: pmaddubsw_512:
89 ; SSE:       # %bb.0:
90 ; SSE-NEXT:    movq %rdi, %rax
91 ; SSE-NEXT:    movdqa (%rdx), %xmm0
92 ; SSE-NEXT:    movdqa 16(%rdx), %xmm1
93 ; SSE-NEXT:    movdqa 32(%rdx), %xmm2
94 ; SSE-NEXT:    movdqa 48(%rdx), %xmm3
95 ; SSE-NEXT:    pmaddubsw (%rsi), %xmm0
96 ; SSE-NEXT:    pmaddubsw 16(%rsi), %xmm1
97 ; SSE-NEXT:    pmaddubsw 32(%rsi), %xmm2
98 ; SSE-NEXT:    pmaddubsw 48(%rsi), %xmm3
99 ; SSE-NEXT:    movdqa 64(%rdx), %xmm4
100 ; SSE-NEXT:    pmaddubsw 64(%rsi), %xmm4
101 ; SSE-NEXT:    movdqa 80(%rdx), %xmm5
102 ; SSE-NEXT:    pmaddubsw 80(%rsi), %xmm5
103 ; SSE-NEXT:    movdqa 96(%rdx), %xmm6
104 ; SSE-NEXT:    pmaddubsw 96(%rsi), %xmm6
105 ; SSE-NEXT:    movdqa 112(%rdx), %xmm7
106 ; SSE-NEXT:    pmaddubsw 112(%rsi), %xmm7
107 ; SSE-NEXT:    movdqa %xmm7, 112(%rdi)
108 ; SSE-NEXT:    movdqa %xmm6, 96(%rdi)
109 ; SSE-NEXT:    movdqa %xmm5, 80(%rdi)
110 ; SSE-NEXT:    movdqa %xmm4, 64(%rdi)
111 ; SSE-NEXT:    movdqa %xmm3, 48(%rdi)
112 ; SSE-NEXT:    movdqa %xmm2, 32(%rdi)
113 ; SSE-NEXT:    movdqa %xmm1, 16(%rdi)
114 ; SSE-NEXT:    movdqa %xmm0, (%rdi)
115 ; SSE-NEXT:    retq
117 ; AVX1-LABEL: pmaddubsw_512:
118 ; AVX1:       # %bb.0:
119 ; AVX1-NEXT:    vmovdqa (%rsi), %xmm0
120 ; AVX1-NEXT:    vmovdqa 16(%rsi), %xmm1
121 ; AVX1-NEXT:    vmovdqa 32(%rsi), %xmm2
122 ; AVX1-NEXT:    vmovdqa 48(%rsi), %xmm3
123 ; AVX1-NEXT:    vpmaddubsw 16(%rdi), %xmm1, %xmm1
124 ; AVX1-NEXT:    vpmaddubsw (%rdi), %xmm0, %xmm0
125 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
126 ; AVX1-NEXT:    vpmaddubsw 48(%rdi), %xmm3, %xmm1
127 ; AVX1-NEXT:    vpmaddubsw 32(%rdi), %xmm2, %xmm2
128 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm2, %ymm1
129 ; AVX1-NEXT:    vmovdqa 80(%rsi), %xmm2
130 ; AVX1-NEXT:    vpmaddubsw 80(%rdi), %xmm2, %xmm2
131 ; AVX1-NEXT:    vmovdqa 64(%rsi), %xmm3
132 ; AVX1-NEXT:    vpmaddubsw 64(%rdi), %xmm3, %xmm3
133 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm3, %ymm2
134 ; AVX1-NEXT:    vmovdqa 112(%rsi), %xmm3
135 ; AVX1-NEXT:    vpmaddubsw 112(%rdi), %xmm3, %xmm3
136 ; AVX1-NEXT:    vmovdqa 96(%rsi), %xmm4
137 ; AVX1-NEXT:    vpmaddubsw 96(%rdi), %xmm4, %xmm4
138 ; AVX1-NEXT:    vinsertf128 $1, %xmm3, %ymm4, %ymm3
139 ; AVX1-NEXT:    retq
141 ; AVX2-LABEL: pmaddubsw_512:
142 ; AVX2:       # %bb.0:
143 ; AVX2-NEXT:    vmovdqa (%rsi), %ymm0
144 ; AVX2-NEXT:    vmovdqa 32(%rsi), %ymm1
145 ; AVX2-NEXT:    vmovdqa 64(%rsi), %ymm2
146 ; AVX2-NEXT:    vmovdqa 96(%rsi), %ymm3
147 ; AVX2-NEXT:    vpmaddubsw (%rdi), %ymm0, %ymm0
148 ; AVX2-NEXT:    vpmaddubsw 32(%rdi), %ymm1, %ymm1
149 ; AVX2-NEXT:    vpmaddubsw 64(%rdi), %ymm2, %ymm2
150 ; AVX2-NEXT:    vpmaddubsw 96(%rdi), %ymm3, %ymm3
151 ; AVX2-NEXT:    retq
153 ; AVX512F-LABEL: pmaddubsw_512:
154 ; AVX512F:       # %bb.0:
155 ; AVX512F-NEXT:    vmovdqa (%rsi), %ymm0
156 ; AVX512F-NEXT:    vmovdqa 32(%rsi), %ymm1
157 ; AVX512F-NEXT:    vmovdqa 64(%rsi), %ymm2
158 ; AVX512F-NEXT:    vmovdqa 96(%rsi), %ymm3
159 ; AVX512F-NEXT:    vpmaddubsw (%rdi), %ymm0, %ymm0
160 ; AVX512F-NEXT:    vpmaddubsw 32(%rdi), %ymm1, %ymm1
161 ; AVX512F-NEXT:    vpmaddubsw 64(%rdi), %ymm2, %ymm2
162 ; AVX512F-NEXT:    vpmaddubsw 96(%rdi), %ymm3, %ymm3
163 ; AVX512F-NEXT:    retq
165 ; AVX512BW-LABEL: pmaddubsw_512:
166 ; AVX512BW:       # %bb.0:
167 ; AVX512BW-NEXT:    vmovdqa64 (%rsi), %zmm0
168 ; AVX512BW-NEXT:    vmovdqa64 64(%rsi), %zmm1
169 ; AVX512BW-NEXT:    vpmaddubsw (%rdi), %zmm0, %zmm0
170 ; AVX512BW-NEXT:    vpmaddubsw 64(%rdi), %zmm1, %zmm1
171 ; AVX512BW-NEXT:    retq
172   %A = load <128 x i8>, <128 x i8>* %Aptr
173   %B = load <128 x i8>, <128 x i8>* %Bptr
174   %A_even = shufflevector <128 x i8> %A, <128 x i8> undef, <64 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30, i32 32, i32 34, i32 36, i32 38, i32 40, i32 42, i32 44, i32 46, i32 48, i32 50, i32 52, i32 54, i32 56, i32 58, i32 60, i32 62, i32 64, i32 66, i32 68, i32 70, i32 72, i32 74, i32 76, i32 78, i32 80, i32 82, i32 84, i32 86, i32 88, i32 90, i32 92, i32 94, i32 96, i32 98, i32 100, i32 102, i32 104, i32 106, i32 108, i32 110, i32 112, i32 114, i32 116, i32 118, i32 120, i32 122, i32 124, i32 126>
175   %A_odd = shufflevector <128 x i8> %A, <128 x i8> undef, <64 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31, i32 33, i32 35, i32 37, i32 39, i32 41, i32 43, i32 45, i32 47, i32 49, i32 51, i32 53, i32 55, i32 57, i32 59, i32 61, i32 63, i32 65, i32 67, i32 69, i32 71, i32 73, i32 75, i32 77, i32 79, i32 81, i32 83, i32 85, i32 87, i32 89, i32 91, i32 93, i32 95, i32 97, i32 99, i32 101, i32 103, i32 105, i32 107, i32 109, i32 111, i32 113, i32 115, i32 117, i32 119, i32 121, i32 123, i32 125, i32 127>
176   %B_even = shufflevector <128 x i8> %B, <128 x i8> undef, <64 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26, i32 28, i32 30, i32 32, i32 34, i32 36, i32 38, i32 40, i32 42, i32 44, i32 46, i32 48, i32 50, i32 52, i32 54, i32 56, i32 58, i32 60, i32 62, i32 64, i32 66, i32 68, i32 70, i32 72, i32 74, i32 76, i32 78, i32 80, i32 82, i32 84, i32 86, i32 88, i32 90, i32 92, i32 94, i32 96, i32 98, i32 100, i32 102, i32 104, i32 106, i32 108, i32 110, i32 112, i32 114, i32 116, i32 118, i32 120, i32 122, i32 124, i32 126>
177   %B_odd = shufflevector <128 x i8> %B, <128 x i8> undef, <64 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15, i32 17, i32 19, i32 21, i32 23, i32 25, i32 27, i32 29, i32 31, i32 33, i32 35, i32 37, i32 39, i32 41, i32 43, i32 45, i32 47, i32 49, i32 51, i32 53, i32 55, i32 57, i32 59, i32 61, i32 63, i32 65, i32 67, i32 69, i32 71, i32 73, i32 75, i32 77, i32 79, i32 81, i32 83, i32 85, i32 87, i32 89, i32 91, i32 93, i32 95, i32 97, i32 99, i32 101, i32 103, i32 105, i32 107, i32 109, i32 111, i32 113, i32 115, i32 117, i32 119, i32 121, i32 123, i32 125, i32 127>
178   %A_even_ext = sext <64 x i8> %A_even to <64 x i32>
179   %B_even_ext = zext <64 x i8> %B_even to <64 x i32>
180   %A_odd_ext = sext <64 x i8> %A_odd to <64 x i32>
181   %B_odd_ext = zext <64 x i8> %B_odd to <64 x i32>
182   %even_mul = mul <64 x i32> %A_even_ext, %B_even_ext
183   %odd_mul = mul <64 x i32> %A_odd_ext, %B_odd_ext
184   %add = add <64 x i32> %even_mul, %odd_mul
185   %cmp_max = icmp sgt <64 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
186   %max = select <64 x i1> %cmp_max, <64 x i32> %add, <64 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
187   %cmp_min = icmp slt <64 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
188   %min = select <64 x i1> %cmp_min, <64 x i32> %max, <64 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
189   %trunc = trunc <64 x i32> %min to <64 x i16>
190   ret <64 x i16> %trunc
193 define <8 x i16> @pmaddubsw_swapped_indices(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
194 ; SSE-LABEL: pmaddubsw_swapped_indices:
195 ; SSE:       # %bb.0:
196 ; SSE-NEXT:    movdqa (%rsi), %xmm0
197 ; SSE-NEXT:    pmaddubsw (%rdi), %xmm0
198 ; SSE-NEXT:    retq
200 ; AVX-LABEL: pmaddubsw_swapped_indices:
201 ; AVX:       # %bb.0:
202 ; AVX-NEXT:    vmovdqa (%rsi), %xmm0
203 ; AVX-NEXT:    vpmaddubsw (%rdi), %xmm0, %xmm0
204 ; AVX-NEXT:    retq
205   %A = load <16 x i8>, <16 x i8>* %Aptr
206   %B = load <16 x i8>, <16 x i8>* %Bptr
207   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 2, i32 5, i32 6, i32 9, i32 10, i32 13, i32 14> ;indices aren't all even
208   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 3, i32 4, i32 7, i32 8, i32 11, i32 12, i32 15> ;indices aren't all odd
209   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 2, i32 5, i32 6, i32 9, i32 10, i32 13, i32 14> ;same indices as A
210   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 3, i32 4, i32 7, i32 8, i32 11, i32 12, i32 15> ;same indices as A
211   %A_even_ext = sext <8 x i8> %A_even to <8 x i32>
212   %B_even_ext = zext <8 x i8> %B_even to <8 x i32>
213   %A_odd_ext = sext <8 x i8> %A_odd to <8 x i32>
214   %B_odd_ext = zext <8 x i8> %B_odd to <8 x i32>
215   %even_mul = mul <8 x i32> %A_even_ext, %B_even_ext
216   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
217   %add = add <8 x i32> %even_mul, %odd_mul
218   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
219   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
220   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
221   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
222   %trunc = trunc <8 x i32> %min to <8 x i16>
223   ret <8 x i16> %trunc
226 define <8 x i16> @pmaddubsw_swapped_extend(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
227 ; SSE-LABEL: pmaddubsw_swapped_extend:
228 ; SSE:       # %bb.0:
229 ; SSE-NEXT:    movdqa (%rdi), %xmm0
230 ; SSE-NEXT:    pmaddubsw (%rsi), %xmm0
231 ; SSE-NEXT:    retq
233 ; AVX-LABEL: pmaddubsw_swapped_extend:
234 ; AVX:       # %bb.0:
235 ; AVX-NEXT:    vmovdqa (%rdi), %xmm0
236 ; AVX-NEXT:    vpmaddubsw (%rsi), %xmm0, %xmm0
237 ; AVX-NEXT:    retq
238   %A = load <16 x i8>, <16 x i8>* %Aptr
239   %B = load <16 x i8>, <16 x i8>* %Bptr
240   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
241   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
242   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
243   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
244   %A_even_ext = zext <8 x i8> %A_even to <8 x i32>
245   %B_even_ext = sext <8 x i8> %B_even to <8 x i32>
246   %A_odd_ext = zext <8 x i8> %A_odd to <8 x i32>
247   %B_odd_ext = sext <8 x i8> %B_odd to <8 x i32>
248   %even_mul = mul <8 x i32> %A_even_ext, %B_even_ext
249   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
250   %add = add <8 x i32> %even_mul, %odd_mul
251   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
252   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
253   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
254   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
255   %trunc = trunc <8 x i32> %min to <8 x i16>
256   ret <8 x i16> %trunc
259 define <8 x i16> @pmaddubsw_commuted_mul(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
260 ; SSE-LABEL: pmaddubsw_commuted_mul:
261 ; SSE:       # %bb.0:
262 ; SSE-NEXT:    movdqa (%rsi), %xmm0
263 ; SSE-NEXT:    pmaddubsw (%rdi), %xmm0
264 ; SSE-NEXT:    retq
266 ; AVX-LABEL: pmaddubsw_commuted_mul:
267 ; AVX:       # %bb.0:
268 ; AVX-NEXT:    vmovdqa (%rsi), %xmm0
269 ; AVX-NEXT:    vpmaddubsw (%rdi), %xmm0, %xmm0
270 ; AVX-NEXT:    retq
271   %A = load <16 x i8>, <16 x i8>* %Aptr
272   %B = load <16 x i8>, <16 x i8>* %Bptr
273   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
274   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
275   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
276   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
277   %A_even_ext = sext <8 x i8> %A_even to <8 x i32>
278   %B_even_ext = zext <8 x i8> %B_even to <8 x i32>
279   %A_odd_ext = sext <8 x i8> %A_odd to <8 x i32>
280   %B_odd_ext = zext <8 x i8> %B_odd to <8 x i32>
281   %even_mul = mul <8 x i32> %B_even_ext, %A_even_ext
282   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
283   %add = add <8 x i32> %even_mul, %odd_mul
284   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
285   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
286   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
287   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
288   %trunc = trunc <8 x i32> %min to <8 x i16>
289   ret <8 x i16> %trunc
292 define <8 x i16> @pmaddubsw_bad_extend(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
293 ; SSE-LABEL: pmaddubsw_bad_extend:
294 ; SSE:       # %bb.0:
295 ; SSE-NEXT:    movdqa (%rdi), %xmm1
296 ; SSE-NEXT:    movdqa (%rsi), %xmm0
297 ; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
298 ; SSE-NEXT:    pand %xmm0, %xmm2
299 ; SSE-NEXT:    movdqa %xmm1, %xmm3
300 ; SSE-NEXT:    psllw $8, %xmm3
301 ; SSE-NEXT:    psraw $8, %xmm3
302 ; SSE-NEXT:    movdqa %xmm3, %xmm4
303 ; SSE-NEXT:    pmulhw %xmm2, %xmm4
304 ; SSE-NEXT:    pmullw %xmm2, %xmm3
305 ; SSE-NEXT:    movdqa %xmm3, %xmm2
306 ; SSE-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]
307 ; SSE-NEXT:    punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7]
308 ; SSE-NEXT:    psraw $8, %xmm0
309 ; SSE-NEXT:    psrlw $8, %xmm1
310 ; SSE-NEXT:    movdqa %xmm1, %xmm4
311 ; SSE-NEXT:    pmulhw %xmm0, %xmm4
312 ; SSE-NEXT:    pmullw %xmm0, %xmm1
313 ; SSE-NEXT:    movdqa %xmm1, %xmm0
314 ; SSE-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3]
315 ; SSE-NEXT:    paddd %xmm2, %xmm0
316 ; SSE-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm4[4],xmm1[5],xmm4[5],xmm1[6],xmm4[6],xmm1[7],xmm4[7]
317 ; SSE-NEXT:    paddd %xmm3, %xmm1
318 ; SSE-NEXT:    packssdw %xmm1, %xmm0
319 ; SSE-NEXT:    retq
321 ; AVX1-LABEL: pmaddubsw_bad_extend:
322 ; AVX1:       # %bb.0:
323 ; AVX1-NEXT:    vmovdqa (%rdi), %xmm0
324 ; AVX1-NEXT:    vmovdqa (%rsi), %xmm1
325 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
326 ; AVX1-NEXT:    vpshufb %xmm2, %xmm0, %xmm3
327 ; AVX1-NEXT:    vpmovsxbd %xmm3, %xmm4
328 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm3 = xmm3[1,1,2,3]
329 ; AVX1-NEXT:    vpmovsxbd %xmm3, %xmm3
330 ; AVX1-NEXT:    vpshufb %xmm2, %xmm1, %xmm2
331 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm5 = xmm2[0],zero,zero,zero,xmm2[1],zero,zero,zero,xmm2[2],zero,zero,zero,xmm2[3],zero,zero,zero
332 ; AVX1-NEXT:    vpmulld %xmm5, %xmm4, %xmm4
333 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[1,1,2,3]
334 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm2 = xmm2[0],zero,zero,zero,xmm2[1],zero,zero,zero,xmm2[2],zero,zero,zero,xmm2[3],zero,zero,zero
335 ; AVX1-NEXT:    vpmulld %xmm2, %xmm3, %xmm2
336 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm3 = <1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u>
337 ; AVX1-NEXT:    vpshufb %xmm3, %xmm0, %xmm0
338 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm5 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
339 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
340 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero
341 ; AVX1-NEXT:    vpshufb %xmm3, %xmm1, %xmm1
342 ; AVX1-NEXT:    vpmovsxbd %xmm1, %xmm3
343 ; AVX1-NEXT:    vpmulld %xmm3, %xmm5, %xmm3
344 ; AVX1-NEXT:    vpaddd %xmm3, %xmm4, %xmm3
345 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[1,1,2,3]
346 ; AVX1-NEXT:    vpmovsxbd %xmm1, %xmm1
347 ; AVX1-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
348 ; AVX1-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
349 ; AVX1-NEXT:    vpackssdw %xmm0, %xmm3, %xmm0
350 ; AVX1-NEXT:    retq
352 ; AVX2-LABEL: pmaddubsw_bad_extend:
353 ; AVX2:       # %bb.0:
354 ; AVX2-NEXT:    vmovdqa (%rdi), %xmm0
355 ; AVX2-NEXT:    vmovdqa (%rsi), %xmm1
356 ; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
357 ; AVX2-NEXT:    vpshufb %xmm2, %xmm0, %xmm3
358 ; AVX2-NEXT:    vpmovsxbd %xmm3, %ymm3
359 ; AVX2-NEXT:    vpshufb %xmm2, %xmm1, %xmm2
360 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} ymm2 = xmm2[0],zero,zero,zero,xmm2[1],zero,zero,zero,xmm2[2],zero,zero,zero,xmm2[3],zero,zero,zero,xmm2[4],zero,zero,zero,xmm2[5],zero,zero,zero,xmm2[6],zero,zero,zero,xmm2[7],zero,zero,zero
361 ; AVX2-NEXT:    vpmulld %ymm2, %ymm3, %ymm2
362 ; AVX2-NEXT:    vmovdqa {{.*#+}} xmm3 = <1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u>
363 ; AVX2-NEXT:    vpshufb %xmm3, %xmm0, %xmm0
364 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero
365 ; AVX2-NEXT:    vpshufb %xmm3, %xmm1, %xmm1
366 ; AVX2-NEXT:    vpmovsxbd %xmm1, %ymm1
367 ; AVX2-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
368 ; AVX2-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
369 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
370 ; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
371 ; AVX2-NEXT:    vzeroupper
372 ; AVX2-NEXT:    retq
374 ; AVX512-LABEL: pmaddubsw_bad_extend:
375 ; AVX512:       # %bb.0:
376 ; AVX512-NEXT:    vmovdqa (%rdi), %xmm0
377 ; AVX512-NEXT:    vmovdqa (%rsi), %xmm1
378 ; AVX512-NEXT:    vmovdqa {{.*#+}} xmm2 = <0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u>
379 ; AVX512-NEXT:    vpshufb %xmm2, %xmm0, %xmm3
380 ; AVX512-NEXT:    vpmovsxbd %xmm3, %ymm3
381 ; AVX512-NEXT:    vpshufb %xmm2, %xmm1, %xmm2
382 ; AVX512-NEXT:    vpmovzxbd {{.*#+}} ymm2 = xmm2[0],zero,zero,zero,xmm2[1],zero,zero,zero,xmm2[2],zero,zero,zero,xmm2[3],zero,zero,zero,xmm2[4],zero,zero,zero,xmm2[5],zero,zero,zero,xmm2[6],zero,zero,zero,xmm2[7],zero,zero,zero
383 ; AVX512-NEXT:    vpmulld %ymm2, %ymm3, %ymm2
384 ; AVX512-NEXT:    vmovdqa {{.*#+}} xmm3 = <1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u>
385 ; AVX512-NEXT:    vpshufb %xmm3, %xmm0, %xmm0
386 ; AVX512-NEXT:    vpmovzxbd {{.*#+}} ymm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero
387 ; AVX512-NEXT:    vpshufb %xmm3, %xmm1, %xmm1
388 ; AVX512-NEXT:    vpmovsxbd %xmm1, %ymm1
389 ; AVX512-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
390 ; AVX512-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
391 ; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [4294934528,4294934528,4294934528,4294934528,4294934528,4294934528,4294934528,4294934528]
392 ; AVX512-NEXT:    vpmaxsd %ymm1, %ymm0, %ymm0
393 ; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [32767,32767,32767,32767,32767,32767,32767,32767]
394 ; AVX512-NEXT:    vpminsd %ymm1, %ymm0, %ymm0
395 ; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
396 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
397 ; AVX512-NEXT:    vzeroupper
398 ; AVX512-NEXT:    retq
399   %A = load <16 x i8>, <16 x i8>* %Aptr
400   %B = load <16 x i8>, <16 x i8>* %Bptr
401   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
402   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
403   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
404   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
405   %A_even_ext = sext <8 x i8> %A_even to <8 x i32>
406   %B_even_ext = zext <8 x i8> %B_even to <8 x i32>
407   %A_odd_ext = zext <8 x i8> %A_odd to <8 x i32>
408   %B_odd_ext = sext <8 x i8> %B_odd to <8 x i32>
409   %even_mul = mul <8 x i32> %A_even_ext, %B_even_ext
410   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
411   %add = add <8 x i32> %even_mul, %odd_mul
412   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
413   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
414   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
415   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
416   %trunc = trunc <8 x i32> %min to <8 x i16>
417   ret <8 x i16> %trunc
420 define <8 x i16> @pmaddubsw_bad_indices(<16 x i8>* %Aptr, <16 x i8>* %Bptr) {
421 ; SSE-LABEL: pmaddubsw_bad_indices:
422 ; SSE:       # %bb.0:
423 ; SSE-NEXT:    movdqa (%rdi), %xmm1
424 ; SSE-NEXT:    movdqa (%rsi), %xmm0
425 ; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0]
426 ; SSE-NEXT:    pand %xmm0, %xmm2
427 ; SSE-NEXT:    movdqa %xmm1, %xmm3
428 ; SSE-NEXT:    pshufb {{.*#+}} xmm3 = xmm3[u,1,u,2,u,5,u,6,u,9,u,10,u,13,u,14]
429 ; SSE-NEXT:    psraw $8, %xmm3
430 ; SSE-NEXT:    movdqa %xmm3, %xmm4
431 ; SSE-NEXT:    pmulhw %xmm2, %xmm4
432 ; SSE-NEXT:    pmullw %xmm2, %xmm3
433 ; SSE-NEXT:    movdqa %xmm3, %xmm2
434 ; SSE-NEXT:    punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm4[0],xmm2[1],xmm4[1],xmm2[2],xmm4[2],xmm2[3],xmm4[3]
435 ; SSE-NEXT:    punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm4[4],xmm3[5],xmm4[5],xmm3[6],xmm4[6],xmm3[7],xmm4[7]
436 ; SSE-NEXT:    psrlw $8, %xmm0
437 ; SSE-NEXT:    pshufb {{.*#+}} xmm1 = xmm1[u,0,u,3,u,4,u,7,u,8,u,11,u,12,u,15]
438 ; SSE-NEXT:    psraw $8, %xmm1
439 ; SSE-NEXT:    movdqa %xmm1, %xmm4
440 ; SSE-NEXT:    pmulhw %xmm0, %xmm4
441 ; SSE-NEXT:    pmullw %xmm0, %xmm1
442 ; SSE-NEXT:    movdqa %xmm1, %xmm0
443 ; SSE-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm4[0],xmm0[1],xmm4[1],xmm0[2],xmm4[2],xmm0[3],xmm4[3]
444 ; SSE-NEXT:    paddd %xmm2, %xmm0
445 ; SSE-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm4[4],xmm1[5],xmm4[5],xmm1[6],xmm4[6],xmm1[7],xmm4[7]
446 ; SSE-NEXT:    paddd %xmm3, %xmm1
447 ; SSE-NEXT:    packssdw %xmm1, %xmm0
448 ; SSE-NEXT:    retq
450 ; AVX1-LABEL: pmaddubsw_bad_indices:
451 ; AVX1:       # %bb.0:
452 ; AVX1-NEXT:    vmovdqa (%rdi), %xmm0
453 ; AVX1-NEXT:    vmovdqa (%rsi), %xmm1
454 ; AVX1-NEXT:    vpshufb {{.*#+}} xmm2 = xmm0[1,2,5,6,9,10,13,14,u,u,u,u,u,u,u,u]
455 ; AVX1-NEXT:    vpmovsxbd %xmm2, %xmm3
456 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[1,1,2,3]
457 ; AVX1-NEXT:    vpmovsxbd %xmm2, %xmm2
458 ; AVX1-NEXT:    vpshufb {{.*#+}} xmm4 = xmm1[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
459 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm5 = xmm4[0],zero,zero,zero,xmm4[1],zero,zero,zero,xmm4[2],zero,zero,zero,xmm4[3],zero,zero,zero
460 ; AVX1-NEXT:    vpmulld %xmm5, %xmm3, %xmm3
461 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm4 = xmm4[1,1,2,3]
462 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm4 = xmm4[0],zero,zero,zero,xmm4[1],zero,zero,zero,xmm4[2],zero,zero,zero,xmm4[3],zero,zero,zero
463 ; AVX1-NEXT:    vpmulld %xmm4, %xmm2, %xmm2
464 ; AVX1-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,3,4,7,8,11,12,15,u,u,u,u,u,u,u,u]
465 ; AVX1-NEXT:    vpmovsxbd %xmm0, %xmm4
466 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,2,3]
467 ; AVX1-NEXT:    vpmovsxbd %xmm0, %xmm0
468 ; AVX1-NEXT:    vpshufb {{.*#+}} xmm1 = xmm1[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
469 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm5 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero
470 ; AVX1-NEXT:    vpmulld %xmm5, %xmm4, %xmm4
471 ; AVX1-NEXT:    vpaddd %xmm4, %xmm3, %xmm3
472 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[1,1,2,3]
473 ; AVX1-NEXT:    vpmovzxbd {{.*#+}} xmm1 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero
474 ; AVX1-NEXT:    vpmulld %xmm1, %xmm0, %xmm0
475 ; AVX1-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
476 ; AVX1-NEXT:    vpackssdw %xmm0, %xmm3, %xmm0
477 ; AVX1-NEXT:    retq
479 ; AVX2-LABEL: pmaddubsw_bad_indices:
480 ; AVX2:       # %bb.0:
481 ; AVX2-NEXT:    vmovdqa (%rdi), %xmm0
482 ; AVX2-NEXT:    vmovdqa (%rsi), %xmm1
483 ; AVX2-NEXT:    vpshufb {{.*#+}} xmm2 = xmm0[1,2,5,6,9,10,13,14,u,u,u,u,u,u,u,u]
484 ; AVX2-NEXT:    vpmovsxbd %xmm2, %ymm2
485 ; AVX2-NEXT:    vpshufb {{.*#+}} xmm3 = xmm1[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
486 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} ymm3 = xmm3[0],zero,zero,zero,xmm3[1],zero,zero,zero,xmm3[2],zero,zero,zero,xmm3[3],zero,zero,zero,xmm3[4],zero,zero,zero,xmm3[5],zero,zero,zero,xmm3[6],zero,zero,zero,xmm3[7],zero,zero,zero
487 ; AVX2-NEXT:    vpmulld %ymm3, %ymm2, %ymm2
488 ; AVX2-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,3,4,7,8,11,12,15,u,u,u,u,u,u,u,u]
489 ; AVX2-NEXT:    vpmovsxbd %xmm0, %ymm0
490 ; AVX2-NEXT:    vpshufb {{.*#+}} xmm1 = xmm1[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
491 ; AVX2-NEXT:    vpmovzxbd {{.*#+}} ymm1 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero,xmm1[4],zero,zero,zero,xmm1[5],zero,zero,zero,xmm1[6],zero,zero,zero,xmm1[7],zero,zero,zero
492 ; AVX2-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
493 ; AVX2-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
494 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
495 ; AVX2-NEXT:    vpackssdw %xmm1, %xmm0, %xmm0
496 ; AVX2-NEXT:    vzeroupper
497 ; AVX2-NEXT:    retq
499 ; AVX512-LABEL: pmaddubsw_bad_indices:
500 ; AVX512:       # %bb.0:
501 ; AVX512-NEXT:    vmovdqa (%rdi), %xmm0
502 ; AVX512-NEXT:    vmovdqa (%rsi), %xmm1
503 ; AVX512-NEXT:    vpshufb {{.*#+}} xmm2 = xmm0[1,2,5,6,9,10,13,14,u,u,u,u,u,u,u,u]
504 ; AVX512-NEXT:    vpmovsxbd %xmm2, %ymm2
505 ; AVX512-NEXT:    vpshufb {{.*#+}} xmm3 = xmm1[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
506 ; AVX512-NEXT:    vpmovzxbd {{.*#+}} ymm3 = xmm3[0],zero,zero,zero,xmm3[1],zero,zero,zero,xmm3[2],zero,zero,zero,xmm3[3],zero,zero,zero,xmm3[4],zero,zero,zero,xmm3[5],zero,zero,zero,xmm3[6],zero,zero,zero,xmm3[7],zero,zero,zero
507 ; AVX512-NEXT:    vpmulld %ymm3, %ymm2, %ymm2
508 ; AVX512-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,3,4,7,8,11,12,15,u,u,u,u,u,u,u,u]
509 ; AVX512-NEXT:    vpmovsxbd %xmm0, %ymm0
510 ; AVX512-NEXT:    vpshufb {{.*#+}} xmm1 = xmm1[1,3,5,7,9,11,13,15,u,u,u,u,u,u,u,u]
511 ; AVX512-NEXT:    vpmovzxbd {{.*#+}} ymm1 = xmm1[0],zero,zero,zero,xmm1[1],zero,zero,zero,xmm1[2],zero,zero,zero,xmm1[3],zero,zero,zero,xmm1[4],zero,zero,zero,xmm1[5],zero,zero,zero,xmm1[6],zero,zero,zero,xmm1[7],zero,zero,zero
512 ; AVX512-NEXT:    vpmulld %ymm1, %ymm0, %ymm0
513 ; AVX512-NEXT:    vpaddd %ymm0, %ymm2, %ymm0
514 ; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [4294934528,4294934528,4294934528,4294934528,4294934528,4294934528,4294934528,4294934528]
515 ; AVX512-NEXT:    vpmaxsd %ymm1, %ymm0, %ymm0
516 ; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 = [32767,32767,32767,32767,32767,32767,32767,32767]
517 ; AVX512-NEXT:    vpminsd %ymm1, %ymm0, %ymm0
518 ; AVX512-NEXT:    vpmovdw %zmm0, %ymm0
519 ; AVX512-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
520 ; AVX512-NEXT:    vzeroupper
521 ; AVX512-NEXT:    retq
522   %A = load <16 x i8>, <16 x i8>* %Aptr
523   %B = load <16 x i8>, <16 x i8>* %Bptr
524   %A_even = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 1, i32 2, i32 5, i32 6, i32 9, i32 10, i32 13, i32 14> ;indices aren't all even
525   %A_odd = shufflevector <16 x i8> %A, <16 x i8> undef, <8 x i32> <i32 0, i32 3, i32 4, i32 7, i32 8, i32 11, i32 12, i32 15> ;indices aren't all odd
526   %B_even = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14> ;different than A
527   %B_odd = shufflevector <16 x i8> %B, <16 x i8> undef, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15> ;different than A
528   %A_even_ext = sext <8 x i8> %A_even to <8 x i32>
529   %B_even_ext = zext <8 x i8> %B_even to <8 x i32>
530   %A_odd_ext = sext <8 x i8> %A_odd to <8 x i32>
531   %B_odd_ext = zext <8 x i8> %B_odd to <8 x i32>
532   %even_mul = mul <8 x i32> %A_even_ext, %B_even_ext
533   %odd_mul = mul <8 x i32> %A_odd_ext, %B_odd_ext
534   %add = add <8 x i32> %even_mul, %odd_mul
535   %cmp_max = icmp sgt <8 x i32> %add, <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
536   %max = select <8 x i1> %cmp_max, <8 x i32> %add, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>
537   %cmp_min = icmp slt <8 x i32> %max, <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
538   %min = select <8 x i1> %cmp_min, <8 x i32> %max, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>
539   %trunc = trunc <8 x i32> %min to <8 x i16>
540   ret <8 x i16> %trunc