On Mon, Mar 9, 2026 at 9:17 PM 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           | 29 +++++++++++++++++++---
>  gcc/testsuite/gcc.target/i386/pr124407-1.c | 15 +++++++++++
>  gcc/testsuite/gcc.target/i386/pr124407-2.c | 12 +++++++++
>  3 files changed, 53 insertions(+), 3 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..155b90b50a5 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)
> @@ -3774,11 +3790,18 @@ ix86_broadcast_inner (rtx op, machine_mode mode,
>          (set (reg:V4SI 98)
>                (vec_duplicate:V4SI (reg:SI 99)))
>
> +        and
> +
> +        (set (subreg:SI (reg/v:SF 105 [ f ]) 0)
> +             (const_int 0 [0]))
> +
>          Set *INSN_P to nullptr and return SET_SRC if SET_SRC is an
>          integer constant.  */
>        op = src;

if op is like (subreg:SF (reg:SI 100) 0), it will still generate op =
gen_int_mode (INTVAL (src), SFmode);?
So we need to

if (op == const0_rtx && !SCALAR_INT_MODE_P (mode))
  op = CONST0_RTX (mode);
else if (mode != GET_MODE (reg) && SCALAR_INT_MODE_P (mode))
  op = gen_int_mode (INTVAL (src), mode);
*insn_p = nullptr;

And then all other !SCALAR_INT_MODE_P (mode) cases will be handled in
your new added code.

>        if (mode != GET_MODE (reg))
>         op = gen_int_mode (INTVAL (src), mode);
> +      else if (op == const0_rtx && !SCALAR_INT_MODE_P (mode))
> +       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..7e87ab3ba57
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr124407-1.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Ofast -msse2" } */
> +
> +typedef __attribute__((__vector_size__(8))) float V;
> +V v;
> +
> +void
> +foo()
> +{
> +  int i;
> +  float f;
> +  __builtin_memcpy(&f, &i, 1);
> +  v -= f;
> +  v /= f;
> +}
> 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
>


-- 
BR,
Hongtao

Reply via email to