https://gcc.gnu.org/g:5be7b70e769e6e992dbf631cd37e24bd9da9e05e

commit r17-2161-g5be7b70e769e6e992dbf631cd37e24bd9da9e05e
Author: liuhongt <[email protected]>
Date:   Fri Jul 3 06:46:32 2026 -0700

    i386: Enable 512-bit byte dot-product only under AVX512BW [PR126098]
    
    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.
    
    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.

Diff:
---
 gcc/config/i386/sse.md                   | 12 ++++--------
 gcc/testsuite/gcc.target/i386/pr126098.c | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 7f652a13c87d..0f35b20006dc 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -631,10 +631,6 @@
 (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_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 "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 000000000000..afba6e60955b
--- /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;
+}

Reply via email to