https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117116
--- Comment #14 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Hongtao Liu from comment #13)
> > I tried to split V2SImode CONST_VECTOR to two SImode CONST elements, but
> > there were some further ICEs generated, and it is getting a bit late
> > here...?
>
> The codegen looks much better, please go ahead with the patch.
Hm, the problem is when -fpic is active. Some "constants" are not legitimate
and cannot be forced into the constant pool (see ix86_cannot_force_const_mem).
Unfortunately, we only have symbol_ref here in ix86_expand_vector_set, so we
are not able to choose if we can push it to constant pool or not.
Play it safe and simply do:
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 2b774ff7c4e..63f5e348d64 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -18263,6 +18263,8 @@ quarter:
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));
For the original testcase, this results (-O2 -mavx2 -fpic) in:
TTY_Getc:
vmovdqa .LC0(%rip), %ymm0
movq TTY_Getc_pstm@GOTPCREL(%rip), %rax
vpinsrq $0, TTY_Getc@GOTPCREL(%rip), %xmm0, %xmm1
vinserti128 $0x0, %xmm1, %ymm0, %ymm0
vmovdqu %ymm0, (%rax)
vzeroupper
ret
.LC0:
.quad 0
.quad 1
.quad 1
.quad 1
and w/o -fpic:
TTY_Getc:
vmovdqa .LC0(%rip), %ymm0
movl $TTY_Getc, %eax
vpinsrq $0, %rax, %xmm0, %xmm1
vinserti128 $0x0, %xmm1, %ymm0, %ymm0
vmovdqa %ymm0, TTY_Getc_pstm(%rip)
vzeroupper
ret
.LC0:
.quad 0
.quad 1
.quad 1
.quad 1