diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d0e95e29d2..2a4c2c44d30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-02-14 H.J. Lu + + PR target/79498 + * config/i386/i386.c (timode_scalar_chain::convert_insn): Insert + the extra instruction to the right place to store 128-bit constant + when needed. + 2017-02-14 Martin Sebor PR middle-end/79448 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d9a4a38b900..daa230315d0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3956,8 +3956,13 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) /* Since there are no instructions to store 128-bit constant, temporary register usage is required. */ rtx tmp = gen_reg_rtx (V1TImode); + start_sequence (); src = gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec (1, src)); src = validize_mem (force_const_mem (V1TImode, src)); + rtx_insn *seq = get_insns (); + end_sequence (); + if (seq) + emit_insn_before (seq, insn); emit_conversion_insns (gen_rtx_SET (dst, tmp), insn); dst = tmp; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6e42393e995..071f38fb565 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-02-14 H.J. Lu + + PR target/79498 + * gcc.target/i386/pr79498.c: New test. + 2017-02-14 Martin Sebor PR middle-end/79448 diff --git a/gcc/testsuite/gcc.target/i386/pr79498.c b/gcc/testsuite/gcc.target/i386/pr79498.c new file mode 100644 index 00000000000..8f623935fd5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr79498.c @@ -0,0 +1,20 @@ +/* PR target/79498 */ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -mno-avx512f -mcmodel=large -Wno-psabi" } */ + +typedef unsigned U __attribute__ ((vector_size (64))); +typedef unsigned __int128 V __attribute__ ((vector_size (64))); + +static inline V +bar (U u, U x, V v) +{ + v = (V)(U) { 0, ~0 }; + v[x[0]] <<= u[-63]; + return v; +} + +V +foo (U u) +{ + return bar (u, (U) {}, (V) {}); +}