1; Test that we can correctly handle vectors of pointers in statepoint 2; rewriting. 3; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s 4; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s 5 6; A non-vector relocation for comparison 7define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" { 8; CHECK-LABEL: test 9; CHECK: gc.statepoint 10; CHECK-NEXT: gc.relocate 11; CHECK-NEXT: bitcast 12; CHECK-NEXT: ret i64 addrspace(1)* 13; A base vector from a argument 14entry: 15 call void @do_safepoint() [ "deopt"() ] 16 ret i64 addrspace(1)* %obj 17} 18 19; A vector argument 20define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" { 21; CHECK-LABEL: test2 22; CHECK-NEXT: gc.statepoint 23; CHECK-NEXT: gc.relocate 24; CHECK-NEXT: bitcast 25; CHECK-NEXT: ret <2 x i64 addrspace(1)*> 26 call void @do_safepoint() [ "deopt"() ] 27 ret <2 x i64 addrspace(1)*> %obj 28} 29 30; A load 31define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" { 32; CHECK-LABEL: test3 33; CHECK: load 34; CHECK-NEXT: gc.statepoint 35; CHECK-NEXT: gc.relocate 36; CHECK-NEXT: bitcast 37; CHECK-NEXT: ret <2 x i64 addrspace(1)*> 38entry: 39 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 40 call void @do_safepoint() [ "deopt"() ] 41 ret <2 x i64 addrspace(1)*> %obj 42} 43 44declare i32 @fake_personality_function() 45 46; When a statepoint is an invoke rather than a call 47define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function { 48; CHECK-LABEL: test4 49; CHECK: load 50; CHECK-NEXT: gc.statepoint 51entry: 52 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 53 invoke void @do_safepoint() [ "deopt"() ] 54 to label %normal_return unwind label %exceptional_return 55 56normal_return: ; preds = %entry 57; CHECK-LABEL: normal_return: 58; CHECK: gc.relocate 59; CHECK-NEXT: bitcast 60; CHECK-NEXT: ret <2 x i64 addrspace(1)*> 61 ret <2 x i64 addrspace(1)*> %obj 62 63exceptional_return: ; preds = %entry 64; CHECK-LABEL: exceptional_return: 65; CHECK: gc.relocate 66; CHECK-NEXT: bitcast 67; CHECK-NEXT: ret <2 x i64 addrspace(1)*> 68 %landing_pad4 = landingpad token 69 cleanup 70 ret <2 x i64 addrspace(1)*> %obj 71} 72 73; A newly created vector 74define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" { 75; CHECK-LABEL: test5 76; CHECK: insertelement 77; CHECK-NEXT: insertelement 78; CHECK-NEXT: gc.statepoint 79; CHECK-NEXT: gc.relocate 80; CHECK-NEXT: bitcast 81; CHECK-NEXT: gc.relocate 82; CHECK-NEXT: bitcast 83; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %vec.relocated.casted 84entry: 85 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0 86 call void @do_safepoint() [ "deopt"() ] 87 ret <2 x i64 addrspace(1)*> %vec 88} 89 90; A merge point 91define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" { 92; CHECK-LABEL: test6 93entry: 94 br i1 %cnd, label %taken, label %untaken 95 96taken: ; preds = %entry 97 %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 98 br label %merge 99 100untaken: ; preds = %entry 101 %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr 102 br label %merge 103 104merge: ; preds = %untaken, %taken 105; CHECK-LABEL: merge: 106; CHECK-NEXT: = phi 107; CHECK-NEXT: = phi 108; CHECK-NEXT: gc.statepoint 109; CHECK-NEXT: gc.relocate 110; CHECK-NEXT: bitcast 111; CHECK-NEXT: gc.relocate 112; CHECK-NEXT: bitcast 113; CHECK-NEXT: ret <2 x i64 addrspace(1)*> 114 %obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ] 115 call void @do_safepoint() [ "deopt"() ] 116 ret <2 x i64 addrspace(1)*> %obj 117} 118 119declare void @do_safepoint() 120