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