[LLVMbugs] [Bug 7382] New: Fast register allocator broken spill/reload surrounding inline asm

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Jun 15 05:43:33 PDT 2010


           Summary: Fast register allocator broken spill/reload
                    surrounding inline asm
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Common Code Generator Code
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: spectral at google.com
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=5037)
 --> (http://llvm.org/bugs/attachment.cgi?id=5037)
Demonstrates apparently incorrect register spill/reload surrounding inline asm.

Using attached file "broken.ll", running:
llc -debug -regalloc=fast broken.ll

produces a .s file that is clearly wrong.  It stores ecx to 8(%rsp), executes
the inline assembly with ecx as the output register, reloads 8(%rsp) in to eax,
and never again uses what the inline assembly produced in ecx.

Relevant bits of broken.ll:
  %zero = load i32* %retval 
  %0 = call i32 asm "bsr   $1, $0\0A\09cmovz $2, $0",
"=&r,ro,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i32 %zero, i32 -1) nounwind,
!srcloc !0 ; <i32> [#uses=1]
  store i32 %0, i32* %v
  %tmp = load i32* %v                             ; <i32> [#uses=1]         
  %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]*
@.str, i32 0, i32 0), i32 %tmp) ; <i32> [#uses=0]

Produces this x86 assembly:
        movl    $0, 12(%rsp)
        movl    $-1, %eax
        movl    %ecx, 8(%rsp)           # 4-byte Spill
        bsr   12(%rsp), %ecx
        cmovz %eax, %ecx
        movl    8(%rsp), %eax           # 4-byte Reload
        movl    %eax, 16(%rsp)
        movl    $.L.str, %edi
        xorb    %al, %al
        movl    8(%rsp), %esi           # 4-byte Reload
        callq   printf

With this in the output from llc -debug:
>> INLINEASM <es:bsr   $1, $0
    cmovz $2, $0>, 14, %reg1024<earlyclobber,def>, 44, <fi#2>, 1, %reg0, 0,
%reg0, 9, %reg1025, 14, %EFLAGS<earlyclobber,imp-def>, <!-1>
Regs: EAX=%reg1025*
Allocating %reg1024 from GR32
Assigning %reg1024 to ECX
Killing last use: %reg1025
Spilling %reg1024 in ECX to stack slot #3
<< INLINEASM <es:bsr   $1, $0
    cmovz $2, $0>, 14, %ECX<earlyclobber,def>, 44, <fi#2>, 1, %reg0, 0, %reg0,
9, %EAX<kill>, 14, %EFLAGS<earlyclobber,imp-def>, <!-1>

>> MOV32mr <fi#1>, 1, %reg0, 0, %reg0, %reg1024; mem:ST4[%v]
Assigning %reg1024 to EAX
Reloading %reg1024 into EAX
<< MOV32mr <fi#1>, 1, %reg0, 0, %reg0, %EAX; mem:ST4[%v]

My assumption: The spill before the inline asm shouldn't be happening at all,
nor should the reloads afterward.  I've looked in to fixing this but am way
beyond my comfort zone, and couldn't produce anything that fixed this bug and
didn't look like it'd break everything else.

Note that broken.ll started life as a .cc file built by clang that I shrunk a
bunch, and then I went and hacked up the .ll file some more to get it smaller,
so it's possible that clang originally did this codegen incorrectly.  However,
it doesn't reproduce the problem with the optimized-mode register allocator
("local", I believe?), so I believe the .ll file is still valid and correct.

This has been reproduced on two machines by two different users, both x86_64
running Linux, but different versions (one based on ubuntu hardy, one based on
ubuntu lucid).  I reproduced this both with a binary Chandler built from a pull
a few days ago and an SVN pull I did 1-2 hours ago (r105993).

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list