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