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 (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