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.