https://gcc.gnu.org/g:7d84a357cfaa3d9ff2cc600a3c145780d37b6aed

commit r17-420-g7d84a357cfaa3d9ff2cc600a3c145780d37b6aed
Author: H.J. Lu <[email protected]>
Date:   Sat May 9 05:58:09 2026 +0800

    x86_cse: Check CONST0_RTX and CONSTM1_RTX
    
    For CONST_VECTOR source, check CONST0_RTX and CONSTM1_RTX with
    X86_CSE_CONSTM1_VECTOR when placing
    
    (insn 32 2 7 2 (set (reg:V2DI 114)
            (const_vector:V2DI [
                    (const_int 0 [0]) repeated x2
                ])) -1
         (nil))
    
    after
    
    (note 2 3 32 2 NOTE_INSN_FUNCTION_BEG)
    
    for X86_CSE_VEC_DUP, not X86_CSE_CONST0_VECTOR or X86_CSE_CONSTM1_VECTOR,
    after replacing redundant vector loads:
    
    (insn 31 15 16 2 (set (reg/v/f:DI 99 [ d ])
            (const_int 0 [0])) "x.c":5:16 -1
         (nil))
    ...
    (insn 18 17 19 2 (set (reg:V2DI 111 [ _22 ])
            (vec_duplicate:V2DI (reg/v/f:DI 99 [ d ]))) "x.c":5:16 9345 
{*vec_dupv2di}
         (nil))
    
    ...
    (insn 29 12 15 2 (set (reg/v/f:DI 98 [ c ])
            (const_int 0 [0])) "x.c":5:16 -1
         (nil))
    ...
    (insn 20 19 21 2 (set (reg:V2DI 112 [ _20 ])
            (vec_duplicate:V2DI (reg/v/f:DI 98 [ c ]))) "x.c":5:16 9345 
{*vec_dupv2di}
         (nil))
    
    with
    
    (insn 18 17 19 2 (set (reg:V2DI 111 [ _22 ])
            (reg:V2DI 114)) "x.c":5:16 2454 {movv2di_internal}
         (nil))
    
    and
    
    (insn 20 19 21 2 (set (reg:V2DI 112 [ _20 ])
            (reg:V2DI 114)) "x.c":5:16 2454 {movv2di_internal}
         (nil))
    
    Adjust gcc.target/i386/pr124407-1.c for the expected x86_cse dump:
    
    (insn 35 8 9 2 (set (reg:V16QI 125)
            (const_vector:V16QI [
                    (const_int 0 [0]) repeated x16
                ])) -1
         (nil))
    
    instead of
    
    (insn 36 8 35 2 (set (reg:SF 126)
            (const_double:SF 0.0 [0x0.0p+0])) -1
         (nil))
    (insn 35 36 9 2 (set (reg:V4SF 125)
            (vec_duplicate:V4SF (reg:SF 126))) -1
         (nil))
    
    gcc/
    
            PR target/125239
            * config/i386/i386-features.cc (ix86_place_single_vector_set):
            For CONST_VECTOR source, check CONST0_RTX with
            X86_CSE_CONST0_VECTOR and CONSTM1_RTX with X86_CSE_CONSTM1_VECTOR.
            (ix86_broadcast_inner): Set x86_cse kind to X86_CSE_CONST0_VECTOR
            for CONST0_RTX and X86_CSE_CONSTM1_VECTOR for CONSTM1_RTX.
    
    gcc/testsuite/
    
            PR target/125239
            * gcc.target/i386/pr124407-1.c: Adjusted.
            * gcc.target/i386/pr125239.c: New test.
    
    Signed-off-by: H.J. Lu <[email protected]>

