Middle end can generate SYMBOL_REF RTX as a value "val" in the call
to expand_vector_set, but SYMBOL_REF RTX is not accepted in
<sse2p4_1>_pinsr<ssemodesuffix> insn pattern, generated via
VEC_MERGE/VEC_DUPLICATE RTX path.
Force the value into a register before VEC_MERGE/VEC_DUPLICATE RTX
is generated if it doesn't satisfy nonimmediate_operand predicate.
PR target/117116
gcc/ChangeLog:
* config/i386/i386-expand.cc (expand_vector_set): Force "val"
into a register before VEC_MERGE/VEC_DUPLICATE RTX is generated
if it doesn't satisfy nonimmediate_operand predicate.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr117116.c: New test.
(cherry picked from commit
80d7032067a3a5b76aecd657d9b35b0a8f5a941d)
else if (use_vec_merge)
{
do_vec_merge:
+ if (!nonimmediate_operand (val, inner_mode))
+ val = force_reg (inner_mode, val);
tmp = gen_rtx_VEC_DUPLICATE (mode, val);
tmp = gen_rtx_VEC_MERGE (mode, tmp, target,
GEN_INT (HOST_WIDE_INT_1U << elt));
--- /dev/null
+/* PR target/117116 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx2" } */
+
+typedef void (*StmFct)();
+typedef struct {
+ StmFct fct_getc;
+ StmFct fct_putc;
+ StmFct fct_flush;
+ StmFct fct_close;
+} StmInf;
+
+StmInf TTY_Getc_pstm;
+
+void TTY_Getc() {
+ TTY_Getc_pstm.fct_getc = TTY_Getc;
+ TTY_Getc_pstm.fct_putc = TTY_Getc_pstm.fct_flush = TTY_Getc_pstm.fct_close = (StmFct)1;
+}