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