The byte sdot_prod/udot_prod expanders used the VI1_AVX512VNNIBW
iterator, which enabled V64QI under AVX512BW || AVX512VNNI. But VNNI
has no same-sign byte instruction (VPDPBUSD is mixed-sign, i.e. usdot),
so the same-sign byte case always emulates via vec_unpacks/vec_unpacku,
and for V64QI that widening is vpmov[sz]xbw, which needs AVX512BW. With
-mavx512vnni alone the optab was offered but couldn't be emulated:
(set (reg:V32HI) (sign_extend:V32HI (reg:V32QI)))
fails to match, ICEing in extract_insn during vregs.
Use the VI1_AVX512 iterator instead (V64QI under AVX512BW), matching the
sibling usdot_prod, and drop VI1_AVX512VNNIBW. The word sdot_prod uses a
separate iterator (VI2_AVX512VNNIBW) and is left unchanged: its V32HI VNNI
path is vpdpwssd on the 16-bit inputs directly, so no widening is needed.
Bootstrapped and regtested on x86_64-pc-gnu{-m32,}.
Ready push to trunk.
gcc/ChangeLog:
PR target/126098
* config/i386/sse.md (VI1_AVX512VNNIBW): Remove.
(sdot_prod<ssedvecmodelower><mode>): Use VI1_AVX512 instead of
VI1_AVX512VNNIBW so V64QI is enabled only under AVX512BW.
(udot_prod<ssedvecmodelower><mode>): Likewise.
gcc/testsuite/ChangeLog:
PR target/126098
* gcc.target/i386/pr126098.c: New test.
---
gcc/config/i386/sse.md | 12 ++++--------
gcc/testsuite/gcc.target/i386/pr126098.c | 16 ++++++++++++++++
2 files changed, 20 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/pr126098.c
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 7f652a13c87..0f35b20006d 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -631,10 +631,6 @@ (define_mode_iterator VI1_AVX512F
(define_mode_iterator VI1_AVX512VNNI
[(V64QI "TARGET_AVX512VNNI") (V32QI "TARGET_AVX2") V16QI])
-(define_mode_iterator VI1_AVX512VNNIBW
- [(V64QI "TARGET_AVX512BW || TARGET_AVX512VNNI")
- (V32QI "TARGET_AVX2") V16QI])
-
(define_mode_iterator VI12_256_512_AVX512VL
[V64QI (V32QI "TARGET_AVX512VL")
V32HI (V16HI "TARGET_AVX512VL")])
@@ -32542,8 +32538,8 @@ (define_int_attr vpdotprodtype
(define_expand "sdot_prod<ssedvecmodelower><mode>"
[(match_operand:<ssedvecmode> 0 "register_operand")
- (match_operand:VI1_AVX512VNNIBW 1 "register_operand")
- (match_operand:VI1_AVX512VNNIBW 2 "register_operand")
+ (match_operand:VI1_AVX512 1 "register_operand")
+ (match_operand:VI1_AVX512 2 "register_operand")
(match_operand:<ssedvecmode> 3 "register_operand")]
"TARGET_SSE2"
{
@@ -32590,8 +32586,8 @@ (define_expand "sdot_prod<ssedvecmodelower><mode>"
(define_expand "udot_prod<ssedvecmodelower><mode>"
[(match_operand:<ssedvecmode> 0 "register_operand")
- (match_operand:VI1_AVX512VNNIBW 1 "register_operand")
- (match_operand:VI1_AVX512VNNIBW 2 "register_operand")
+ (match_operand:VI1_AVX512 1 "register_operand")
+ (match_operand:VI1_AVX512 2 "register_operand")
(match_operand:<ssedvecmode> 3 "register_operand")]
"TARGET_SSE2"
{
diff --git a/gcc/testsuite/gcc.target/i386/pr126098.c
b/gcc/testsuite/gcc.target/i386/pr126098.c
new file mode 100644
index 00000000000..afba6e60955
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126098.c
@@ -0,0 +1,16 @@
+/* PR target/126098 */
+/* { dg-do compile } */
+/* { dg-options "-mavx512vnni -O3" } */
+
+/* AVX512VNNI does not imply AVX512BW, so the byte (V64QI) dot-product must
+ not be advertised as available: emulating it needs vpmovsxbw on 512-bit
+ vectors, which requires AVX512BW. Advertising it led to an unrecognizable
+ (sign_extend:V32HI (reg:V32QI)) insn and an ICE in extract_insn. */
+
+char *fn_c, *fn_d;
+int fn() {
+ int res = 0;
+ for (int i = 0; i < 64; ++i)
+ res += fn_c[i] * fn_d[i];
+ return res;
+}
--
2.34.1