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).

Reply via email to