For non-int load with 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):
        non-int load with integer constant.

gcc/testsuite/

        PR target/124407
        * gcc.target/i386/pr124407.c: New test.

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

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 0e4fdcd2853..92aa99cfb8a 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -3331,9 +3331,26 @@ 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 (GET_MODE (reg), 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)
diff --git a/gcc/testsuite/gcc.target/i386/pr124407.c 
b/gcc/testsuite/gcc.target/i386/pr124407.c
new file mode 100644
index 00000000000..7e87ab3ba57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr124407.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;
+}
-- 
2.53.0

Reply via email to