This is reproduceable with gcc 4.0.0 and gcc SVN, but not with gcc 3.4.6.

I still don't really know what's the problem, but I think it may be that not
enough registers are available for output, and gcc is using the same register
for 2 different outputs.

gccs were built with:
--prefix=/usr --enable-languages=c --program-suffix=-{svn,4.0.0}

file was compiled with:
gcc-{svn,4.0.0} -v -save-temps -O3 -c regs.c

The corresponding inline asm that triggers the error is the following, when
used many times in a function inside many ifs:
asm volatile (
    "cmpl %0, %3\n\t"
    "cmovl %3, %0\n\t"
    "cmovl %4, %1\n\t"
    "cmovl %5, %2\n\t"
    : "+r" (dmin), "+r" (dx), "+r" (dy)
    : "r" (d), "r" (val1), "r" (val2)
    );

The problem can be seen at the end of the assembly file:
# 47 "regs.c" 1
    cmpl %edx, %esi
    cmovl %esi, %edx
    cmovl %edi, %eax
    cmovl %ecx, %eax

# 0 "" 2
#NO_APP
    movl    %eax, %ebx
    movl    %eax, %edi
    movl    %eax, -36(%ebp)
    movl    %eax, -24(%ebp)
    movl    %edx, dmin

eax is used twice, both for dx and dy.

Test code minimized from motion_est.c from FFmpeg. Could be minimized further.


-- 
           Summary: wrong registers used in cmov instruction
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: inline-asm
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ramiro at lisha dot ufsc dot br
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31386

Reply via email to