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

Reply via email to