https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71626
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- One possibility would be to allow SUBREG of constant for the V1XXmode vectors like: --- gcc/varasm.c.jj 2016-06-10 20:24:03.000000000 +0200 +++ gcc/varasm.c 2016-06-27 11:43:25.330955071 +0200 @@ -3834,6 +3834,17 @@ output_constant_pool_2 (machine_mode mod machine_mode submode = GET_MODE_INNER (mode); unsigned int subalign = MIN (align, GET_MODE_BITSIZE (submode)); + /* For V1??mode, allow SUBREGs. */ + if (GET_CODE (x) == SUBREG + && GET_MODE_NUNITS (mode) == 1 + && GET_MODE_BITSIZE (submode) == GET_MODE_BITSIZE (mode) + && SUBREG_BYTE (x) == 0 + && GET_MODE (SUBREG_REG (x)) == submode) + { + output_constant_pool_2 (submode, SUBREG_REG (x), align); + break; + } + gcc_assert (GET_CODE (x) == CONST_VECTOR); units = CONST_VECTOR_NUNITS (x); Without -fpic the result looks good, but with -fpic it forces something that needs relocations into .rodata.cst.* constants, which I think is bad. Though, can't find right now where we normally avoid pushing relocatable stuff through force_const_mem... Another option is to do something in the i386 vector move expansion.