diff options
author | Philip Reames <listmail@philipreames.com> | 2015-04-10 22:58:39 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2015-04-10 22:58:39 +0000 |
commit | 8106a264d37d2f04423a69250be5cbda0e21ec9c (patch) | |
tree | 9155d2a7afac568dd3e05eae1d2810f3f93c2c56 /llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll | |
parent | df1ef08c0c6448dc51242d0ffc9fc0909d1306a4 (diff) | |
download | bcm5719-llvm-8106a264d37d2f04423a69250be5cbda0e21ec9c.tar.gz bcm5719-llvm-8106a264d37d2f04423a69250be5cbda0e21ec9c.zip |
[RewriteStatepointsForGC] test case missing from 234657
llvm-svn: 234658
Diffstat (limited to 'llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll')
-rw-r--r-- | llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll b/llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll new file mode 100644 index 00000000000..5817c276b7f --- /dev/null +++ b/llvm/test/Transforms/RewriteStatepointsForGC/liveness-basics.ll @@ -0,0 +1,158 @@ +; A collection of liveness test cases to ensure we're reporting the +; correct live values at statepoints +; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s + + +; Tests to make sure we consider %obj live in both the taken and untaken +; predeccessor of merge. +define i64 addrspace(1)* @test1(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" { +; CHECK-LABEL: @test1 +entry: + br i1 %cmp, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)* +; CHECK-NEXT: br label %merge + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br label %merge + +untaken: +; CHECK-LABEL: untaken: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %obj.relocated1 = call coldcc i64 addrspace(1)* +; CHECK-NEXT: br label %merge + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: %.0 = phi i64 addrspace(1)* [ %obj.relocated, %taken ], [ %obj.relocated1, %untaken ] +; CHECK-NEXT: ret i64 addrspace(1)* %.0 + ret i64 addrspace(1)* %obj +} + +; A local kill should not effect liveness in predecessor block +define i64 addrspace(1)* @test2(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" { +; CHECK-LABEL: @test2 +entry: +; CHECK-LABEL: entry: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: br + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br i1 %cmp, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: %obj = load +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: gc.relocate +; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated + + %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %obj + +untaken: + ret i64 addrspace(1)* null +} + +; A local kill should effect values live from a successor phi. Also, we +; should only propagate liveness from a phi to the appropriate predecessors. +define i64 addrspace(1)* @test3(i1 %cmp, i64 addrspace(1)** %loc) gc "statepoint-example" { +; CHECK-LABEL: @test3 +entry: + br i1 %cmp, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %obj = load +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)* +; CHECK-NEXT: br label %merge + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + %obj = load i64 addrspace(1)*, i64 addrspace(1)** %loc + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br label %merge + +untaken: +; CHECK-LABEL: taken: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: br label %merge + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br label %merge + +merge: + %phi = phi i64 addrspace(1)* [ %obj, %taken ], [ null, %untaken ] + ret i64 addrspace(1)* %phi +} + +; A base pointer must be live if it is needed at a later statepoint, +; even if the base pointer is otherwise unused. +define i64 addrspace(1)* @test4(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" { +; CHECK-LABEL: @test4 +entry: +; CHECK-LABEL: entry: +; CHECK-NEXT: %derived = getelementptr +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %derived.relocated = +; CHECK-NEXT: %obj.relocated = +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %derived.relocated1 = +; Note: It's legal to relocate obj again, but not strictly needed +; CHECK-NEXT: %obj.relocated2 = +; CHECK-NEXT: ret i64 addrspace(1)* %derived.relocated1 +; + %derived = getelementptr i64, i64 addrspace(1)* %obj, i64 8 + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %derived +} + +declare void @consume(...) readonly + +; Make sure that a phi def visited during iteration is considered a kill. +; Also, liveness after base pointer analysis can change based on new uses, +; not just new defs. +define i64 addrspace(1)* @test5(i1 %cmp, i64 addrspace(1)* %obj) gc "statepoint-example" { +; CHECK-LABEL: @test5 +entry: + br i1 %cmp, label %taken, label %untaken + +taken: +; CHECK-LABEL: taken: +; CHECK-NEXT: gc.statepoint +; CHECK-NEXT: %obj.relocated = call coldcc i64 addrspace(1)* +; CHECK-NEXT: br label %merge + call i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @foo, i32 0, i32 0, i32 0) + br label %merge + +untaken: +; CHECK-LABEL: untaken: +; CHECK-NEXT: br label %merge + br label %merge + +merge: +; CHECK-LABEL: merge: +; CHECK-NEXT: %.0 = phi i64 addrspace(1)* +; CHECK-NEXT: %obj2a = phi +; CHECK-NEXT: @consume +; CHECK-NEXT: br label %final + %obj2a = phi i64 addrspace(1)* [ %obj, %taken ], [null, %untaken] + call void (...)* @consume(i64 addrspace(1)* %obj2a) + br label %final +final: +; CHECK-LABEL: final: +; CHECK-NEXT: @consume +; CHECK-NEXT: ret i64 addrspace(1)* %.0 + call void (...)* @consume(i64 addrspace(1)* %obj2a) + ret i64 addrspace(1)* %obj +} + +declare void @foo() + +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...) + |