1; RUN: opt %s -rewrite-statepoints-for-gc -S | FileCheck %s 2 3define i64 addrspace(1)* @test(<2 x i64 addrspace(1)*> %vec, i32 %idx) gc "statepoint-example" { 4; CHECK-LABEL: @test 5; CHECK: extractelement 6; CHECK: extractelement 7; CHECK: statepoint 8; CHECK: gc.relocate 9; CHECK-DAG: ; (%base_ee, %base_ee) 10; CHECK: gc.relocate 11; CHECK-DAG: ; (%base_ee, %obj) 12; Note that the second extractelement is actually redundant here. A correct output would 13; be to reuse the existing obj as a base since it is actually a base pointer. 14entry: 15 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx 16 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 17 18 ret i64 addrspace(1)* %obj 19} 20 21define i64 addrspace(1)* @test2(<2 x i64 addrspace(1)*>* %ptr, i1 %cnd, i32 %idx1, i32 %idx2) 22 gc "statepoint-example" { 23; CHECK-LABEL: test2 24entry: 25 br i1 %cnd, label %taken, label %untaken 26taken: 27 %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 28 br label %merge 29untaken: 30 %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 31 br label %merge 32merge: 33 %vec = phi <2 x i64 addrspace(1)*> [%obja, %taken], [%objb, %untaken] 34 br i1 %cnd, label %taken2, label %untaken2 35taken2: 36 %obj0 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx1 37 br label %merge2 38untaken2: 39 %obj1 = extractelement <2 x i64 addrspace(1)*> %vec, i32 %idx2 40 br label %merge2 41merge2: 42; CHECK-LABEL: merge2: 43; CHECK: %obj.base = phi i64 addrspace(1)* 44; CHECK: %obj = phi i64 addrspace(1)* 45; CHECK: statepoint 46; CHECK: gc.relocate 47; CHECK-DAG: ; (%obj.base, %obj) 48; CHECK: gc.relocate 49; CHECK-DAG: ; (%obj.base, %obj.base) 50 %obj = phi i64 addrspace(1)* [%obj0, %taken2], [%obj1, %untaken2] 51 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 52 ret i64 addrspace(1)* %obj 53} 54 55define i64 addrspace(1)* @test3(i64 addrspace(1)* %ptr) 56 gc "statepoint-example" { 57; CHECK-LABEL: test3 58entry: 59 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %ptr, i32 0 60 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 61; CHECK: insertelement 62; CHECK: extractelement 63; CHECK: statepoint 64; CHECK: gc.relocate 65; CHECK-DAG: ; (%ptr, %obj) 66 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 67 ret i64 addrspace(1)* %obj 68} 69define i64 addrspace(1)* @test4(i64 addrspace(1)* %ptr) 70 gc "statepoint-example" { 71; CHECK-LABEL: test4 72entry: 73 %derived = getelementptr i64, i64 addrspace(1)* %ptr, i64 16 74 %veca = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %derived, i32 0 75 %vec = insertelement <2 x i64 addrspace(1)*> %veca, i64 addrspace(1)* %ptr, i32 1 76 %obj = extractelement <2 x i64 addrspace(1)*> %vec, i32 0 77; CHECK: statepoint 78; CHECK: gc.relocate 79; CHECK-DAG: ; (%ptr, %obj) 80; CHECK: gc.relocate 81; CHECK-DAG: ; (%ptr, %ptr) 82 %safepoint_token = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 83 ret i64 addrspace(1)* %obj 84} 85 86declare void @do_safepoint() 87 88declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) 89