[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
http://llvm.org/bugs/show_bug.cgi?id=7382
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.
Summary:
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.
Details:
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
#APP
bsr 12(%rsp), %ecx
cmovz %eax, %ecx
#NO_APP
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]
Regs: EAX ECX* EFLAGS
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