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