Hello!

> 2013-10-25  Vladimir Makarov <vmaka...@redhat.com>
>
>      ...
>      * lra-spills.c (lra_final_code_change): Remove useless move insns.

This change regressed x86 AVX vzeroupper insertion pass and exposed
another instance of PR 58679 [1]. The testcase:

--cut here--
typedef long long __m128i __attribute__ ((__vector_size__ (16)));
typedef char __v16qi __attribute__ ((__vector_size__ (16)));

 __m128i _mm_cmpistrm (__m128i __X, __m128i __Y, const int __M)
{
  return (__m128i) __builtin_ia32_pcmpistrm128((__v16qi)__X, (__v16qi)__Y, 1);
}
--cut here--

-O2 -mavx:

tt.c: In function ‘_mm_cmpistrm’:
tt.c:8:1: internal compiler error: in create_pre_exit, at mode-switching.c:422
 }
 ^
0xe0ed41 create_pre_exit
        /home/uros/gcc-svn/trunk/gcc/mode-switching.c:408
0xe0ed41 optimize_mode_switching
        /home/uros/gcc-svn/trunk/gcc/mode-switching.c:496
0xe0ed41 rest_of_handle_mode_switching
        /home/uros/gcc-svn/trunk/gcc/mode-switching.c:782
0xe0ed41 execute
        /home/uros/gcc-svn/trunk/gcc/mode-switching.c:817
0xbcaf85 rest_of_handle_insert_vzeroupper
        /home/uros/gcc-svn/trunk/gcc/config/i386/i386.c:2370

The problem is in the wrong assumption of mode switching pass, which
in its exit bb expects a simple register copy insn that copies return
value to a return register. This is not the case anymore, since LRA
now removes the null copy by itself.

On a related note, gcc.c-torture/execute/pr30185.c from [1] does not
fail vzeroupper insertion pass anymore, due to unnecessary return
value copy insn:

foo:
        movq    %rsi, %rax
        cqto
        idivq   %rcx
        movq    %rax, %rsi          <--- here (*)
        xorl    %eax, %eax
        movq    %rsi, %rdx
        ret

"movq %rax, %rdx" should be emitted at (*).

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58679

Uros.

Reply via email to