[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / RewriteStatepointsForGC / liveness-basics.ll
blobe827ff6e6e6a641c7baf6f5e4503fd664b3089d9
1 ; A collection of liveness test cases to ensure we're reporting the
2 ; correct live values at statepoints
3 ; RUN: opt -passes=rewrite-statepoints-for-gc -spp-rematerialization-threshold=0 -S < %s | FileCheck %s
5 ; Tests to make sure we consider %obj live in both the taken and untaken
6 ; predeccessor of merge.
8 define ptr addrspace(1) @test1(i1 %cmp, ptr addrspace(1) %obj) gc "statepoint-example" {
9 ; CHECK-LABEL: @test1
10 entry:
11   br i1 %cmp, label %taken, label %untaken
13 taken:                                            ; preds = %entry
14 ; CHECK-LABEL: taken:
15 ; CHECK-NEXT: gc.statepoint
16 ; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)
17 ; CHECK-NEXT: br label %merge
18   call void @foo() [ "deopt"() ]
19   br label %merge
21 untaken:                                          ; preds = %entry
22 ; CHECK-LABEL: untaken:
23 ; CHECK-NEXT: gc.statepoint
24 ; CHECK-NEXT: %obj.relocated2 = call coldcc ptr addrspace(1)
25 ; CHECK-NEXT: br label %merge
26   call void @foo() [ "deopt"() ]
27   br label %merge
29 merge:                                            ; preds = %untaken, %taken
30 ; CHECK-LABEL: merge:
31 ; CHECK-NEXT: %.0 = phi ptr addrspace(1) [ %obj.relocated, %taken ], [ %obj.relocated2, %untaken ]
32 ; CHECK-NEXT: ret ptr addrspace(1) %.0
33 ; A local kill should not effect liveness in predecessor block
34   ret ptr addrspace(1) %obj
37 define ptr addrspace(1) @test2(i1 %cmp, ptr %loc) gc "statepoint-example" {
38 ; CHECK-LABEL: @test2
39 entry:
40 ; CHECK-LABEL: entry:
41 ; CHECK-NEXT:  gc.statepoint
42 ; CHECK-NEXT:  br
43   call void @foo() [ "deopt"() ]
44   br i1 %cmp, label %taken, label %untaken
46 taken:                                            ; preds = %entry
47 ; CHECK-LABEL: taken:
48 ; CHECK-NEXT:  %obj = load
49 ; CHECK-NEXT:  gc.statepoint
50 ; CHECK-NEXT:  gc.relocate
51 ; CHECK-NEXT:  ret ptr addrspace(1) %obj.relocated
52 ; A local kill should effect values live from a successor phi.  Also, we
53 ; should only propagate liveness from a phi to the appropriate predecessors.
54   %obj = load ptr addrspace(1), ptr %loc
55   call void @foo() [ "deopt"() ]
56   ret ptr addrspace(1) %obj
58 untaken:                                          ; preds = %entry
59   ret ptr addrspace(1) null
62 define ptr addrspace(1) @test3(i1 %cmp, ptr %loc) gc "statepoint-example" {
63 ; CHECK-LABEL: @test3
64 entry:
65   br i1 %cmp, label %taken, label %untaken
67 taken:                                            ; preds = %entry
68 ; CHECK-LABEL: taken:
69 ; CHECK-NEXT: gc.statepoint
70 ; CHECK-NEXT: %obj = load
71 ; CHECK-NEXT: gc.statepoint
72 ; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)
73 ; CHECK-NEXT: br label %merge
74   call void @foo() [ "deopt"() ]
75   %obj = load ptr addrspace(1), ptr %loc
76   call void @foo() [ "deopt"() ]
77   br label %merge
79 untaken:                                          ; preds = %entry
80 ; CHECK-LABEL: taken:
81 ; CHECK-NEXT: gc.statepoint
82 ; CHECK-NEXT: br label %merge
83 ; A base pointer must be live if it is needed at a later statepoint,
84 ; even if the base pointer is otherwise unused.
85   call void @foo() [ "deopt"() ]
86   br label %merge
88 merge:                                            ; preds = %untaken, %taken
89   %phi = phi ptr addrspace(1) [ %obj, %taken ], [ null, %untaken ]
90   ret ptr addrspace(1) %phi
93 define ptr addrspace(1) @test4(i1 %cmp, ptr addrspace(1) %obj) gc "statepoint-example" {
94 ; CHECK-LABEL: @test4
95 entry:
96 ; CHECK-LABEL: entry:
97 ; CHECK-NEXT:  %derived = getelementptr
98 ; CHECK-NEXT:  gc.statepoint
99 ; CHECK-NEXT:  %derived.relocated =
100 ; CHECK-NEXT:  %obj.relocated =
101 ; CHECK-NEXT:  gc.statepoint
102 ; CHECK-NEXT:  %derived.relocated2 =
104 ; Note: It's legal to relocate obj again, but not strictly needed
105 ; CHECK-NEXT:  %obj.relocated3 =
106 ; CHECK-NEXT:  ret ptr addrspace(1) %derived.relocated2
108 ; Make sure that a phi def visited during iteration is considered a kill.
109 ; Also, liveness after base pointer analysis can change based on new uses,
110 ; not just new defs.
111   %derived = getelementptr i64, ptr addrspace(1) %obj, i64 8
112   call void @foo() [ "deopt"() ]
113   call void @foo() [ "deopt"() ]
114   ret ptr addrspace(1) %derived
117 declare void @consume(...) readonly "gc-leaf-function"
119 define ptr addrspace(1) @test5(i1 %cmp, ptr addrspace(1) %obj) gc "statepoint-example" {
120 ; CHECK-LABEL: @test5
121 entry:
122   br i1 %cmp, label %taken, label %untaken
124 taken:                                            ; preds = %entry
125 ; CHECK-LABEL: taken:
126 ; CHECK-NEXT: gc.statepoint
127 ; CHECK-NEXT: %obj.relocated = call coldcc ptr addrspace(1)
128 ; CHECK-NEXT: br label %merge
129   call void @foo() [ "deopt"() ]
130   br label %merge
132 untaken:                                          ; preds = %entry
133 ; CHECK-LABEL: untaken:
134 ; CHECK-NEXT: br label %merge
135   br label %merge
137 merge:                                            ; preds = %untaken, %taken
138 ; CHECK-LABEL: merge:
139 ; CHECK-NEXT: %.0 = phi ptr addrspace(1)
140 ; CHECK-NEXT: %obj2a = phi
141 ; CHECK-NEXT: @consume
142 ; CHECK-NEXT: br label %final
143   %obj2a = phi ptr addrspace(1) [ %obj, %taken ], [ null, %untaken ]
144   call void (...) @consume(ptr addrspace(1) %obj2a)
145   br label %final
147 final:                                            ; preds = %merge
148 ; CHECK-LABEL: final:
149 ; CHECK-NEXT: @consume
150 ; CHECK-NEXT: ret ptr addrspace(1) %.0
151   call void (...) @consume(ptr addrspace(1) %obj2a)
152   ret ptr addrspace(1) %obj
155 declare void @foo()