1*cee313d2SEric Christopher; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
2*cee313d2SEric Christopher; RUN: opt -S -passes=rewrite-statepoints-for-gc < %s | FileCheck %s
3*cee313d2SEric Christopher
4*cee313d2SEric Christopher; CHECK: declare i8 addrspace(1)* @some_function_ret_deref()
5*cee313d2SEric Christopher; CHECK: define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* %a)
6*cee313d2SEric Christopher; CHECK: define i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* %a)
7*cee313d2SEric Christopher; CHECK: define i8 addrspace(1)* @test_noalias_arg(i8 addrspace(1)* %a)
8*cee313d2SEric Christopher
9*cee313d2SEric Christopherdeclare void @foo()
10*cee313d2SEric Christopher
11*cee313d2SEric Christopherdeclare i8 addrspace(1)* @some_function() "gc-leaf-function"
12*cee313d2SEric Christopher
13*cee313d2SEric Christopherdeclare void @some_function_consumer(i8 addrspace(1)*) "gc-leaf-function"
14*cee313d2SEric Christopher
15*cee313d2SEric Christopherdeclare dereferenceable(4) i8 addrspace(1)* @some_function_ret_deref() "gc-leaf-function"
16*cee313d2SEric Christopherdeclare noalias i8 addrspace(1)* @some_function_ret_noalias() "gc-leaf-function"
17*cee313d2SEric Christopher
18*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* dereferenceable(4) %a) gc "statepoint-example" {
19*cee313d2SEric Christopherentry:
20*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
21*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
22*cee313d2SEric Christopher}
23*cee313d2SEric Christopher
24*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* dereferenceable_or_null(4) %a) gc "statepoint-example" {
25*cee313d2SEric Christopherentry:
26*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
27*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
28*cee313d2SEric Christopher}
29*cee313d2SEric Christopher
30*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_noalias_arg(i8 addrspace(1)* noalias %a) gc "statepoint-example" {
31*cee313d2SEric Christopherentry:
32*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
33*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
34*cee313d2SEric Christopher}
35*cee313d2SEric Christopher
36*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_deref_retval() gc "statepoint-example" {
37*cee313d2SEric Christopher; CHECK-LABEL: @test_deref_retval(
38*cee313d2SEric Christopher; CHECK: %a = call i8 addrspace(1)* @some_function()
39*cee313d2SEric Christopherentry:
40*cee313d2SEric Christopher  %a = call dereferenceable(4) i8 addrspace(1)* @some_function()
41*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
42*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
43*cee313d2SEric Christopher}
44*cee313d2SEric Christopher
45*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_deref_or_null_retval() gc "statepoint-example" {
46*cee313d2SEric Christopher; CHECK-LABEL: @test_deref_or_null_retval(
47*cee313d2SEric Christopher; CHECK: %a = call i8 addrspace(1)* @some_function()
48*cee313d2SEric Christopherentry:
49*cee313d2SEric Christopher  %a = call dereferenceable_or_null(4) i8 addrspace(1)* @some_function()
50*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
51*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
52*cee313d2SEric Christopher}
53*cee313d2SEric Christopher
54*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_noalias_retval() gc "statepoint-example" {
55*cee313d2SEric Christopher; CHECK-LABEL: @test_noalias_retval(
56*cee313d2SEric Christopher; CHECK: %a = call i8 addrspace(1)* @some_function()
57*cee313d2SEric Christopherentry:
58*cee313d2SEric Christopher  %a = call noalias i8 addrspace(1)* @some_function()
59*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
60*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
61*cee313d2SEric Christopher}
62*cee313d2SEric Christopher
63*cee313d2SEric Christopherdefine i8 @test_md(i8 addrspace(1)* %ptr) gc "statepoint-example" {
64*cee313d2SEric Christopher; CHECK-LABEL: @test_md(
65*cee313d2SEric Christopher; CHECK: %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa [[TAG_old:!.*]]
66*cee313d2SEric Christopherentry:
67*cee313d2SEric Christopher  %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !0
68*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
69*cee313d2SEric Christopher  ret i8 %tmp
70*cee313d2SEric Christopher}
71*cee313d2SEric Christopher
72*cee313d2SEric Christopher; Same as test_md() above, but with new-format TBAA metadata.
73*cee313d2SEric Christopherdefine i8 @test_md_new(i8 addrspace(1)* %ptr) gc "statepoint-example" {
74*cee313d2SEric Christopher; CHECK-LABEL: @test_md_new(
75*cee313d2SEric Christopher; CHECK: %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa [[TAG_new:!.*]]
76*cee313d2SEric Christopherentry:
77*cee313d2SEric Christopher  %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !4
78*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
79*cee313d2SEric Christopher  ret i8 %tmp
80*cee313d2SEric Christopher}
81*cee313d2SEric Christopher
82*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_decl_only_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
83*cee313d2SEric Christopher; CHECK-LABEL: @test_decl_only_attribute(
84*cee313d2SEric Christopher; No change here, but the prototype of some_function_ret_deref should have changed.
85*cee313d2SEric Christopher; CHECK: call i8 addrspace(1)* @some_function_ret_deref()
86*cee313d2SEric Christopherentry:
87*cee313d2SEric Christopher  %a = call i8 addrspace(1)* @some_function_ret_deref()
88*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
89*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
90*cee313d2SEric Christopher}
91*cee313d2SEric Christopher
92*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_decl_only_noalias(i8 addrspace(1)* %ptr) gc "statepoint-example" {
93*cee313d2SEric Christopher; CHECK-LABEL: @test_decl_only_noalias(
94*cee313d2SEric Christopher; No change here, but the prototype of some_function_ret_noalias should have changed.
95*cee313d2SEric Christopher; CHECK: call i8 addrspace(1)* @some_function_ret_noalias()
96*cee313d2SEric Christopherentry:
97*cee313d2SEric Christopher  %a = call i8 addrspace(1)* @some_function_ret_noalias()
98*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
99*cee313d2SEric Christopher  ret i8 addrspace(1)* %a
100*cee313d2SEric Christopher}
101*cee313d2SEric Christopher
102*cee313d2SEric Christopherdefine i8 addrspace(1)* @test_callsite_arg_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
103*cee313d2SEric Christopher; CHECK-LABEL: @test_callsite_arg_attribute(
104*cee313d2SEric Christopher; CHECK: call void @some_function_consumer(i8 addrspace(1)* %ptr)
105*cee313d2SEric Christopherentry:
106*cee313d2SEric Christopher  call void @some_function_consumer(i8 addrspace(1)* dereferenceable(4) noalias %ptr)
107*cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
108*cee313d2SEric Christopher  ret i8 addrspace(1)* %ptr
109*cee313d2SEric Christopher}
110*cee313d2SEric Christopher
111*cee313d2SEric Christopher!0 = !{!1, !2, i64 0, i64 1}  ; TAG_old
112*cee313d2SEric Christopher!1 = !{!"type_base_old", !2, i64 0}
113*cee313d2SEric Christopher!2 = !{!"type_access_old", !3}
114*cee313d2SEric Christopher!3 = !{!"root"}
115*cee313d2SEric Christopher
116*cee313d2SEric Christopher!4 = !{!5, !6, i64 0, i64 1, i64 1}  ; TAG_new
117*cee313d2SEric Christopher!5 = !{!3, i64 1, !"type_base_new", !6, i64 0, i64 1}
118*cee313d2SEric Christopher!6 = !{!3, i64 1, !"type_access_new"}
119*cee313d2SEric Christopher
120*cee313d2SEric Christopher; CHECK-DAG: [[ROOT:!.*]] = !{!"root"}
121*cee313d2SEric Christopher; CHECK-DAG: [[TYPE_access_old:!.*]] = !{!"type_access_old", [[ROOT]]}
122*cee313d2SEric Christopher; CHECK-DAG: [[TYPE_base_old:!.*]] = !{!"type_base_old", [[TYPE_access_old]], i64 0}
123*cee313d2SEric Christopher; CHECK-DAG: [[TAG_old]] = !{[[TYPE_base_old]], [[TYPE_access_old]], i64 0}
124*cee313d2SEric Christopher; CHECK-DAG: [[TYPE_access_new:!.*]] = !{[[ROOT]], i64 1, !"type_access_new"}
125*cee313d2SEric Christopher; CHECK-DAG: [[TYPE_base_new:!.*]] = !{[[ROOT]], i64 1, !"type_base_new", [[TYPE_access_new]], i64 0, i64 1}
126*cee313d2SEric Christopher; CHECK-DAG: [[TAG_new]] = !{[[TYPE_base_new]], [[TYPE_access_new]], i64 0, i64 1}
127