[RS4GC] Fix rematerialization of bitcast of bitcast.
[oota-llvm.git] / test / Transforms / RewriteStatepointsForGC / deref-pointers.ll
1 ; RUN: opt -S -rewrite-statepoints-for-gc < %s | FileCheck %s
2
3 declare void @foo()
4 declare i8 addrspace(1)* @some_function()
5 declare void @some_function_consumer(i8 addrspace(1)*)
6 declare dereferenceable(4) i8 addrspace(1)* @some_function_ret_deref()
7 ; CHECK: declare i8 addrspace(1)* @some_function_ret_deref()
8 declare noalias i8 addrspace(1)* @some_function_ret_noalias()
9 ; CHECK: declare i8 addrspace(1)* @some_function_ret_noalias()
10
11 define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* dereferenceable(4) %a) gc "statepoint-example" {
12 ; CHECK: define i8 addrspace(1)* @test_deref_arg(i8 addrspace(1)* %a)
13 entry:
14   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
15   ret i8 addrspace(1)* %a
16 }
17
18 define i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* dereferenceable_or_null(4) %a) gc "statepoint-example" {
19 ; CHECK: define i8 addrspace(1)* @test_deref_or_null_arg(i8 addrspace(1)* %a)
20 entry:
21   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
22   ret i8 addrspace(1)* %a
23 }
24
25 define i8 addrspace(1)* @test_deref_retval() gc "statepoint-example" {
26 ; CHECK-LABEL: @test_deref_retval(
27 entry:
28   %a = call dereferenceable(4) i8 addrspace(1)* @some_function()
29 ; CHECK: %a = call i8 addrspace(1)* @some_function()
30   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
31   ret i8 addrspace(1)* %a
32 }
33
34 define i8 addrspace(1)* @test_deref_or_null_retval() gc "statepoint-example" {
35 ; CHECK-LABEL: @test_deref_or_null_retval(
36 entry:
37   %a = call dereferenceable_or_null(4) i8 addrspace(1)* @some_function()
38 ; CHECK: %a = call i8 addrspace(1)* @some_function()
39   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
40   ret i8 addrspace(1)* %a
41 }
42
43 define i8 @test_md(i8 addrspace(1)* %ptr) gc "statepoint-example" {
44 ; CHECK-LABEL: @test_md(
45  entry:
46 ; CHECK: %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !0
47   %tmp = load i8, i8 addrspace(1)* %ptr, !tbaa !0
48   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
49   ret i8 %tmp
50 }
51
52 define i8 addrspace(1)* @test_decl_only_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
53 ; CHECK-LABEL: @test_decl_only_attribute(
54 entry:
55 ; No change here, but the prototype of some_function_ret_deref should have changed.
56 ; CHECK: call i8 addrspace(1)* @some_function_ret_deref()
57   %a = call i8 addrspace(1)* @some_function_ret_deref()
58   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
59   ret i8 addrspace(1)* %a
60 }
61
62 define i8 addrspace(1)* @test_callsite_arg_attribute(i8 addrspace(1)* %ptr) gc "statepoint-example" {
63 ; CHECK-LABEL: @test_callsite_arg_attribute(
64 entry:
65 ; CHECK: call void @some_function_consumer(i8 addrspace(1)* %ptr)
66   call void @some_function_consumer(i8 addrspace(1)* dereferenceable(4) %ptr)
67   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
68   ret i8 addrspace(1)* %ptr
69 }
70
71 define i8 addrspace(1)* @test_noalias_arg(i8 addrspace(1)* noalias %a) gc "statepoint-example" {
72 ; CHECK: define i8 addrspace(1)* @test_noalias_arg(i8 addrspace(1)* %a)
73 entry:
74   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
75   ret i8 addrspace(1)* %a
76 }
77
78 define i8 addrspace(1)* @test_noalias_retval() gc "statepoint-example" {
79 ; CHECK-LABEL: @test_noalias_retval(
80 entry:
81   %a = call noalias i8 addrspace(1)* @some_function()
82 ; CHECK: %a = call i8 addrspace(1)* @some_function()
83   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
84   ret i8 addrspace(1)* %a
85 }
86
87 define i8 addrspace(1)* @test_decl_only_noalias(i8 addrspace(1)* %ptr) gc "statepoint-example" {
88 ; CHECK-LABEL: @test_decl_only_noalias(
89 entry:
90 ; No change here, but the prototype of some_function_ret_noalias should have changed.
91 ; CHECK: call i8 addrspace(1)* @some_function_ret_noalias()
92   %a = call i8 addrspace(1)* @some_function_ret_noalias()
93   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
94   ret i8 addrspace(1)* %a
95 }
96
97 define i8 addrspace(1)* @test_callsite_arg_noalias(i8 addrspace(1)* %ptr) gc "statepoint-example" {
98 ; CHECK-LABEL: @test_callsite_arg_noalias(
99 entry:
100 ; CHECK: call void @some_function_consumer(i8 addrspace(1)* %ptr)
101   call void @some_function_consumer(i8 addrspace(1)* noalias %ptr)
102   call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0)
103   ret i8 addrspace(1)* %ptr
104 }
105
106 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
107
108 !0 = !{!1, !1, i64 0, i64 1}
109 !1 = !{!"red", !2}
110 !2 = !{!"blue"}
111
112 ; CHECK: !0 = !{!1, !1, i64 0}
113 ; CHECK: !1 = !{!"red", !2}
114 ; CHECK: !2 = !{!"blue"}