https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67609
--- Comment #14 from Vladimir Makarov <vmakarov at gcc dot gnu.org> --- (In reply to Uroš Bizjak from comment #13) > The runtime version of the test still fails: > > > gcc -O2 -pr67609.c > > $ ./a.out > Aborted > > set_lower: > .LFB518: > movdqa reg(%rip), %xmm1 # 6 *movti_internal/4 > >> movapd %xmm0, %xmm1 # 7 *movdf_internal/14 > movaps %xmm1, reg(%rip) # 8 *movv2df_internal/3 > ret # 14 simple_return_internal > > Marked insn moves the whole register and clobbers the high word of the xmm1. Yes, right. The bug is not fixed yet. Although it is not RA problem anymore, I believe. Before final we have (insn:TI 7 6 8 2 (set (subreg:DF (reg/v:TI 22 xmm1 [orig:89 v ] [89]) 0) (reg/v:DF 21 xmm0 [orig:90 b ] [90])) b3.c:7 126 {*movdf_internal} (expr_list:REG_DEAD (reg/v:DF 21 xmm0 [orig:90 b ] [90]) (nil))) How can the final pass use movapd for this? RTL semantics say high part of xmm1 should be not changed. I only can guess. That final pass removes the subreg first as it was done in LRA earlier. I see two solutions. Prevent the final remove the subreg first and generate corresponding insn (most probably needs some additions to i386.md). Or prevent use movapd in *movdf_internal using movlpd instead (by the way it will also solve other bugs like 67124). The first solution is less safe as it may affect all targets. Although it could be implemented in a safe way: remove the subreg only if there is no insn definition with subreg. But I am not a specialist in writing md files to be sure (e.g. how to treat insn as *movdf_internal on all passes and only as insn with subreg on the final pass).