diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
| commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
| tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /test/Transforms/RewriteStatepointsForGC | |
| parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
Notes
Diffstat (limited to 'test/Transforms/RewriteStatepointsForGC')
4 files changed, 198 insertions, 0 deletions
diff --git a/test/Transforms/RewriteStatepointsForGC/base-vector.ll b/test/Transforms/RewriteStatepointsForGC/base-vector.ll index 39a78d725977..9026275cf682 100644 --- a/test/Transforms/RewriteStatepointsForGC/base-vector.ll +++ b/test/Transforms/RewriteStatepointsForGC/base-vector.ll @@ -165,4 +165,83 @@ next: ; preds = %merge ret i64 addrspace(1)* %objb } +; identify base for shufflevector +define void @test8(i64 addrspace(1)* %obj, i64 %idx) gc "statepoint-example" { +; CHECK-LABEL: @test8 +; CHECK: %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1 +; CHECK: %gep2 = getelementptr i64, i64 addrspace(1)* %obj, i64 2 +; CHECK: %vec1.base = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* %obj, i32 0, !is_base_value !0 +; CHECK: %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 +; CHECK: %vec2.base = insertelement <4 x i64 addrspace(1)*> zeroinitializer, i64 addrspace(1)* %obj, i32 2, !is_base_value !0 +; CHECK: %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep2, i32 2 +; CHECK: %vec.base = shufflevector <4 x i64 addrspace(1)*> %vec1.base, <4 x i64 addrspace(1)*> %vec2.base, <2 x i32> <i32 0, i32 2>, !is_base_value !0 +; CHECK: %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec2, <2 x i32> <i32 0, i32 2> +; CHECK: %bdv.base = extractelement <2 x i64 addrspace(1)*> %vec.base, i64 %idx, !is_base_value !0 +; CHECK: %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx +; CHECK: gc.statepoint +; CHECK: gc.relocate +; CHECK-DAG: (%bdv.base, %bdv) +entry: + %gep = getelementptr i64, i64 addrspace(1)* %obj, i64 1 + %gep2 = getelementptr i64, i64 addrspace(1)* %obj, i64 2 + %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep, i32 0 + %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %gep2, i32 2 + %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec2, <2 x i32> <i32 0, i32 2> + %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx + call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] + call void @use(i64 addrspace(1)* %bdv) + ret void +} + +; Since the same 'base' vector is used in the shuffle operands, we do not need +; create a shufflevector base. +define void @test9(<4 x i64 addrspace(1)*> %vec1, i64 %idx) gc "statepoint-example" { +; CHECK-LABEL: @test9 +; CHECK: %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec1, <2 x i32> <i32 0, i32 2> +; CHECK: %base_ee = extractelement <4 x i64 addrspace(1)*> %vec1, i64 %idx, !is_base_value !0 +; CHECK: %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx +; CHECK: gc.statepoint +; CHECK: gc.relocate +; CHECK-DAG: (%base_ee, %bdv) +entry: + ; shrinking vec1 into vec + %vec = shufflevector <4 x i64 addrspace(1)*> %vec1, <4 x i64 addrspace(1)*> %vec1, <2 x i32> <i32 0, i32 2> + %bdv = extractelement <2 x i64 addrspace(1)*> %vec, i64 %idx + call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] + call void @use(i64 addrspace(1)* %bdv) + ret void +} + +; vector operand of shufflevector is a phi +define i64 addrspace(1)* @test10(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" { +; CHECK-LABEL: @test10 +entry: + %vec1 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj, i32 0 + br i1 %cnd, label %here, label %merge + +here: + %vec2 = insertelement <4 x i64 addrspace(1)*> undef, i64 addrspace(1)* %obj2, i32 2 + br label %merge + +merge: ; preds = %merge, %entry, %here +; CHECK-LABEL: merge: +; CHECK: %vec.base = phi <4 x i64 addrspace(1)*> [ %vec1.base, %entry ], [ %vec2.base, %here ], [ %vec3.base, %merge ], !is_base_value !0 +; CHECK: vec +; CHECK: vec3.base = shufflevector <4 x i64 addrspace(1)*> %vec.base, <4 x i64 addrspace(1)*> %vec.base +; CHECK: vec3 +; CHECK: bdv.base +; CHECK: bdv + %vec = phi <4 x i64 addrspace(1)*> [ %vec1, %entry ], [ %vec2, %here], [ %vec3, %merge] + %vec3 = shufflevector <4 x i64 addrspace(1)*> %vec, <4 x i64 addrspace(1)*> %vec, <4 x i32> <i32 2, i32 0, i32 1, i32 3> + %bdv = extractelement <4 x i64 addrspace(1)*> %vec3, i32 0 + br i1 %cnd, label %merge, label %next + +next: +; CHECK-LABEL: next: +; CHECK: gc.statepoint +; CHECK: gc.relocate +; CHECK-DAG: (%bdv.base, %bdv) + call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ] + ret i64 addrspace(1)* %bdv +} declare void @do_safepoint() diff --git a/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll b/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll new file mode 100644 index 000000000000..bbf10714e5e1 --- /dev/null +++ b/test/Transforms/RewriteStatepointsForGC/deopt-lowering-attrs.ll @@ -0,0 +1,34 @@ +; RUN: opt -rewrite-statepoints-for-gc -S < %s | FileCheck %s +; Check that the "deopt-lowering" function attribute gets transcoded into +; flags on the resulting statepoint + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +declare void @foo() +declare void @bar() "deopt-lowering"="live-in" +declare void @baz() "deopt-lowering"="live-through" + +define void @test1() gc "statepoint-example" { +; CHECK-LABEL: @test1( +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 1, i32 57) +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 1, i32 42) +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @baz, i32 0, i32 0, i32 0, i32 1, i32 13) + +entry: + call void @foo() [ "deopt"(i32 57) ] + call void @bar() [ "deopt"(i32 42) ] + call void @baz() [ "deopt"(i32 13) ] + ret void +} + +; add deopt-lowering attribute as part of callsite +define void @test2() gc "statepoint-example" { +; CHECK-LABEL: @test2( +; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 1, i32 57) + +entry: + call void @foo() "deopt-lowering"="live-in" [ "deopt"(i32 57) ] + ret void +} + diff --git a/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll b/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll index c4ec2ce5bf77..6372c9b80de5 100644 --- a/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll +++ b/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll @@ -259,3 +259,72 @@ entry: call void @use_obj32(i32 addrspace(1)* %ptr.gep11) ret void } + + +declare i32 addrspace(1)* @new_instance() nounwind "gc-leaf-function" + +; remat the gep in presence of base pointer which is a phi node. +; FIXME: We should remove the extra basephi.base as well. +define void @contains_basephi(i1 %cond) gc "statepoint-example" { +; CHECK-LABEL: contains_basephi +entry: + %base1 = call i32 addrspace(1)* @new_instance() + %base2 = call i32 addrspace(1)* @new_instance() + br i1 %cond, label %here, label %there + +here: + br label %merge + +there: + br label %merge + +merge: + ; CHECK: %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0 + ; CHECK: %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] + ; CHECK: %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 + ; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint + ; CHECK: %basephi.base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%basephi.base, %basephi.base) + ; CHECK: %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)* + ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 + ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat) + + + + %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] + %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 + call void @do_safepoint() ["deopt"() ] + call void @use_obj32(i32 addrspace(1)* %ptr.gep) + ret void +} + + +define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" { +; CHECK-LABEL: test_intersecting_chains_with_phi +entry: + %base1 = call i32 addrspace(1)* @new_instance() + %base2 = call i32 addrspace(1)* @new_instance() + br i1 %cond, label %here, label %there + +here: + br label %merge + +there: + br label %merge + +merge: + %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] + %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 + %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* + %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* + call void @do_safepoint() [ "deopt"() ] + ; CHECK: statepoint + ; CHECK: %ptr.gep.remat1 = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 + ; CHECK: %ptr.cast.remat = bitcast i32 addrspace(1)* %ptr.gep.remat1 to i64 addrspace(1)* + ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 + ; CHECK: %ptr.cast2.remat = bitcast i32 addrspace(1)* %ptr.gep.remat to i16 addrspace(1)* + ; CHECK: call void @use_obj64(i64 addrspace(1)* %ptr.cast.remat) + ; CHECK: call void @use_obj16(i16 addrspace(1)* %ptr.cast2.remat) + call void @use_obj64(i64 addrspace(1)* %ptr.cast) + call void @use_obj16(i16 addrspace(1)* %ptr.cast2) + ret void +} diff --git a/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll b/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll new file mode 100644 index 000000000000..38ad79e887f7 --- /dev/null +++ b/test/Transforms/RewriteStatepointsForGC/statepoint-attrs.ll @@ -0,0 +1,16 @@ +; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s +; Ensure statepoints copy (valid) attributes from callsites. + +declare void @f(i8 addrspace(1)* %obj) + +; copy over norecurse noimplicitfloat to statepoint call +define void @test1(i8 addrspace(1)* %arg) gc "statepoint-example" { +; CHECK-LABEL: test1( +; CHECK: call token (i64, i32, void (i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8f(i64 2882400000, i32 0, void (i8 addrspace(1)*)* @f, i32 1, i32 0, i8 addrspace(1)* %arg, i32 0, i32 0, i8 addrspace(1)* %arg) #1 + + call void @f(i8 addrspace(1)* %arg) #1 + ret void +} + + +attributes #1 = { norecurse noimplicitfloat } |
