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 -S | FileCheck  %s
4
5; A non-vector relocation for comparison
6define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
7; CHECK-LABEL: test
8; CHECK: gc.statepoint
9; CHECK-NEXT: gc.relocate
10; CHECK-NEXT: ret i64 addrspace(1)* %obj.relocated
11entry:
12  %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0)
13  ret i64 addrspace(1)* %obj
14}
15
16; A base vector from a argument
17define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
18; CHECK-LABEL: test2
19; CHECK: extractelement
20; CHECK-NEXT: extractelement
21; CHECK-NEXT: gc.statepoint
22; CHECK-NEXT: gc.relocate
23; CHECK-NEXT: gc.relocate
24; CHECK-NEXT: insertelement
25; CHECK-NEXT: insertelement
26; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5
27entry:
28  %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0)
29  ret <2 x i64 addrspace(1)*> %obj
30}
31
32; A base vector from a load
33define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
34; CHECK-LABEL: test3
35; CHECK: load
36; CHECK-NEXT: extractelement
37; CHECK-NEXT: extractelement
38; CHECK-NEXT: gc.statepoint
39; CHECK-NEXT: gc.relocate
40; CHECK-NEXT: gc.relocate
41; CHECK-NEXT: insertelement
42; CHECK-NEXT: insertelement
43; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %5
44entry:
45  %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
46  %safepoint_token = call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0)
47  ret <2 x i64 addrspace(1)*> %obj
48}
49
50declare i32 @fake_personality_function()
51
52; When a statepoint is an invoke rather than a call
53define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
54; CHECK-LABEL: test4
55; CHECK: load
56; CHECK-NEXT: extractelement
57; CHECK-NEXT: extractelement
58; CHECK-NEXT: gc.statepoint
59entry:
60  %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
61  invoke i32 (void ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* @do_safepoint, i32 0, i32 0, i32 0)
62          to label %normal_return unwind label %exceptional_return
63
64; CHECK-LABEL: normal_return:
65; CHECK: gc.relocate
66; CHECK-NEXT: gc.relocate
67; CHECK-NEXT: insertelement
68; CHECK-NEXT: insertelement
69; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %6
70normal_return:                                    ; preds = %entry
71  ret <2 x i64 addrspace(1)*> %obj
72
73; CHECK-LABEL: exceptional_return:
74; CHECK: gc.relocate
75; CHECK-NEXT: gc.relocate
76; CHECK-NEXT: insertelement
77; CHECK-NEXT: insertelement
78; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %10
79exceptional_return:                               ; preds = %entry
80  %landing_pad4 = landingpad { i8*, i32 } personality i32 ()* @fake_personality_function
81          cleanup
82  ret <2 x i64 addrspace(1)*> %obj
83}
84
85declare void @do_safepoint()
86
87declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()*, i32, i32, ...)
88