1 ; Test that we can correctly handle vectors of pointers in statepoint
2 ; rewriting. Currently, we scalarize, but that's an implementation detail.
3 ; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S | FileCheck %s
5 ; A non-vector relocation for comparison
7 define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
10 ; CHECK-NEXT: gc.relocate
12 ; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated.casted
13 ; A base vector from a argument
15 call void @do_safepoint() [ "deopt"() ]
16 ret i64 addrspace(1)* %obj
19 define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
21 ; CHECK: extractelement
22 ; CHECK-NEXT: extractelement
23 ; CHECK-NEXT: gc.statepoint
24 ; CHECK-NEXT: gc.relocate
26 ; CHECK-NEXT: gc.relocate
28 ; CHECK-NEXT: insertelement
29 ; CHECK-NEXT: insertelement
30 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
31 ; A base vector from a load
33 call void @do_safepoint() [ "deopt"() ]
34 ret <2 x i64 addrspace(1)*> %obj
37 define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
40 ; CHECK-NEXT: extractelement
41 ; CHECK-NEXT: extractelement
42 ; CHECK-NEXT: gc.statepoint
43 ; CHECK-NEXT: gc.relocate
45 ; CHECK-NEXT: gc.relocate
47 ; CHECK-NEXT: insertelement
48 ; CHECK-NEXT: insertelement
49 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
50 ; When a statepoint is an invoke rather than a call
52 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
53 call void @do_safepoint() [ "deopt"() ]
54 ret <2 x i64 addrspace(1)*> %obj
57 declare i32 @fake_personality_function()
59 define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function {
62 ; CHECK-NEXT: extractelement
63 ; CHECK-NEXT: extractelement
64 ; CHECK-NEXT: gc.statepoint
66 %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
67 invoke void @do_safepoint() [ "deopt"() ]
68 to label %normal_return unwind label %exceptional_return
70 normal_return: ; preds = %entry
71 ; CHECK-LABEL: normal_return:
74 ; CHECK-NEXT: gc.relocate
76 ; CHECK-NEXT: insertelement
77 ; CHECK-NEXT: insertelement
78 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
79 ret <2 x i64 addrspace(1)*> %obj
81 exceptional_return: ; preds = %entry
82 ; CHECK-LABEL: exceptional_return:
85 ; CHECK-NEXT: gc.relocate
87 ; CHECK-NEXT: insertelement
88 ; CHECK-NEXT: insertelement
89 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %13
90 ; Can we handle an insert element with a constant offset? This effectively
91 ; tests both the equal and inequal case since we have to relocate both indices
93 %landing_pad4 = landingpad token
95 ret <2 x i64 addrspace(1)*> %obj
98 define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" {
100 ; CHECK: insertelement
101 ; CHECK-NEXT: extractelement
102 ; CHECK-NEXT: extractelement
103 ; CHECK-NEXT: gc.statepoint
104 ; CHECK-NEXT: gc.relocate
105 ; CHECK-NEXT: bitcast
106 ; CHECK-NEXT: gc.relocate
107 ; CHECK-NEXT: bitcast
108 ; CHECK-NEXT: insertelement
109 ; CHECK-NEXT: insertelement
110 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %7
111 ; A base vector from a load
113 %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
114 call void @do_safepoint() [ "deopt"() ]
115 ret <2 x i64 addrspace(1)*> %vec
118 define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
121 br i1 %cnd, label %taken, label %untaken
123 taken: ; preds = %entry
124 %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
127 untaken: ; preds = %entry
128 %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
131 merge: ; preds = %untaken, %taken
132 ; CHECK-LABEL: merge:
134 ; CHECK-NEXT: extractelement
135 ; CHECK-NEXT: extractelement
136 ; CHECK-NEXT: gc.statepoint
137 ; CHECK-NEXT: gc.relocate
138 ; CHECK-NEXT: bitcast
139 ; CHECK-NEXT: gc.relocate
140 ; CHECK-NEXT: bitcast
141 ; CHECK-NEXT: insertelement
142 ; CHECK-NEXT: insertelement
143 ; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
144 %obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
145 call void @do_safepoint() [ "deopt"() ]
146 ret <2 x i64 addrspace(1)*> %obj
149 declare void @do_safepoint()