1; RUN: llc < %s 2>&1 | FileCheck %s 2 3target triple = "x86_64-pc-linux-gnu" 4 5declare void @"some_call"(i64 addrspace(1)*) 6declare i64 addrspace(1)* @"some_other_call"(i64 addrspace(1)*) 7 8declare i32 @"personality_function"() 9 10define i64 addrspace(1)* @test_basic(i64 addrspace(1)* %obj, 11 i64 addrspace(1)* %obj1) 12gc "statepoint-example" personality i32 ()* @"personality_function" { 13entry: 14 ; CHECK: Ltmp{{[0-9]+}}: 15 ; CHECK: callq some_call 16 ; CHECK: Ltmp{{[0-9]+}}: 17 %0 = invoke token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @some_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) 18 to label %invoke_safepoint_normal_dest unwind label %exceptional_return 19 20invoke_safepoint_normal_dest: 21 ; CHECK: movq 22 %obj.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %0, i32 13, i32 13) 23 %obj1.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %0, i32 14, i32 14) 24 br label %normal_return 25 26normal_return: 27 ; CHECK: retq 28 ret i64 addrspace(1)* %obj.relocated 29 30exceptional_return: 31 ; CHECK: Ltmp{{[0-9]+}}: 32 ; CHECK: movq 33 ; CHECK: retq 34 %landing_pad = landingpad token 35 cleanup 36 %obj.relocated1 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 13, i32 13) 37 %obj1.relocated1 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 14, i32 14) 38 ret i64 addrspace(1)* %obj1.relocated1 39} 40; CHECK-LABEL: GCC_except_table{{[0-9]+}}: 41; CHECK: .long .Ltmp{{[0-9]+}}-.Ltmp{{[0-9]+}} 42; CHECK: .long .Ltmp{{[0-9]+}}-.Lfunc_begin{{[0-9]+}} 43; CHECK: .byte 0 44; CHECK: .p2align 4 45 46define i64 addrspace(1)* @test_result(i64 addrspace(1)* %obj, 47 i64 addrspace(1)* %obj1) 48 gc "statepoint-example" personality i32 ()* @personality_function { 49entry: 50 ; CHECK: .Ltmp{{[0-9]+}}: 51 ; CHECK: callq some_other_call 52 ; CHECK: .Ltmp{{[0-9]+}}: 53 %0 = invoke token (i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64 0, i32 0, i64 addrspace(1)* (i64 addrspace(1)*)* @some_other_call, i32 1, i32 0, i64 addrspace(1)* %obj, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) 54 to label %normal_return unwind label %exceptional_return 55 56normal_return: 57 ; CHECK: popq 58 ; CHECK: retq 59 %ret_val = call i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token %0) 60 ret i64 addrspace(1)* %ret_val 61 62exceptional_return: 63 ; CHECK: .Ltmp{{[0-9]+}}: 64 ; CHECK: movq 65 %landing_pad = landingpad token 66 cleanup 67 %obj.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 13, i32 13) 68 ret i64 addrspace(1)* %obj.relocated 69} 70; CHECK-LABEL: GCC_except_table{{[0-9]+}}: 71; CHECK: .long .Ltmp{{[0-9]+}}-.Ltmp{{[0-9]+}} 72; CHECK: .long .Ltmp{{[0-9]+}}-.Lfunc_begin{{[0-9]+}} 73; CHECK: .byte 0 74; CHECK: .p2align 4 75 76define i64 addrspace(1)* @test_same_val(i1 %cond, i64 addrspace(1)* %val1, i64 addrspace(1)* %val2, i64 addrspace(1)* %val3) 77 gc "statepoint-example" personality i32 ()* @"personality_function" { 78entry: 79 br i1 %cond, label %left, label %right 80 81left: 82 ; CHECK-LABEL: %left 83 ; CHECK: movq %rdx, 8(%rsp) 84 ; CHECK: movq 85 ; CHECK: callq some_call 86 %sp1 = invoke token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @some_call, i32 1, i32 0, i64 addrspace(1)* %val1, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %val1, i64 addrspace(1)* %val2) 87 to label %left.relocs unwind label %exceptional_return.left 88 89left.relocs: 90 ; CHECK: movq (%rsp), 91 ; CHECK: movq 8(%rsp), [[REGVAL2:%[a-z]+]] 92 %val1.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp1, i32 13, i32 13) 93 %val2.relocated_left = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp1, i32 14, i32 14) 94 br label %normal_return 95 96right: 97 ; CHECK-LABEL: %right 98 ; CHECK: movq 99 ; CHECK: movq %rdx, (%rsp) 100 ; CHECK: callq some_call 101 %sp2 = invoke token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @some_call, i32 1, i32 0, i64 addrspace(1)* %val1, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* %val2, i64 addrspace(1)* %val3) 102 to label %right.relocs unwind label %exceptional_return.right 103 104right.relocs: 105 ; CHECK: movq (%rsp), [[REGVAL2]] 106 ; CHECK: movq 107 %val2.relocated_right = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp2, i32 13, i32 13) 108 %val3.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp2, i32 14, i32 14) 109 br label %normal_return 110 111normal_return: 112 ; CHECK-LABEL: %normal_return 113 ; CHECK: cmoveq {{.*}}[[REGVAL2]]{{.*}} 114 ; CHECK: retq 115 %a1 = phi i64 addrspace(1)* [%val1.relocated, %left.relocs], [%val3.relocated, %right.relocs] 116 %a2 = phi i64 addrspace(1)* [%val2.relocated_left, %left.relocs], [%val2.relocated_right, %right.relocs] 117 %ret = select i1 %cond, i64 addrspace(1)* %a1, i64 addrspace(1)* %a2 118 ret i64 addrspace(1)* %ret 119 120exceptional_return.left: 121 %landing_pad = landingpad token 122 cleanup 123 %val.relocated2 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 13, i32 13) 124 ret i64 addrspace(1)* %val.relocated2 125 126exceptional_return.right: 127 %landing_pad1 = landingpad token 128 cleanup 129 %val.relocated3 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad1, i32 13, i32 13) 130 ret i64 addrspace(1)* %val.relocated3 131} 132 133define i64 addrspace(1)* @test_null_undef(i64 addrspace(1)* %val1) 134 gc "statepoint-example" personality i32 ()* @"personality_function" { 135; CHECK-LABEL: test_null_undef: 136entry: 137 ; CHECK: callq some_call 138 %sp1 = invoke token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @some_call, i32 1, i32 0, i64 addrspace(1)* %val1, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i64 addrspace(1)* null, i64 addrspace(1)* undef) 139 to label %normal_return unwind label %exceptional_return 140 141normal_return: 142 ; CHECK-LABEL: %normal_return 143 ; CHECK: xorl %eax, %eax 144 ; CHECK-NEXT: popq 145 ; CHECK-NEXT: retq 146 %null.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp1, i32 13, i32 13) 147 %undef.relocated = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %sp1, i32 14, i32 14) 148 ret i64 addrspace(1)* %null.relocated 149 150exceptional_return: 151 %landing_pad = landingpad token 152 cleanup 153 %null.relocated2 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 13, i32 13) 154 %undef.relocated2 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 14, i32 14) 155 ret i64 addrspace(1)* %null.relocated2 156} 157 158define i64 addrspace(1)* @test_alloca_and_const(i64 addrspace(1)* %val1) 159 gc "statepoint-example" personality i32 ()* @"personality_function" { 160; CHECK-LABEL: test_alloca_and_const: 161entry: 162 %a = alloca i32 163 %aa = addrspacecast i32* %a to i32 addrspace(1)* 164 %c = inttoptr i64 15 to i64 addrspace(1)* 165 ; CHECK: callq 166 %sp = invoke token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 0, i32 0, void (i64 addrspace(1)*)* @some_call, i32 1, i32 0, i64 addrspace(1)* %val1, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %aa, i64 addrspace(1)* %c) 167 to label %normal_return unwind label %exceptional_return 168 169normal_return: 170 ; CHECK: leaq 171 ; CHECK-NEXT: popq 172 ; CHECK-NEXT: retq 173 %aa.rel = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %sp, i32 13, i32 13) 174 %aa.converted = bitcast i32 addrspace(1)* %aa.rel to i64 addrspace(1)* 175 ret i64 addrspace(1)* %aa.converted 176 177exceptional_return: 178 ; CHECK: movl $15 179 ; CHECK-NEXT: popq 180 ; CHECK-NEXT: retq 181 %landing_pad = landingpad token 182 cleanup 183 %aa.rel2 = call coldcc i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token %landing_pad, i32 14, i32 14) 184 ret i64 addrspace(1)* %aa.rel2 185} 186 187declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) 188declare token @llvm.experimental.gc.statepoint.p0f_p1i64p1i64f(i64, i32, i64 addrspace(1)* (i64 addrspace(1)*)*, i32, i32, ...) 189 190declare i64 addrspace(1)* @llvm.experimental.gc.relocate.p1i64(token, i32, i32) 191declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) 192declare i64 addrspace(1)* @llvm.experimental.gc.result.p1i64(token) 193