Since SImode MOV only supports signed 32-bit immediate, change unsigned
32-bit immediate to signed if needed.

gcc/

        PR target/121497
        * config/i386/i386-features.cc (ix86_place_single_vector_set):
        Change unsigned 32-bit immediate to signed if needed.

gcc/testsuite/

        PR target/121497
        * gcc.target/i386/pr121497.c: New test.

Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
---
 gcc/config/i386/i386-features.cc         | 15 +++++++++++++--
 gcc/testsuite/gcc.target/i386/pr121497.c | 18 ++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr121497.c

diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 9941e61361c..16d1593de77 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -3193,8 +3193,19 @@ 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))
+      if (CONST_INT_P (inner_scalar))
+       {
+         if (TARGET_64BIT && GET_MODE (reg) == SImode)
+           {
+             /* Since SImode MOV only supports signed 32-bit immediate,
+                change unsigned 32-bit immediate to signed if needed. */
+             HOST_WIDE_INT val = INTVAL (inner_scalar);
+             if (val > 0 && val_signbit_known_set_p (SImode, val))
+               inner_scalar = GEN_INT (val | ~GET_MODE_MASK (SImode));
+           }
+       }
+      else 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);
       rtx set = gen_rtx_SET (reg, inner_scalar);
       insn = emit_insn_before (set, set_insn);
diff --git a/gcc/testsuite/gcc.target/i386/pr121497.c 
b/gcc/testsuite/gcc.target/i386/pr121497.c
new file mode 100644
index 00000000000..ce55f9558f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr121497.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -msse2 -w" } */
+
+extern void a(int *);
+int q;
+void b(int c, int d, int e, int f, int g, int h) {
+  int t[] = {c, d, e, f, g, h};
+  a(t);
+}
+int main() {
+  int k[2], i = 0, *p();
+  if (q) {
+    for (; (int)p + i < 2; i++)
+      k[i] = -1294967296;
+    b(k[0] + 7, k[0] + 9, k[0] + 6, k[0] + 9, k[0] + 9, k[0] + 6);
+  }
+  return 0;
+}
-- 
2.50.1

Reply via email to