1c6ec563fSPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2cee313d2SEric Christopher; RUN: opt < %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
3cee313d2SEric Christopher; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
4cee313d2SEric Christopher
5cee313d2SEric Christopherdeclare i64 addrspace(1)* @generate_obj() "gc-leaf-function"
6cee313d2SEric Christopher
7cee313d2SEric Christopherdeclare void @use_obj(i64 addrspace(1)*) "gc-leaf-function"
8cee313d2SEric Christopher
9c6ec563fSPhilip Reames; The rewriting needs to make %obj loop variant by inserting a phi
10c6ec563fSPhilip Reames; of the original value and it's relocation.
11c6ec563fSPhilip Reamesdefine void @test() gc "statepoint-example" {
12c6ec563fSPhilip Reames; CHECK-LABEL: @test(
13c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
14c6ec563fSPhilip Reames; CHECK-NEXT:    [[OBJ:%.*]] = call i64 addrspace(1)* @generate_obj()
15c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
16c6ec563fSPhilip Reames; CHECK:       loop:
17c6ec563fSPhilip Reames; CHECK-NEXT:    [[DOT0:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[ENTRY:%.*]] ], [ [[OBJ_RELOCATED_CASTED:%.*]], [[LOOP]] ]
18c6ec563fSPhilip Reames; CHECK-NEXT:    call void @use_obj(i64 addrspace(1)* [[DOT0]])
19*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @do_safepoint, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[DOT0]]) ]
20c6ec563fSPhilip Reames; CHECK-NEXT:    [[OBJ_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
21c6ec563fSPhilip Reames; CHECK-NEXT:    [[OBJ_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[OBJ_RELOCATED]] to i64 addrspace(1)*
22c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
23c6ec563fSPhilip Reames;
24cee313d2SEric Christopherentry:
25cee313d2SEric Christopher  %obj = call i64 addrspace(1)* @generate_obj()
26cee313d2SEric Christopher  br label %loop
27cee313d2SEric Christopher
28c6ec563fSPhilip Reamesloop:
29cee313d2SEric Christopher  call void @use_obj(i64 addrspace(1)* %obj)
30cee313d2SEric Christopher  call void @do_safepoint() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
31cee313d2SEric Christopher  br label %loop
32cee313d2SEric Christopher}
33cee313d2SEric Christopher
34cee313d2SEric Christopherdeclare void @do_safepoint()
35cee313d2SEric Christopher
36cee313d2SEric Christopherdeclare void @parse_point(i64 addrspace(1)*)
37cee313d2SEric Christopher
38cee313d2SEric Christopherdefine i64 addrspace(1)* @test1(i32 %caller, i8 addrspace(1)* %a, i8 addrspace(1)* %b, i32 %unknown) gc "statepoint-example" {
39c6ec563fSPhilip Reames; CHECK-LABEL: @test1(
40c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
41c6ec563fSPhilip Reames; CHECK-NEXT:    br i1 undef, label [[LEFT:%.*]], label [[RIGHT:%.*]]
42c6ec563fSPhilip Reames; CHECK:       left:
43c6ec563fSPhilip Reames; CHECK-NEXT:    [[A_CAST:%.*]] = bitcast i8 addrspace(1)* [[A:%.*]] to i64 addrspace(1)*
44c6ec563fSPhilip Reames; CHECK-NEXT:    switch i32 [[UNKNOWN:%.*]], label [[RIGHT]] [
45c6ec563fSPhilip Reames; CHECK-NEXT:    i32 0, label [[MERGE:%.*]]
46c6ec563fSPhilip Reames; CHECK-NEXT:    i32 1, label [[MERGE]]
47c6ec563fSPhilip Reames; CHECK-NEXT:    i32 5, label [[MERGE]]
48c6ec563fSPhilip Reames; CHECK-NEXT:    ]
49c6ec563fSPhilip Reames; CHECK:       right:
50c6ec563fSPhilip Reames; CHECK-NEXT:    [[B_CAST:%.*]] = bitcast i8 addrspace(1)* [[B:%.*]] to i64 addrspace(1)*
51c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[MERGE]]
52c6ec563fSPhilip Reames; CHECK:       merge:
53c6ec563fSPhilip Reames; CHECK-NEXT:    [[VALUE:%.*]] = phi i64 addrspace(1)* [ [[A_CAST]], [[LEFT]] ], [ [[A_CAST]], [[LEFT]] ], [ [[A_CAST]], [[LEFT]] ], [ [[B_CAST]], [[RIGHT]] ]
54*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void (i64 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i64f(i64 2882400000, i32 0, void (i64 addrspace(1)*)* elementtype(void (i64 addrspace(1)*)) @parse_point, i32 1, i32 0, i64 addrspace(1)* [[VALUE]], i32 0, i32 0) [ "deopt"(i32 0, i32 0, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[VALUE]]) ]
555cabf472SPhilip Reames; CHECK-NEXT:    [[VALUE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
56c6ec563fSPhilip Reames; CHECK-NEXT:    [[VALUE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[VALUE_RELOCATED]] to i64 addrspace(1)*
57c6ec563fSPhilip Reames; CHECK-NEXT:    ret i64 addrspace(1)* [[VALUE_RELOCATED_CASTED]]
58c6ec563fSPhilip Reames;
59cee313d2SEric Christopherentry:
60cee313d2SEric Christopher  br i1 undef, label %left, label %right
61cee313d2SEric Christopher
62c6ec563fSPhilip Reamesleft:
63cee313d2SEric Christopher; Our safepoint placement pass calls removeUnreachableBlocks, which does a bunch
64cee313d2SEric Christopher; of simplifications to branch instructions.  This bug is visible only when
65cee313d2SEric Christopher; there are multiple branches into the same block from the same predecessor, and
66cee313d2SEric Christopher; the following ceremony is to make that artefact survive a call to
67cee313d2SEric Christopher; removeUnreachableBlocks.  As an example, "br i1 undef, label %merge, label %merge"
68cee313d2SEric Christopher; will get simplified to "br label %merge" by removeUnreachableBlocks.
69cee313d2SEric Christopher  %a.cast = bitcast i8 addrspace(1)* %a to i64 addrspace(1)*
70cee313d2SEric Christopher  switch i32 %unknown, label %right [
71cee313d2SEric Christopher  i32 0, label %merge
72cee313d2SEric Christopher  i32 1, label %merge
73cee313d2SEric Christopher  i32 5, label %merge
74cee313d2SEric Christopher  i32 3, label %right
75cee313d2SEric Christopher  ]
76cee313d2SEric Christopher
77c6ec563fSPhilip Reamesright:
78cee313d2SEric Christopher  %b.cast = bitcast i8 addrspace(1)* %b to i64 addrspace(1)*
79cee313d2SEric Christopher  br label %merge
80cee313d2SEric Christopher
81c6ec563fSPhilip Reamesmerge:
82cee313d2SEric Christopher  %value = phi i64 addrspace(1)* [ %a.cast, %left ], [ %a.cast, %left ], [ %a.cast, %left ], [ %b.cast, %right ]
83cee313d2SEric Christopher  call void @parse_point(i64 addrspace(1)* %value) [ "deopt"(i32 0, i32 0, i32 0, i32 0, i32 0) ]
84cee313d2SEric Christopher  ret i64 addrspace(1)* %value
85cee313d2SEric Christopher}
86cee313d2SEric Christopher
87cee313d2SEric Christopher;; The purpose of this test is to ensure that when two live values share a
88cee313d2SEric Christopher;;  base defining value with inherent conflicts, we end up with a *single*
89cee313d2SEric Christopher;;  base phi/select per such node.  This is testing an optimization, not a
90cee313d2SEric Christopher;;  fundemental correctness criteria
91cee313d2SEric Christopherdefine void @test2(i1 %cnd, i64 addrspace(1)* %base_obj, i64 addrspace(1)* %base_arg2) gc "statepoint-example" {
92c6ec563fSPhilip Reames; CHECK-LABEL: @test2(
93c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
94c6ec563fSPhilip Reames; CHECK-NEXT:    [[OBJ:%.*]] = getelementptr i64, i64 addrspace(1)* [[BASE_OBJ:%.*]], i32 1
95c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
96c6ec563fSPhilip Reames; CHECK:       loop:
97c6ec563fSPhilip Reames; CHECK-NEXT:    [[DOT0:%.*]] = phi i64 addrspace(1)* [ [[BASE_ARG2:%.*]], [[ENTRY:%.*]] ], [ [[BASE_ARG2_RELOCATED_CASTED:%.*]], [[LOOP]] ]
98c6ec563fSPhilip Reames; CHECK-NEXT:    [[CURRENT_BASE:%.*]] = phi i64 addrspace(1)* [ [[BASE_OBJ]], [[ENTRY]] ], [ [[NEXT_BASE_RELOCATED_CASTED:%.*]], [[LOOP]] ], !is_base_value !0
99c6ec563fSPhilip Reames; CHECK-NEXT:    [[CURRENT:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[ENTRY]] ], [ [[NEXT_RELOCATED_CASTED:%.*]], [[LOOP]] ]
100c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA:%.*]] = phi i64 addrspace(1)* [ [[OBJ]], [[ENTRY]] ], [ [[EXTRA2_RELOCATED_CASTED:%.*]], [[LOOP]] ]
101c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXTA:%.*]] = getelementptr i64, i64 addrspace(1)* [[CURRENT]], i32 1
102c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT_BASE:%.*]] = select i1 [[CND:%.*]], i64 addrspace(1)* [[CURRENT_BASE]], i64 addrspace(1)* [[DOT0]], !is_base_value !0
103c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT:%.*]] = select i1 [[CND]], i64 addrspace(1)* [[NEXTA]], i64 addrspace(1)* [[DOT0]]
104c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2_BASE:%.*]] = select i1 [[CND]], i64 addrspace(1)* [[CURRENT_BASE]], i64 addrspace(1)* [[DOT0]], !is_base_value !0
105c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2:%.*]] = select i1 [[CND]], i64 addrspace(1)* [[NEXTA]], i64 addrspace(1)* [[DOT0]]
106*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[NEXT_BASE]], i64 addrspace(1)* [[NEXT]], i64 addrspace(1)* [[EXTRA2]], i64 addrspace(1)* [[DOT0]], i64 addrspace(1)* [[EXTRA2_BASE]]) ]
107c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
108c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT_BASE_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[NEXT_BASE_RELOCATED]] to i64 addrspace(1)*
109c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 1)
110c6ec563fSPhilip Reames; CHECK-NEXT:    [[NEXT_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[NEXT_RELOCATED]] to i64 addrspace(1)*
111c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 4, i32 2)
112c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[EXTRA2_RELOCATED]] to i64 addrspace(1)*
113c6ec563fSPhilip Reames; CHECK-NEXT:    [[BASE_ARG2_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 3, i32 3)
114c6ec563fSPhilip Reames; CHECK-NEXT:    [[BASE_ARG2_RELOCATED_CASTED]] = bitcast i8 addrspace(1)* [[BASE_ARG2_RELOCATED]] to i64 addrspace(1)*
115c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2_BASE_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 4, i32 4)
116c6ec563fSPhilip Reames; CHECK-NEXT:    [[EXTRA2_BASE_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[EXTRA2_BASE_RELOCATED]] to i64 addrspace(1)*
117c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
118c6ec563fSPhilip Reames;
119cee313d2SEric Christopherentry:
120cee313d2SEric Christopher  %obj = getelementptr i64, i64 addrspace(1)* %base_obj, i32 1
121cee313d2SEric Christopher  br label %loop
122cee313d2SEric Christopher
123cee313d2SEric Christopher; Given the two selects are equivelent, so are their base phis - ideally,
124cee313d2SEric Christopher; we'd have commoned these, but that's a missed optimization, not correctness.
125cee313d2SEric Christopher;; Both 'next' and 'extra2' are live across the backedge safepoint...
126cee313d2SEric Christopher
127c6ec563fSPhilip Reamesloop:
128cee313d2SEric Christopher  %current = phi i64 addrspace(1)* [ %obj, %entry ], [ %next, %loop ]
129cee313d2SEric Christopher  %extra = phi i64 addrspace(1)* [ %obj, %entry ], [ %extra2, %loop ]
130cee313d2SEric Christopher  %nexta = getelementptr i64, i64 addrspace(1)* %current, i32 1
131cee313d2SEric Christopher  %next = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
132cee313d2SEric Christopher  %extra2 = select i1 %cnd, i64 addrspace(1)* %nexta, i64 addrspace(1)* %base_arg2
133cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
134cee313d2SEric Christopher  br label %loop
135cee313d2SEric Christopher}
136cee313d2SEric Christopher
137cee313d2SEric Christopherdefine i64 addrspace(1)* @test3(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" {
138c6ec563fSPhilip Reames; CHECK-LABEL: @test3(
139c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
140c6ec563fSPhilip Reames; CHECK-NEXT:    br i1 [[CND:%.*]], label [[MERGE:%.*]], label [[TAKEN:%.*]]
141c6ec563fSPhilip Reames; CHECK:       taken:
142c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[MERGE]]
143c6ec563fSPhilip Reames; CHECK:       merge:
1445cabf472SPhilip Reames; CHECK-NEXT:    [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[TAKEN]] ]
145*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
1465cabf472SPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
147c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
148c6ec563fSPhilip Reames; CHECK-NEXT:    ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
149c6ec563fSPhilip Reames;
150cee313d2SEric Christopherentry:
151cee313d2SEric Christopher  br i1 %cnd, label %merge, label %taken
152cee313d2SEric Christopher
153c6ec563fSPhilip Reamestaken:
154cee313d2SEric Christopher  br label %merge
155cee313d2SEric Christopher
156c6ec563fSPhilip Reamesmerge:
157cee313d2SEric Christopher  %bdv = phi i64 addrspace(1)* [ %obj, %entry ], [ %obj2, %taken ]
158cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
159cee313d2SEric Christopher  ret i64 addrspace(1)* %bdv
160cee313d2SEric Christopher}
161cee313d2SEric Christopher
162cee313d2SEric Christopherdefine i64 addrspace(1)* @test4(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" {
163c6ec563fSPhilip Reames; CHECK-LABEL: @test4(
164c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
165c6ec563fSPhilip Reames; CHECK-NEXT:    br i1 [[CND:%.*]], label [[MERGE:%.*]], label [[TAKEN:%.*]]
166c6ec563fSPhilip Reames; CHECK:       taken:
167c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[MERGE]]
168c6ec563fSPhilip Reames; CHECK:       merge:
169c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ]], [[TAKEN]] ]
170*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
1715cabf472SPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
172c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
173c6ec563fSPhilip Reames; CHECK-NEXT:    ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
174c6ec563fSPhilip Reames;
175cee313d2SEric Christopherentry:
176cee313d2SEric Christopher  br i1 %cnd, label %merge, label %taken
177cee313d2SEric Christopher
178c6ec563fSPhilip Reamestaken:
179cee313d2SEric Christopher  br label %merge
180cee313d2SEric Christopher
181c6ec563fSPhilip Reamesmerge:
182cee313d2SEric Christopher  %bdv = phi i64 addrspace(1)* [ %obj, %entry ], [ %obj, %taken ]
183cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
184cee313d2SEric Christopher  ret i64 addrspace(1)* %bdv
185cee313d2SEric Christopher}
186cee313d2SEric Christopher
187cee313d2SEric Christopherdefine i64 addrspace(1)* @test5(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" {
188c6ec563fSPhilip Reames; CHECK-LABEL: @test5(
189c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
190c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[MERGE:%.*]]
191c6ec563fSPhilip Reames; CHECK:       merge:
1925cabf472SPhilip Reames; CHECK-NEXT:    [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[MERGE]] ]
193c6ec563fSPhilip Reames; CHECK-NEXT:    br i1 [[CND:%.*]], label [[MERGE]], label [[NEXT:%.*]]
194c6ec563fSPhilip Reames; CHECK:       next:
195*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
1965cabf472SPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
197c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
198c6ec563fSPhilip Reames; CHECK-NEXT:    ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
199c6ec563fSPhilip Reames;
200cee313d2SEric Christopherentry:
201cee313d2SEric Christopher  br label %merge
202cee313d2SEric Christopher
203c6ec563fSPhilip Reamesmerge:
204cee313d2SEric Christopher  %bdv = phi i64 addrspace(1)* [ %obj, %entry ], [ %obj2, %merge ]
205cee313d2SEric Christopher  br i1 %cnd, label %merge, label %next
206cee313d2SEric Christopher
207c6ec563fSPhilip Reamesnext:
208cee313d2SEric Christopher  call void @foo() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
209cee313d2SEric Christopher  ret i64 addrspace(1)* %bdv
210cee313d2SEric Christopher}
211cee313d2SEric Christopher
21299f93dd3SPhilip Reames; We know from the deopt use that %bdv must be a base value, and as
21399f93dd3SPhilip Reames; result can avoid materializing the extra copy of the BDV phi node.
21499f93dd3SPhilip Reames; (Even without a general forward analysis)
21599f93dd3SPhilip Reamesdefine i64 addrspace(1)* @test6(i1 %cnd, i64 addrspace(1)* %obj, i64 addrspace(1)* %obj2) gc "statepoint-example" {
216c6ec563fSPhilip Reames; CHECK-LABEL: @test6(
217c6ec563fSPhilip Reames; CHECK-NEXT:  entry:
218c6ec563fSPhilip Reames; CHECK-NEXT:    br label [[MERGE:%.*]]
219c6ec563fSPhilip Reames; CHECK:       merge:
220c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV:%.*]] = phi i64 addrspace(1)* [ [[OBJ:%.*]], [[ENTRY:%.*]] ], [ [[OBJ2:%.*]], [[MERGE]] ]
221c6ec563fSPhilip Reames; CHECK-NEXT:    br i1 [[CND:%.*]], label [[MERGE]], label [[NEXT:%.*]]
222c6ec563fSPhilip Reames; CHECK:       next:
223*c680eeabSNikita Popov; CHECK-NEXT:    [[STATEPOINT_TOKEN:%.*]] = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) [ "deopt"(i64 addrspace(1)* [[BDV]]), "gc-live"(i64 addrspace(1)* [[BDV]]) ]
224c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED:%.*]] = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token [[STATEPOINT_TOKEN]], i32 0, i32 0)
225c6ec563fSPhilip Reames; CHECK-NEXT:    [[BDV_RELOCATED_CASTED:%.*]] = bitcast i8 addrspace(1)* [[BDV_RELOCATED]] to i64 addrspace(1)*
226c6ec563fSPhilip Reames; CHECK-NEXT:    ret i64 addrspace(1)* [[BDV_RELOCATED_CASTED]]
227c6ec563fSPhilip Reames;
22899f93dd3SPhilip Reamesentry:
22999f93dd3SPhilip Reames  br label %merge
23099f93dd3SPhilip Reames
231c6ec563fSPhilip Reamesmerge:
23299f93dd3SPhilip Reames  %bdv = phi i64 addrspace(1)* [ %obj, %entry ], [ %obj2, %merge ]
23399f93dd3SPhilip Reames  br i1 %cnd, label %merge, label %next
23499f93dd3SPhilip Reames
235c6ec563fSPhilip Reamesnext:
23699f93dd3SPhilip Reames  call void @foo() [ "deopt"(i64 addrspace(1)* %bdv) ]
23799f93dd3SPhilip Reames  ret i64 addrspace(1)* %bdv
23899f93dd3SPhilip Reames}
23999f93dd3SPhilip Reames
240cee313d2SEric Christopherdeclare void @foo()
241