When converting TI store with CONST_INT to V1TI store with CONST_VECTOR in large model, an extra instruction may be needed to load CONST_VECTOR into a register. Insert the extra instruction to the right place.
Tested on x86-64. I am checking in this pre-approved patch. Thanks. H.J. --- gcc/ 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. gcc/testsuite/ PR target/79498 * gcc.target/i386/pr79498.c: New test. --- gcc/config/i386/i386.c | 5 +++++ gcc/testsuite/gcc.target/i386/pr79498.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr79498.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d7dce4b..02287fd 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/gcc.target/i386/pr79498.c b/gcc/testsuite/gcc.target/i386/pr79498.c new file mode 100644 index 0000000..8f62393 --- /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) {}); +} -- 2.9.3