aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2009-12-16 00:29:41 +0000
committerDale Johannesen <dalej@apple.com>2009-12-16 00:29:41 +0000
commitfc49bd244741fd7923768509759fbfb7198edbec (patch)
tree68d1de65d3aaa29b83ca49224b9ec0edc15a947d /test
parentbd13cb911cb40ac6a82db12deaef775a9d19ff4b (diff)
downloadexternal_llvm-fc49bd244741fd7923768509759fbfb7198edbec.zip
external_llvm-fc49bd244741fd7923768509759fbfb7198edbec.tar.gz
external_llvm-fc49bd244741fd7923768509759fbfb7198edbec.tar.bz2
Do better with physical reg operands (typically, from inline asm)
in local register allocator. If a reg-reg copy has a phys reg input and a virt reg output, and this is the last use of the phys reg, assign the phys reg to the virt reg. If a reg-reg copy has a phys reg output and we need to reload its spilled input, reload it directly into the phys reg than passing it through another reg. Following 76208, there is sometimes no dependency between the def of a phys reg and its use; this creates a window where that phys reg can be used for spilling (this is true in linear scan also). This is bad and needs to be fixed a better way, although 76208 works too well in practice to be reverted. However, there should normally be no spilling within inline asm blocks. The patch here goes a long way towards making this actually be true. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@91485 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll4
-rw-r--r--test/CodeGen/X86/phys-reg-local-regalloc.ll49
2 files changed, 51 insertions, 2 deletions
diff --git a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
index f2fdedf..c4ed166 100644
--- a/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
+++ b/test/CodeGen/PowerPC/2007-04-30-InlineAsmEarlyClobber.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s | grep {subfc r3,r5,r4}
; RUN: llc < %s | grep {subfze r4,r2}
-; RUN: llc < %s -regalloc=local | grep {subfc r5,r2,r4}
-; RUN: llc < %s -regalloc=local | grep {subfze r2,r3}
+; RUN: llc < %s -regalloc=local | grep {subfc r5,r4,r3}
+; RUN: llc < %s -regalloc=local | grep {subfze r2,r2}
; The first argument of subfc must not be the same as any other register.
; PR1357
diff --git a/test/CodeGen/X86/phys-reg-local-regalloc.ll b/test/CodeGen/X86/phys-reg-local-regalloc.ll
new file mode 100644
index 0000000..e5e2d4b
--- /dev/null
+++ b/test/CodeGen/X86/phys-reg-local-regalloc.ll
@@ -0,0 +1,49 @@
+; RUN: llc < %s -march=x86 -mtriple=i386-apple-darwin9 -regalloc=local | FileCheck %s
+
+@.str = private constant [12 x i8] c"x + y = %i\0A\00", align 1 ; <[12 x i8]*> [#uses=1]
+
+define i32 @main() nounwind {
+entry:
+; CHECK: movl 24(%esp), %eax
+; CHECK-NOT: movl
+; CHECK: movl %eax, 36(%esp)
+; CHECK-NOT: movl
+; CHECK: movl 28(%esp), %ebx
+; CHECK-NOT: movl
+; CHECK: movl %ebx, 40(%esp)
+; CHECK-NOT: movl
+; CHECK: addl %ebx, %eax
+ %retval = alloca i32 ; <i32*> [#uses=2]
+ %"%ebx" = alloca i32 ; <i32*> [#uses=1]
+ %"%eax" = alloca i32 ; <i32*> [#uses=2]
+ %result = alloca i32 ; <i32*> [#uses=2]
+ %y = alloca i32 ; <i32*> [#uses=2]
+ %x = alloca i32 ; <i32*> [#uses=2]
+ %0 = alloca i32 ; <i32*> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i32 1, i32* %x, align 4
+ store i32 2, i32* %y, align 4
+ call void asm sideeffect alignstack "# top of block", "~{dirflag},~{fpsr},~{flags},~{edi},~{esi},~{edx},~{ecx},~{eax}"() nounwind
+ %asmtmp = call i32 asm sideeffect alignstack "movl $1, $0", "=={eax},*m,~{dirflag},~{fpsr},~{flags},~{memory}"(i32* %x) nounwind ; <i32> [#uses=1]
+ store i32 %asmtmp, i32* %"%eax"
+ %asmtmp1 = call i32 asm sideeffect alignstack "movl $1, $0", "=={ebx},*m,~{dirflag},~{fpsr},~{flags},~{memory}"(i32* %y) nounwind ; <i32> [#uses=1]
+ store i32 %asmtmp1, i32* %"%ebx"
+ %1 = call i32 asm "", "={bx}"() nounwind ; <i32> [#uses=1]
+ %2 = call i32 asm "", "={ax}"() nounwind ; <i32> [#uses=1]
+ %asmtmp2 = call i32 asm sideeffect alignstack "addl $1, $0", "=={eax},{ebx},{eax},~{dirflag},~{fpsr},~{flags},~{memory}"(i32 %1, i32 %2) nounwind ; <i32> [#uses=1]
+ store i32 %asmtmp2, i32* %"%eax"
+ %3 = call i32 asm "", "={ax}"() nounwind ; <i32> [#uses=1]
+ call void asm sideeffect alignstack "movl $0, $1", "{eax},*m,~{dirflag},~{fpsr},~{flags},~{memory}"(i32 %3, i32* %result) nounwind
+ %4 = load i32* %result, align 4 ; <i32> [#uses=1]
+ %5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %4) nounwind ; <i32> [#uses=0]
+ store i32 0, i32* %0, align 4
+ %6 = load i32* %0, align 4 ; <i32> [#uses=1]
+ store i32 %6, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %entry
+ %retval3 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval3
+}
+
+declare i32 @printf(i8*, ...) nounwind