Diff:
---
 gcc/config/i386/i386-features.cc           | 53 +++++++++++++++++++++++++++---
 gcc/testsuite/gcc.target/i386/pr124407-1.c |  3 +-
 gcc/testsuite/gcc.target/i386/pr125239.c   | 10 ++++++
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index a1411d2b1b1f..fe1baed3e9a2 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -3289,6 +3289,32 @@ ix86_place_single_vector_set (rtx dest, rtx src, bitmap 
bbs,
 
   if (CONST_INT_P (src))
     dest = gen_rtx_SUBREG (load->dest_mode, dest, 0);
+  else if (CONST_VECTOR_P (src))
+    {
+      /* The only possible CONST_VECTORs of SRC are CONST0_RTX and
+        CONSTM1_RTX.  Otherwise,
+
+        rtx set = gen_rtx_SET (dest, src);
+
+        won't be a valid instruction.  CONST0_RTX always works.  It
+        can comes from:
+
+        1. remove_partial_avx_dependency with LOAD == NULL.
+        2. X86_CSE_VEC_DUP with
+
+        (insn 48 58 16 3 (set (reg:V4HI 123)
+               (const_vector:V4HI [
+                       (const_int 0 [0]) repeated x4
+                 ])) 2065 {*movv4hi_internal} (nil))
+
+        3. X86_CSE_CONST0_VECTOR.
+       */
+      machine_mode mode = GET_MODE (dest);
+      if (!(src == CONST0_RTX (mode)
+           || (src == CONSTM1_RTX (mode)
+               && load->kind == X86_CSE_CONSTM1_VECTOR)))
+       gcc_unreachable ();
+    }
   rtx set = gen_rtx_SET (dest, src);
 
   rtx_insn *insn = BB_HEAD (bb);
@@ -3903,6 +3929,7 @@ ix86_broadcast_inner (rtx op, machine_mode mode,
       return nullptr;
     }
 
+  machine_mode orig_mode = mode;
   mode = GET_MODE (op);
 
   /* Only single def chain is supported.  */
@@ -3938,13 +3965,29 @@ ix86_broadcast_inner (rtx op, machine_mode mode,
         Set *INSN_P to nullptr and return SET_SRC if SET_SRC is an
         integer constant.  */
       op = src;
-      if (SCALAR_INT_MODE_P (mode))
+      if (SCALAR_INT_MODE_P (mode) && mode != GET_MODE (reg))
+       op = gen_int_mode (INTVAL (src), mode);
+      if (op == const0_rtx)
        {
-         if (mode != GET_MODE (reg))
-           op = gen_int_mode (INTVAL (src), mode);
+          if (standard_sse_constant_p (CONST0_RTX (orig_mode),
+                                       orig_mode) == 1)
+            {
+              *scalar_mode_p = QImode;
+              *kind_p = X86_CSE_CONST0_VECTOR;
+              *insn_p = nullptr;
+              return const0_rtx;
+            }
+          op = CONST0_RTX (mode);
+       }
+      else if (op == constm1_rtx
+              && standard_sse_constant_p (CONSTM1_RTX (orig_mode),
+                                          orig_mode) == 2)
+       {
+         *scalar_mode_p = QImode;
+         *kind_p = X86_CSE_CONSTM1_VECTOR;
+         *insn_p = nullptr;
+         return constm1_rtx;
        }
-      else if (op == const0_rtx)
-       op = CONST0_RTX (mode);
       *insn_p = nullptr;
     }
   else
diff --git a/gcc/testsuite/gcc.target/i386/pr124407-1.c 
b/gcc/testsuite/gcc.target/i386/pr124407-1.c
index 41ffe5e24d50..e8fb0dd7872c 100644
--- a/gcc/testsuite/gcc.target/i386/pr124407-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr124407-1.c
@@ -14,4 +14,5 @@ foo()
   v /= f;
 }
 
-/* { dg-final { scan-rtl-dump {\(const_double:SF 0.0 \[0x0.0p\+0\]\)} 
"x86_cse" { target { ! ia32 } } } } */
+/* { dg-final { scan-rtl-dump {\(set \(reg:V16QI 125\)} "x86_cse" { target { ! 
ia32 } } } } */
+/* { dg-final { scan-rtl-dump {\(const_int 0 \[0\]\) repeated x16} "x86_cse" { 
target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr125239.c 
b/gcc/testsuite/gcc.target/i386/pr125239.c
new file mode 100644
index 000000000000..7ebf45ed6610
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr125239.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64 -fno-tree-dse -fno-tree-dce" } */
+
+extern void a (void);
+void
+b (void)
+{
+  int *c, *d, *e[2][20] = {{c}, {c, d, d, d, c, c, d, c}};
+  a ();
+}

Reply via email to