llvm.org GIT mirror llvm / 8c0cdd1
[PlaceSafepoints] Clamp NoStatepoints to true This change permanently clamps -spp-no-statepoints to true (the code deletion will come later). Tests that specifically tested PlaceSafepoint's ability to wrap calls in gc.statepoint have been moved to RS4GC's test suite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@259096 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 3 years ago
20 changed file(s) with 329 addition(s) and 367 deletion(s). Raw diff Collapse all Expand all
107107 static cl::opt SplitBackedge("spp-split-backedge", cl::Hidden,
108108 cl::init(false));
109109
110 // If true, don't wrap calls (the ones present in the IR, and the ones
111 // introduced due to polls) in gc.statepoint.
112 static cl::opt NoStatepoints("spp-no-statepoints", cl::Hidden,
113 cl::init(false));
110 static const bool NoStatepoints = true;
114111
115112 // Print tracing output
116113 static cl::opt TraceLSP("spp-trace", cl::Hidden, cl::init(false));
55 ; CHECK-LABEL: @test_entry
66 entry:
77 ; CHECK-LABEL: entry
8 ; CHECK: statepoint
8 ; CHECK: call void @do_safepoint
99 ret void
1010 }
1111
1313 define void @test_negative() {
1414 ; CHECK-LABEL: @test_negative
1515 entry:
16 ; CHECK-NOT: statepoint
16 ; CHECK-NOT: do_safepoint
1717 ret void
1818 }
1919
2424 entry:
2525 ; CHECK-LABEL: entry
2626 ; This statepoint is technically not required, but we don't exploit that yet.
27 ; CHECK: statepoint
27 ; CHECK: call void @do_safepoint
2828 br label %other
2929
3030 ; CHECK-LABEL: other
31 ; CHECK: statepoint
31 ; CHECK: call void @do_safepoint
3232 other:
33 call void undef()
3433 br label %other
3534 }
3635
4039 ; CHECK-LABEL: test_unreachable
4140 entry:
4241 ; CHECK-LABEL: entry
43 ; CHECK: statepoint
42 ; CHECK: call void @do_safepoint
4443 ret void
4544
4645 ; CHECK-NOT: other
47 ; CHECK-NOT: statepoint
46 ; CHECK-NOT: do_safepoint
4847 other:
4948 br label %other
5049 }
5150
5251 declare void @foo()
5352
54 ; Do we turn a call into it's own statepoint
55 define void @test_simple_call() gc "statepoint-example" {
56 ; CHECK-LABEL: test_simple_call
57 entry:
58 br label %other
59 other:
60 ; CHECK-LABEL: other
61 ; CHECK: statepoint
62 ; CHECK-NOT: gc.result
63 call void @foo()
64 ret void
65 }
66
6753 declare zeroext i1 @i1_return_i1(i1)
6854
6955 define i1 @test_call_with_result() gc "statepoint-example" {
7056 ; CHECK-LABEL: test_call_with_result
71 ; This is checking that a statepoint_poll + statepoint + result is
72 ; inserted for a function that takes 1 argument.
73 ; CHECK: gc.statepoint.p0f_isVoidf
74 ; CHECK: gc.statepoint.p0f_i1i1f
75 ; CHECK: (i64 2882400000, i32 0, i1 (i1)* @i1_return_i1, i32 1, i32 0, i1 false, i32 0, i32 0)
76 ; CHECK: %call12 = call i1 @llvm.experimental.gc.result.i1
57 ; This is checking that a statepoint_poll is inserted for a function
58 ; that takes 1 argument.
59 ; CHECK: call void @do_safepoint
7760 entry:
7861 %call1 = tail call i1 (i1) @i1_return_i1(i1 false)
7962 ret i1 %call1
99
1010 entry:
1111 ; CHECK-LABEL: entry
12 ; CHECK: statepoint
12 ; CHECK: call void @do_safepoint
1313 br label %loop
1414
1515 loop:
1616 ; CHECK-LABEL: loop
17 ; CHECK: @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo
18 ; CHECK-NOT: statepoint
17 ; CHECK-NOT: call void @do_safepoint
1918 call void @foo()
2019 br label %loop
2120 }
+0
-38
test/Transforms/PlaceSafepoints/call_gc_result.ll less more
None ;; RUN: opt < %s -place-safepoints -S | FileCheck %s
1
2 ;; This test is to verify that gc_result from a call statepoint
3 ;; can have preceding phis in its parent basic block. Unlike
4 ;; invoke statepoint, call statepoint does not terminate the
5 ;; block, and thus its gc_result is in the same block with the
6 ;; call statepoint.
7
8 declare i32 @foo()
9
10 define i32 @test1(i1 %cond, i32 %a) gc "statepoint-example" {
11 entry:
12 br i1 %cond, label %branch1, label %branch2
13
14 branch1:
15 %b = add i32 %a, 1
16 br label %merge
17
18 branch2:
19 br label %merge
20
21 merge:
22 ;; CHECK: %phi = phi i32 [ %a, %branch2 ], [ %b, %branch1 ]
23 ;; CHECK-NEXT: %safepoint_token1 = call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @foo, i32 0, i32 0, i32 0, i32 0)
24 ;; CHECK-NEXT: %ret2 = call i32 @llvm.experimental.gc.result.i32(token %safepoint_token1)
25 %phi = phi i32 [ %a, %branch2 ], [ %b, %branch1 ]
26 %ret = call i32 @foo()
27 ret i32 %ret
28 }
29
30 ; This function is inlined when inserting a poll.
31 declare void @do_safepoint()
32 define void @gc.safepoint_poll() {
33 ; CHECK-LABEL: gc.safepoint_poll
34 entry:
35 call void @do_safepoint()
36 ret void
37 }
77 define void @test1(i32) gc "statepoint-example" {
88 ; CHECK-LABEL: test1
99 ; CHECK-LABEL: entry
10 ; CHECK: statepoint
10 ; CHECK: call void @do_safepoint
1111 ; CHECK-LABEL: loop
12 ; CHECK-NOT: statepoint
12 ; CHECK-NOT: call void @do_safepoint
1313 ; CHECK-LABEL: exit
1414
1515 entry:
2929 define void @test2(i32) gc "statepoint-example" {
3030 ; CHECK-LABEL: test2
3131 ; CHECK-LABEL: entry
32 ; CHECK: statepoint
32 ; CHECK: call void @do_safepoint
3333 ; CHECK-LABEL: loop
34 ; CHECK-NOT: statepoint
34 ; CHECK-NOT: call void @do_safepoint
3535 ; CHECK-LABEL: exit
3636
3737 entry:
5454 define void @test3(i8 %upper) gc "statepoint-example" {
5555 ; CHECK-LABEL: test3
5656 ; CHECK-LABEL: entry
57 ; CHECK: statepoint
57 ; CHECK: call void @do_safepoint
5858 ; CHECK-LABEL: loop
59 ; CHECK-NOT: statepoint
59 ; CHECK-NOT: call void @do_safepoint
6060 ; CHECK-LABEL: exit
6161
6262 entry:
7676 define void @test4(i64 %upper) gc "statepoint-example" {
7777 ; CHECK-LABEL: test4
7878 ; CHECK-LABEL: entry
79 ; CHECK: statepoint
79 ; CHECK: call void @do_safepoint
8080 ; CHECK-LABEL: loop
81 ; CHECK: statepoint
81 ; CHECK: call void @do_safepoint
8282 ; CHECK-LABEL: exit
8383
8484 ; COUNTED-64-LABEL: test4
8585 ; COUNTED-64-LABEL: entry
86 ; COUNTED-64: statepoint
86 ; COUNTED-64: call void @do_safepoint
8787 ; COUNTED-64-LABEL: loop
88 ; COUNTED-64-NOT: statepoint
88 ; COUNTED-64-NOT: call void @do_safepoint
8989 ; COUNTED-64-LABEL: exit
9090
9191 entry:
106106 define void @test5(i64 %upper) gc "statepoint-example" {
107107 ; CHECK-LABEL: test5
108108 ; CHECK-LABEL: entry
109 ; CHECK: statepoint
109 ; CHECK: call void @do_safepoint
110110 ; CHECK-LABEL: loop
111 ; CHECK: statepoint
111 ; CHECK: call void @do_safepoint
112112 ; CHECK-LABEL: exit
113113
114114 ; COUNTED-64-LABEL: test5
115115 ; COUNTED-64-LABEL: entry
116 ; COUNTED-64: statepoint
116 ; COUNTED-64: call void @do_safepoint
117117 ; COUNTED-64-LABEL: loop
118 ; COUNTED-64: statepoint
118 ; COUNTED-64: call void @do_safepoint
119119 ; COUNTED-64-LABEL: exit
120120
121121 entry:
+0
-111
test/Transforms/PlaceSafepoints/invokes.ll less more
None ; RUN: opt < %s -S -place-safepoints | FileCheck %s
1
2 declare i64 addrspace(1)* @some_call(i64 addrspace(1)*)
3 declare i32 @personality_function()
4
5 define i64 addrspace(1)* @test_basic(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
6 ; CHECK-LABEL: entry:
7 entry:
8 ; CHECK: invoke
9 ; CHECK: statepoint
10 ; CHECK: some_call
11 %ret_val = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
12 to label %normal_return unwind label %exceptional_return
13
14 ; CHECK-LABEL: normal_return:
15 ; CHECK: gc.result
16 ; CHECK: ret i64
17
18 normal_return:
19 ret i64 addrspace(1)* %ret_val
20
21 ; CHECK-LABEL: exceptional_return:
22 ; CHECK: landingpad
23 ; CHECK: ret i64
24
25 exceptional_return:
26 %landing_pad4 = landingpad {i8*, i32}
27 cleanup
28 ret i64 addrspace(1)* %obj1
29 }
30
31 define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
32 ; CHECK-LABEL: entry:
33 entry:
34 ; CHECK: invoke
35 ; CHECK: statepoint
36 ; CHECK: some_call
37 %ret_val1 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
38 to label %second_invoke unwind label %exceptional_return
39
40 ; CHECK-LABEL: second_invoke:
41 second_invoke:
42 ; CHECK: invoke
43 ; CHECK: statepoint
44 ; CHECK: some_call
45 %ret_val2 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %ret_val1)
46 to label %normal_return unwind label %exceptional_return
47
48 ; CHECK-LABEL: normal_return:
49 normal_return:
50 ; CHECK: gc.result
51 ; CHECK: ret i64
52 ret i64 addrspace(1)* %ret_val2
53
54 ; CHECK: exceptional_return:
55 ; CHECK: ret i64
56
57 exceptional_return:
58 %landing_pad4 = landingpad {i8*, i32}
59 cleanup
60 ret i64 addrspace(1)* %obj1
61 }
62
63 define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" personality i32 ()* @personality_function {
64 ; CHECK-LABEL: @test_phi_node
65 ; CHECK-LABEL: entry:
66 entry:
67 br i1 %cond, label %left, label %right
68
69 left:
70 %ret_val_left = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
71 to label %merge unwind label %exceptional_return
72
73 right:
74 %ret_val_right = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
75 to label %merge unwind label %exceptional_return
76
77 ; CHECK: merge[[A:[0-9]]]:
78 ; CHECK: gc.result
79 ; CHECK: br label %[[with_phi:merge[0-9]*]]
80
81 ; CHECK: merge[[B:[0-9]]]:
82 ; CHECK: gc.result
83 ; CHECK: br label %[[with_phi]]
84
85 ; CHECK: [[with_phi]]:
86 ; CHECK: phi
87 ; CHECK: ret i64 addrspace(1)* %ret_val
88 merge:
89 %ret_val = phi i64 addrspace(1)* [%ret_val_left, %left], [%ret_val_right, %right]
90 ret i64 addrspace(1)* %ret_val
91
92 ; CHECK-LABEL: exceptional_return:
93 ; CHECK: ret i64 addrspace(1)*
94
95 exceptional_return:
96 %landing_pad4 = landingpad {i8*, i32}
97 cleanup
98 ret i64 addrspace(1)* %obj
99 }
100
101 declare void @do_safepoint()
102 define void @gc.safepoint_poll() {
103 ; CHECK-LABEL: gc.safepoint_poll
104 ; CHECK-LABEL: entry
105 ; CHECK-NEXT: do_safepoint
106 ; CHECK-NEXT: ret void
107 entry:
108 call void @do_safepoint()
109 ret void
110 }
+0
-35
test/Transforms/PlaceSafepoints/leaf-function.ll less more
None ; RUN: opt < %s -S -place-safepoints | FileCheck %s
1
2 declare void @foo() "gc-leaf-function"
3 declare void @bar()
4
5 ; Calls of functions with the "gc-leaf-function" attribute shouldn't be turned
6 ; into a safepoint. An entry safepoint should get inserted, though.
7 define void @test_leaf_function() gc "statepoint-example" {
8 ; CHECK-LABEL: test_leaf_function
9 ; CHECK: gc.statepoint.p0f_isVoidf
10 ; CHECK-NOT: statepoint
11 ; CHECK-NOT: gc.result
12 entry:
13 call void @foo()
14 ret void
15 }
16
17 define void @test_leaf_function_call() gc "statepoint-example" {
18 ; CHECK-LABEL: test_leaf_function_call
19 ; CHECK: gc.statepoint.p0f_isVoidf
20 ; CHECK-NOT: statepoint
21 ; CHECK-NOT: gc.result
22 entry:
23 call void @bar() "gc-leaf-function"
24 ret void
25 }
26
27 ; This function is inlined when inserting a poll.
28 declare void @do_safepoint()
29 define void @gc.safepoint_poll() {
30 ; CHECK-LABEL: gc.safepoint_poll
31 entry:
32 call void @do_safepoint()
33 ret void
34 }
None ; RUN: opt -spp-no-statepoints -S -place-safepoints < %s | FileCheck %s
0 ; RUN: opt -S -place-safepoints < %s | FileCheck %s
11
22 define void @test() gc "statepoint-example" {
33 ; CHECK-LABEL: test(
+0
-44
test/Transforms/PlaceSafepoints/patchable-statepoints.ll less more
None ; RUN: opt -place-safepoints -S < %s | FileCheck %s
1
2 declare void @f()
3 declare i32 @personality_function()
4
5 define void @test_id() gc "statepoint-example" personality i32 ()* @personality_function {
6 ; CHECK-LABEL: @test_id(
7 entry:
8 ; CHECK-LABEL: entry:
9 ; CHECK: invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 100, i32 0, void ()* @f
10 invoke void @f() "statepoint-id"="100" to label %normal_return unwind label %exceptional_return
11
12 normal_return:
13 ret void
14
15 exceptional_return:
16 %landing_pad4 = landingpad {i8*, i32} cleanup
17 ret void
18 }
19
20 define void @test_num_patch_bytes() gc "statepoint-example" personality i32 ()* @personality_function {
21 ; CHECK-LABEL: @test_num_patch_bytes(
22 entry:
23 ; CHECK-LABEL: entry:
24 ; CHECK: invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 99, void ()* @f,
25 invoke void @f() "statepoint-num-patch-bytes"="99" to label %normal_return unwind label %exceptional_return
26
27 normal_return:
28 ret void
29
30 exceptional_return:
31 %landing_pad4 = landingpad {i8*, i32} cleanup
32 ret void
33 }
34
35 declare void @do_safepoint()
36 define void @gc.safepoint_poll() {
37 entry:
38 call void @do_safepoint()
39 ret void
40 }
41
42 ; CHECK-NOT: statepoint-id
43 ; CHECK-NOT: statepoint-num-patch_bytes
33 define void @test(i32, i1 %cond) gc "statepoint-example" {
44 ; CHECK-LABEL: @test
55 ; CHECK-LABEL: loop.loop_crit_edge
6 ; CHECK: gc.statepoint
6 ; CHECK: call void @do_safepoint
77 ; CHECK-NEXT: br label %loop
88 entry:
99 br label %loop
2222 define void @test2(i32, i1 %cond) gc "statepoint-example" {
2323 ; CHECK-LABEL: @test2
2424 ; CHECK-LABEL: loop2.loop2_crit_edge:
25 ; CHECK: gc.statepoint
25 ; CHECK: call void @do_safepoint
2626 ; CHECK-NEXT: br label %loop2
2727 ; CHECK-LABEL: loop2.loop_crit_edge:
28 ; CHECK: gc.statepoint
28 ; CHECK: call void @do_safepoint
2929 ; CHECK-NEXT: br label %loop
3030 entry:
3131 br label %loop
+0
-42
test/Transforms/PlaceSafepoints/statepoint-calling-conventions.ll less more
None ; RUN: opt -place-safepoints -S < %s | FileCheck %s
1
2 ; Ensure that the gc.statepoint calls / invokes we generate carry over
3 ; the right calling conventions.
4
5 define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
6 ; CHECK-LABEL: @test_invoke_format(
7 ; CHECK-LABEL: entry:
8 ; CHECK: invoke coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0)
9 entry:
10 %ret_val = invoke coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
11 to label %normal_return unwind label %exceptional_return
12
13 normal_return:
14 ret i64 addrspace(1)* %ret_val
15
16 exceptional_return:
17 %landing_pad4 = landingpad {i8*, i32}
18 cleanup
19 ret i64 addrspace(1)* %obj1
20 }
21
22 define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
23 ; CHECK-LABEL: @test_call_format(
24 ; CHECK-LABEL: entry:
25 ; CHECK: call coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0)
26 entry:
27 %ret_val = call coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
28 ret i64 addrspace(1)* %ret_val
29 }
30
31 ; This function is inlined when inserting a poll.
32 declare void @do_safepoint()
33 define void @gc.safepoint_poll() {
34 ; CHECK-LABEL: gc.safepoint_poll
35 entry:
36 call void @do_safepoint()
37 ret void
38 }
39
40 declare coldcc i64 addrspace(1)* @callee(i64 addrspace(1)*)
41 declare i32 @personality()
77 define void @test_simple_call() gc "coreclr" {
88 ; CHECK-LABEL: test_simple_call
99 entry:
10 ; CHECK: call void @do_safepoint
1011 br label %other
1112 other:
12 ; CHECK-LABEL: other
13 ; CHECK: statepoint
14 ; CHECK-NOT: gc.result
1513 call void @foo()
1614 ret void
1715 }
+0
-42
test/Transforms/PlaceSafepoints/statepoint-format.ll less more
None ; RUN: opt -place-safepoints -S < %s | FileCheck %s
1
2 ; Ensure that the gc.statepoint calls / invokes we generate have the
3 ; set of arguments we expect it to have.
4
5 define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
6 ; CHECK-LABEL: @test_invoke_format(
7 ; CHECK-LABEL: entry:
8 ; CHECK: invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0)
9 entry:
10 %ret_val = invoke i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
11 to label %normal_return unwind label %exceptional_return
12
13 normal_return:
14 ret i64 addrspace(1)* %ret_val
15
16 exceptional_return:
17 %landing_pad4 = landingpad {i8*, i32}
18 cleanup
19 ret i64 addrspace(1)* %obj1
20 }
21
22 define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
23 ; CHECK-LABEL: @test_call_format(
24 ; CHECK-LABEL: entry:
25 ; CHECK: call token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0)
26 entry:
27 %ret_val = call i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
28 ret i64 addrspace(1)* %ret_val
29 }
30
31 ; This function is inlined when inserting a poll.
32 declare void @do_safepoint()
33 define void @gc.safepoint_poll() {
34 ; CHECK-LABEL: gc.safepoint_poll
35 entry:
36 call void @do_safepoint()
37 ret void
38 }
39
40 declare i64 addrspace(1)* @callee(i64 addrspace(1)*)
41 declare i32 @personality()
88 ; CHECK-LABEL: entry
99 ; CHECK-NEXT: alloca
1010 ; CHECK-NEXT: localescape
11 ; CHECK-NEXT: statepoint
11 ; CHECK-NEXT: call void @do_safepoint
1212 %ptr = alloca i32
1313 call void (...) @llvm.localescape(i32* %ptr)
1414 ret void
0 ;; RUN: opt < %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S | FileCheck %s
1
2 ;; This test is to verify that gc_result from a call statepoint
3 ;; can have preceding phis in its parent basic block. Unlike
4 ;; invoke statepoint, call statepoint does not terminate the
5 ;; block, and thus its gc_result is in the same block with the
6 ;; call statepoint.
7
8 declare i32 @foo()
9
10 define i32 @test1(i1 %cond, i32 %a) gc "statepoint-example" {
11 entry:
12 br i1 %cond, label %branch1, label %branch2
13
14 branch1:
15 %b = add i32 %a, 1
16 br label %merge
17
18 branch2:
19 br label %merge
20
21 merge:
22 ;; CHECK: %phi = phi i32 [ %a, %branch2 ], [ %b, %branch1 ]
23 ;; CHECK-NEXT: [[TOKEN:%[^ ]+]] = call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 2882400000, i32 0, i32 ()* @foo, i32 0, i32 0, i32 0, i32 0
24 ;; CHECK-NEXT: call i32 @llvm.experimental.gc.result.i32(token [[TOKEN]])
25 %phi = phi i32 [ %a, %branch2 ], [ %b, %branch1 ]
26 %ret = call i32 @foo()
27 ret i32 %ret
28 }
29
30 ; This function is inlined when inserting a poll.
31 declare void @do_safepoint()
32 define void @gc.safepoint_poll() {
33 ; CHECK-LABEL: gc.safepoint_poll
34 entry:
35 call void @do_safepoint()
36 ret void
37 }
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles | FileCheck %s
1
2 declare i64 addrspace(1)* @some_call(i64 addrspace(1)*)
3 declare i32 @personality_function()
4
5 define i64 addrspace(1)* @test_basic(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
6 ; CHECK-LABEL: entry:
7 entry:
8 ; CHECK: invoke
9 ; CHECK: statepoint
10 ; CHECK: some_call
11 %ret_val = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
12 to label %normal_return unwind label %exceptional_return
13
14 ; CHECK-LABEL: normal_return:
15 ; CHECK: gc.result
16 ; CHECK: ret i64
17
18 normal_return:
19 ret i64 addrspace(1)* %ret_val
20
21 ; CHECK-LABEL: exceptional_return:
22 ; CHECK: landingpad
23 ; CHECK: ret i64
24
25 exceptional_return:
26 %landing_pad4 = landingpad token
27 cleanup
28 ret i64 addrspace(1)* %obj1
29 }
30
31 define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
32 ; CHECK-LABEL: entry:
33 entry:
34 ; CHECK: invoke
35 ; CHECK: statepoint
36 ; CHECK: some_call
37 %ret_val1 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
38 to label %second_invoke unwind label %exceptional_return
39
40 ; CHECK-LABEL: second_invoke:
41 second_invoke:
42 ; CHECK: invoke
43 ; CHECK: statepoint
44 ; CHECK: some_call
45 %ret_val2 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %ret_val1)
46 to label %normal_return unwind label %exceptional_return
47
48 ; CHECK-LABEL: normal_return:
49 normal_return:
50 ; CHECK: gc.result
51 ; CHECK: ret i64
52 ret i64 addrspace(1)* %ret_val2
53
54 ; CHECK: exceptional_return:
55 ; CHECK: ret i64
56
57 exceptional_return:
58 %landing_pad4 = landingpad token
59 cleanup
60 ret i64 addrspace(1)* %obj1
61 }
62
63 define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" personality i32 ()* @personality_function {
64 ; CHECK-LABEL: @test_phi_node
65 ; CHECK-LABEL: entry:
66 entry:
67 br i1 %cond, label %left, label %right
68
69 left:
70 %ret_val_left = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
71 to label %merge unwind label %exceptional_return
72
73 right:
74 %ret_val_right = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
75 to label %merge unwind label %exceptional_return
76
77 ; CHECK: merge[[A:[0-9]]]:
78 ; CHECK: gc.result
79 ; CHECK: br label %[[with_phi:merge[0-9]*]]
80
81 ; CHECK: merge[[B:[0-9]]]:
82 ; CHECK: gc.result
83 ; CHECK: br label %[[with_phi]]
84
85 ; CHECK: [[with_phi]]:
86 ; CHECK: phi
87 ; CHECK: ret i64 addrspace(1)* %ret_val
88 merge:
89 %ret_val = phi i64 addrspace(1)* [%ret_val_left, %left], [%ret_val_right, %right]
90 ret i64 addrspace(1)* %ret_val
91
92 ; CHECK-LABEL: exceptional_return:
93 ; CHECK: ret i64 addrspace(1)*
94
95 exceptional_return:
96 %landing_pad4 = landingpad token
97 cleanup
98 ret i64 addrspace(1)* %obj
99 }
100
101 declare void @do_safepoint()
102 define void @gc.safepoint_poll() {
103 ; CHECK-LABEL: gc.safepoint_poll
104 ; CHECK-LABEL: entry
105 ; CHECK-NEXT: do_safepoint
106 ; CHECK-NEXT: ret void
107 entry:
108 call void @do_safepoint()
109 ret void
110 }
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles | FileCheck %s
1
2 declare void @foo() "gc-leaf-function"
3 declare void @bar()
4
5 ; Calls of functions with the "gc-leaf-function" attribute shouldn't be turned
6 ; into a safepoint. An entry safepoint should get inserted, though.
7 define void @test_leaf_function() gc "statepoint-example" {
8 ; CHECK-LABEL: test_leaf_function
9 ; CHECK-NOT: gc.statepoint
10 ; CHECK-NOT: gc.result
11 entry:
12 call void @foo()
13 ret void
14 }
15
16 define void @test_leaf_function_call() gc "statepoint-example" {
17 ; CHECK-LABEL: test_leaf_function_call
18 ; CHECK-NOT: gc.statepoint
19 ; CHECK-NOT: gc.result
20 entry:
21 call void @bar() "gc-leaf-function"
22 ret void
23 }
24
25 ; This function is inlined when inserting a poll.
26 declare void @do_safepoint()
27 define void @gc.safepoint_poll() {
28 ; CHECK-LABEL: gc.safepoint_poll
29 entry:
30 call void @do_safepoint()
31 ret void
32 }
0 ; RUN: opt -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S < %s | FileCheck %s
1
2 ; Ensure that the gc.statepoint calls / invokes we generate carry over
3 ; the right calling conventions.
4
5 define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
6 ; CHECK-LABEL: @test_invoke_format(
7 ; CHECK-LABEL: entry:
8 ; CHECK: invoke coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0
9 entry:
10 %ret_val = invoke coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
11 to label %normal_return unwind label %exceptional_return
12
13 normal_return:
14 ret i64 addrspace(1)* %ret_val
15
16 exceptional_return:
17 %landing_pad4 = landingpad token
18 cleanup
19 ret i64 addrspace(1)* %obj1
20 }
21
22 define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
23 ; CHECK-LABEL: @test_call_format(
24 ; CHECK-LABEL: entry:
25 ; CHECK: call coldcc token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0
26 entry:
27 %ret_val = call coldcc i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
28 ret i64 addrspace(1)* %ret_val
29 }
30
31 ; This function is inlined when inserting a poll.
32 declare void @do_safepoint()
33 define void @gc.safepoint_poll() {
34 ; CHECK-LABEL: gc.safepoint_poll
35 entry:
36 call void @do_safepoint()
37 ret void
38 }
39
40 declare coldcc i64 addrspace(1)* @callee(i64 addrspace(1)*)
41 declare i32 @personality()
0 ; RUN: opt < %s -S -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles | FileCheck %s
1
2 ; Basic test to make sure that safepoints are placed
3 ; for CoreCLR GC
4
5 declare void @foo()
6
7 define void @test_simple_call() gc "coreclr" {
8 ; CHECK-LABEL: test_simple_call
9 entry:
10 br label %other
11 other:
12 ; CHECK-LABEL: other
13 ; CHECK: statepoint
14 ; CHECK-NOT: gc.result
15 call void @foo()
16 ret void
17 }
18
19 ; This function is inlined when inserting a poll. To avoid recursive
20 ; issues, make sure we don't place safepoints in it.
21 declare void @do_safepoint()
22 define void @gc.safepoint_poll() {
23 ; CHECK-LABEL: gc.safepoint_poll
24 ; CHECK-LABEL: entry
25 ; CHECK-NEXT: do_safepoint
26 ; CHECK-NEXT: ret void
27 entry:
28 call void @do_safepoint()
29 ret void
30 }
0 ; RUN: opt -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S < %s | FileCheck %s
1
2 ; Ensure that the gc.statepoint calls / invokes we generate have the
3 ; set of arguments we expect it to have.
4
5 define i64 addrspace(1)* @test_invoke_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality {
6 ; CHECK-LABEL: @test_invoke_format(
7 ; CHECK-LABEL: entry:
8 ; CHECK: invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
9 entry:
10 %ret_val = invoke i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
11 to label %normal_return unwind label %exceptional_return
12
13 normal_return:
14 ret i64 addrspace(1)* %ret_val
15
16 exceptional_return:
17 %landing_pad4 = landingpad token
18 cleanup
19 ret i64 addrspace(1)* %obj1
20 }
21
22 define i64 addrspace(1)* @test_call_format(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" {
23 ; CHECK-LABEL: @test_call_format(
24 ; CHECK-LABEL: entry:
25 ; CHECK: call token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 2882400000, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @callee, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 0, i64 addrspace(1)* %obj)
26 entry:
27 %ret_val = call i64 addrspace(1)* @callee(i64 addrspace(1)* %obj)
28 ret i64 addrspace(1)* %ret_val
29 }
30
31 ; This function is inlined when inserting a poll.
32 declare void @do_safepoint()
33 define void @gc.safepoint_poll() {
34 ; CHECK-LABEL: gc.safepoint_poll
35 entry:
36 call void @do_safepoint()
37 ret void
38 }
39
40 declare i64 addrspace(1)* @callee(i64 addrspace(1)*)
41 declare i32 @personality()