On Tue, Mar 10, 2026 at 5:51 PM Hongtao Liu <[email protected]> wrote:
>
> On Wed, Mar 11, 2026 at 3:48 AM H.J. Lu <[email protected]> wrote:
> >
> > 1. For non-int load with zero integer constant, generate:
> >
> > (set (reg/v:SF 126 [ f ])
> >      (const_double:SF 0.0 [0x0.0p+0]))
> >
> > instead of
> >
> > (set (reg/v:SF 126 [ f ])
> >      (const_int 0 [0]))
> >
> > 2. For non-int load with non-zero integer constant, generate:
> >
> > (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
> >      (const_int 1313486336 [0x4e4a3600]))
> >
> > instead of
> >
> > (set (reg/v:SF 105 [ f ])
> >      (const_int 1313486336 [0x4e4a3600]))
> >
> > gcc/
> >
> >         PR target/124407
> >         * config/i386/i386-features.cc (ix86_place_single_vector_set):
> >         Handle non-int load with integer constant.
> >         (ix86_broadcast_inner): Convert const0_rtx to non-int mode.
> >
> > gcc/testsuite/
> >
> >         PR target/124407
> >         * gcc.target/i386/pr124407-1.c: New test.
> >         * gcc.target/i386/pr124407-2.c: Likewise.
> >
> > Signed-off-by: H.J. Lu <[email protected]>
> > ---
> >  gcc/config/i386/i386-features.cc           | 33 +++++++++++++++++++---
> >  gcc/testsuite/gcc.target/i386/pr124407-1.c | 17 +++++++++++
> >  gcc/testsuite/gcc.target/i386/pr124407-2.c | 12 ++++++++
> >  3 files changed, 58 insertions(+), 4 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr124407-1.c
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr124407-2.c
> >
> > diff --git a/gcc/config/i386/i386-features.cc 
> > b/gcc/config/i386/i386-features.cc
> > index 0e4fdcd2853..49fc32d9240 100644
> > --- a/gcc/config/i386/i386-features.cc
> > +++ b/gcc/config/i386/i386-features.cc
> > @@ -3331,9 +3331,25 @@ ix86_place_single_vector_set (rtx dest, rtx src, 
> > bitmap bbs,
> >        rtx inner_scalar = load->val;
> >        /* Set the source in (vec_duplicate:V4SI (reg:SI 99)).  */
> >        rtx reg = XEXP (src, 0);
> > -      if ((REG_P (inner_scalar) || MEM_P (inner_scalar))
> > -         && GET_MODE (reg) != GET_MODE (inner_scalar))
> > -       inner_scalar = gen_rtx_SUBREG (GET_MODE (reg), inner_scalar, 0);
> > +      machine_mode reg_mode = GET_MODE (reg);
> > +      if (reg_mode != GET_MODE (inner_scalar))
> > +       {
> > +         if (REG_P (inner_scalar) || MEM_P (inner_scalar))
> > +           inner_scalar = gen_rtx_SUBREG (reg_mode, inner_scalar, 0);
> > +         else if (!SCALAR_INT_MODE_P (reg_mode))
> > +           {
> > +             /* For non-int load with integer constant, generate
> > +
> > +                (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
> > +                     (const_int 1313486336 [0x4e4a3600]))
> > +
> > +              */
> > +             gcc_assert (CONST_INT_P (inner_scalar));
> > +             unsigned int bits = GET_MODE_BITSIZE (reg_mode);
> > +             machine_mode mode = int_mode_for_size (bits, 0).require ();
> > +             reg = gen_rtx_SUBREG (mode, reg, 0);
> > +           }
> > +       }
> >        rtx set = gen_rtx_SET (reg, inner_scalar);
> >        insn = emit_insn_before (set, set_insn);
> >        if (dump_file)
> > @@ -3769,6 +3785,13 @@ ix86_broadcast_inner (rtx op, machine_mode mode,
> >      {
> >        /* Handle sequences like
> >
> > +        (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
> > +             (const_int 0 [0]))
> > +        (set (reg:V4SF 110)
> > +             (vec_duplicate:V4SF (reg/v:SF 105 [ f ])))
> > +
> > +        and
> > +
> >          (set (reg:SI 99)
> >                (const_int 34 [0x22]))
> >          (set (reg:V4SI 98)
> > @@ -3777,7 +3800,9 @@ 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 (mode != GET_MODE (reg))
> > +      if (op == const0_rtx && !SCALAR_INT_MODE_P (mode))
> > +       op = CONST0_RTX (mode);
> > +      else if (mode != GET_MODE (reg))
> should be
>
>    else if (mode != GET_MODE (reg) && SCALAR_INT_MODE_P (mode))?

How about

      if (SCALAR_INT_MODE_P (mode))
        {
          if (mode != GET_MODE (reg))
            op = gen_int_mode (INTVAL (src), mode);
        }
      else if (op == const0_rtx)
        op = CONST0_RTX (mode);

in the enclosed v5 patch?

>
> Others LGTM.
> >         op = gen_int_mode (INTVAL (src), mode);
> >        *insn_p = nullptr;
> >      }
>



-- 
H.J.
From 3cad238b5b55b125a85b2c6761bc3a2de0c7700c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <[email protected]>
Date: Mon, 9 Mar 2026 06:16:24 -0700
Subject: [PATCH v5] x86: Handle non-int load with integer constant

1. For non-int load with zero integer constant, generate:

(set (reg/v:SF 126 [ f ])
     (const_double:SF 0.0 [0x0.0p+0]))

instead of

(set (reg/v:SF 126 [ f ])
     (const_int 0 [0]))

2. For non-int load with non-zero integer constant, generate:

(set (subreg:SI (reg/v:SF 105 [ f ]) 0)
     (const_int 1313486336 [0x4e4a3600]))

instead of

(set (reg/v:SF 105 [ f ])
     (const_int 1313486336 [0x4e4a3600]))

gcc/

	PR target/124407
	* config/i386/i386-features.cc (ix86_place_single_vector_set):
	Handle non-int load with integer constant.
	(ix86_broadcast_inner): Convert const0_rtx to non-int mode.

gcc/testsuite/

	PR target/124407
	* gcc.target/i386/pr124407-1.c: New test.
	* gcc.target/i386/pr124407-2.c: Likewise.

Signed-off-by: H.J. Lu <[email protected]>
---
 gcc/config/i386/i386-features.cc           | 38 +++++++++++++++++++---
 gcc/testsuite/gcc.target/i386/pr124407-1.c | 17 ++++++++++
 gcc/testsuite/gcc.target/i386/pr124407-2.c | 12 +++++++
 3 files changed, 62 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr124407-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr124407-2.c

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 0e4fdcd2853..f95f30f84cd 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -3331,9 +3331,25 @@ ix86_place_single_vector_set (rtx dest, rtx src, bitmap bbs,
       rtx inner_scalar = load->val;
       /* Set the source in (vec_duplicate:V4SI (reg:SI 99)).  */
       rtx reg = XEXP (src, 0);
-      if ((REG_P (inner_scalar) || MEM_P (inner_scalar))
-	  && GET_MODE (reg) != GET_MODE (inner_scalar))
-	inner_scalar = gen_rtx_SUBREG (GET_MODE (reg), inner_scalar, 0);
+      machine_mode reg_mode = GET_MODE (reg);
+      if (reg_mode != GET_MODE (inner_scalar))
+	{
+	  if (REG_P (inner_scalar) || MEM_P (inner_scalar))
+	    inner_scalar = gen_rtx_SUBREG (reg_mode, inner_scalar, 0);
+	  else if (!SCALAR_INT_MODE_P (reg_mode))
+	    {
+	      /* For non-int load with integer constant, generate
+
+		 (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
+		      (const_int 1313486336 [0x4e4a3600]))
+
+	       */
+	      gcc_assert (CONST_INT_P (inner_scalar));
+	      unsigned int bits = GET_MODE_BITSIZE (reg_mode);
+	      machine_mode mode = int_mode_for_size (bits, 0).require ();
+	      reg = gen_rtx_SUBREG (mode, reg, 0);
+	    }
+	}
       rtx set = gen_rtx_SET (reg, inner_scalar);
       insn = emit_insn_before (set, set_insn);
       if (dump_file)
@@ -3769,6 +3785,13 @@ ix86_broadcast_inner (rtx op, machine_mode mode,
     {
       /* Handle sequences like
 
+	 (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
+	      (const_int 0 [0]))
+	 (set (reg:V4SF 110)
+	      (vec_duplicate:V4SF (reg/v:SF 105 [ f ])))
+
+	 and
+
 	 (set (reg:SI 99)
 	       (const_int 34 [0x22]))
 	 (set (reg:V4SI 98)
@@ -3777,8 +3800,13 @@ 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 (mode != GET_MODE (reg))
-	op = gen_int_mode (INTVAL (src), mode);
+      if (SCALAR_INT_MODE_P (mode))
+	{
+	  if (mode != GET_MODE (reg))
+	    op = gen_int_mode (INTVAL (src), mode);
+	}
+      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
new file mode 100644
index 00000000000..41ffe5e24d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr124407-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -msse2 -fdump-rtl-x86_cse" } */
+
+typedef __attribute__((__vector_size__(8))) float V;
+V v;
+
+void
+foo()
+{
+  int i;
+  float f;
+  __builtin_memcpy(&f, &i, 1);
+  v -= f;
+  v /= f;
+}
+
+/* { dg-final { scan-rtl-dump {\(const_double:SF 0.0 \[0x0.0p\+0\]\)} "x86_cse" { target { ! ia32 } } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr124407-2.c b/gcc/testsuite/gcc.target/i386/pr124407-2.c
new file mode 100644
index 00000000000..eadfce726b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr124407-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -msse2" } */
+
+__attribute__((__vector_size__(2 * sizeof(float)))) float v64f32_0;
+
+void
+foo0 (float f32_0)
+{
+  double v128f64_0;
+  v64f32_0 -= *(float *)__builtin_memcpy(&f32_0, &v128f64_0, 1);
+  foo0 (848135872);
+}
-- 
2.53.0

Reply via email to