diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-08-12 21:00:20 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-08-12 21:00:20 +0000 |
| commit | 9ac4e38a16bd3f7695ec474deeb91c2eec858480 (patch) | |
| tree | 520c54b8f57c47a9fb447b134723335ec57ec87f /llvm/test/Transforms/RewriteStatepointsForGC | |
| parent | 2211cfe0a339b7d2eb6424e18e4d1b0b4932affd (diff) | |
| download | bcm5719-llvm-9ac4e38a16bd3f7695ec474deeb91c2eec858480.tar.gz bcm5719-llvm-9ac4e38a16bd3f7695ec474deeb91c2eec858480.zip | |
[RewriteStatepointsForGC] Handle extractelement fully in the base pointer algorithm
When rewriting the IR such that base pointers are available for every live pointer, we potentially need to duplicate instructions to propagate the base. The original code had only handled PHI and Select under the belief those were the only instructions which would need duplicated. When I added support for vector instructions, I'd added a collection of hacks for ExtractElement which caught most of the common cases. Of course, I then found the one test case my hacks couldn't cover. :)
This change removes all of the early hacks for extract element. By defining extractelement as a BDV (rather than trying to look through it), we can extend the rewriting algorithm to duplicate the extract as needed. Note that a couple of peephole optimizations were left in for the moment, because while we now handle extractelement as a first class citizen, we're not yet handling insertelement. That change will follow in the near future.
llvm-svn: 244808
Diffstat (limited to 'llvm/test/Transforms/RewriteStatepointsForGC')
| -rw-r--r-- | llvm/test/Transforms/RewriteStatepointsForGC/base-vector.ll | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/llvm/test/Transforms/RewriteStatepointsForGC/base-vector.ll b/llvm/test/Transforms/RewriteStatepointsForGC/base-vector.ll new file mode 100644 index 00000000000..2cba038a770 --- /dev/null +++ b/llvm/test/Transforms/RewriteStatepointsForGC/base-vector.ll @@ -0,0 +1,88 @@ +; RUN: opt %s -rewrite-statepoints-for-gc -S | FileCheck %s + +define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" { +; CHECK-LABEL: @test +; CHECK: extractelement +; CHECK: extractelement +; CHECK: statepoint +; CHECK: gc.relocate +; CHECK-DAG: ; (%base_ee, %base_ee) +; CHECK: gc.relocate +; CHECK-DAG: ; (%base_ee, %obj) +; Note that the second extractelement is actually redundant here. A correct output would +; be to reuse the existing obj as a base since it is actually a base pointer. +entry: + %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx + %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + + ret i64 addrspace(1)* %obj +} + +define i64 addrspace(1)* @test2(<2 x i64 addrspace(1)*>* %ptr, i1 %cnd, i32 %idx1, i32 %idx2) + gc "statepoint-example" { +; CHECK-LABEL: test2 +entry: + br i1 %cnd, label %taken, label %untaken +taken: + %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr + br label %merge +untaken: + %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr + br label %merge +merge: + %vec = phi <2 x i64 addrspace(1)*> [%obja, %taken], [%objb, %untaken] + br i1 %cnd, label %taken2, label %untaken2 +taken2: + %obj0 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx1 + br label %merge2 +untaken2: + %obj1 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx2 + br label %merge2 +merge2: +; CHECK-LABEL: merge2: +; CHECK: %obj.base = phi i64 addrspace(1)* +; CHECK: %obj = phi i64 addrspace(1)* +; CHECK: statepoint +; CHECK: gc.relocate +; CHECK-DAG: ; (%obj.base, %obj) +; CHECK: gc.relocate +; CHECK-DAG: ; (%obj.base, %obj.base) + %obj = phi i64 addrspace(1)* [%obj0, %taken2], [%obj1, %untaken2] + %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %obj +} + +define i64 addrspace(1)* @test3(i64 addrspace(1)* %ptr) + gc "statepoint-example" { +; CHECK-LABEL: test3 +entry: + %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %ptr, i32 0 + %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 +; CHECK: insertelement +; CHECK: extractelement +; CHECK: statepoint +; CHECK: gc.relocate +; CHECK-DAG: ; (%ptr, %obj) + %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %obj +} +define i64 addrspace(1)* @test4(i64 addrspace(1)* %ptr) + gc "statepoint-example" { +; CHECK-LABEL: test4 +entry: + %derived = getelementptr i64, i64 addrspace(1)* %ptr, i64 16 + %veca = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %derived, i32 0 + %vec = insertelement <2 x i64 addrspace(1)*> %veca, i64 addrspace(1)* %ptr, i32 1 + %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 +; CHECK: statepoint +; CHECK: gc.relocate +; CHECK-DAG: ; (%ptr, %obj) +; CHECK: gc.relocate +; CHECK-DAG: ; (%ptr, %ptr) + %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) + ret i64 addrspace(1)* %obj +} + +declare void @do_safepoint() + +declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) |

