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