[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / X86 / statepoint-vreg-details.ll
blob6594d90089f5f21b4f718c7b41f5ff68ad9e287f
1 ; This file contains some of the same basic tests as statepoint-vreg.ll, but
2 ; focuses on examining the intermediate representation.  It's separate so that
3 ; the main file is easy to update with update_llc_test_checks.py
5 ; This run is to demonstrate what MIR SSA looks like.
6 ; RUN: llc -max-registers-for-gc-values=4 -stop-after finalize-isel < %s | FileCheck --check-prefix=CHECK-VREG %s
7 ; This run is to demonstrate register allocator work.
8 ; RUN: llc -max-registers-for-gc-values=4 -stop-after virtregrewriter < %s | FileCheck --check-prefix=CHECK-PREG %s
10 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
11 target triple = "x86_64-pc-linux-gnu"
13 declare dso_local i1 @return_i1()
14 declare dso_local void @func()
15 declare dso_local void @consume(i32 addrspace(1)*)
16 declare dso_local void @consume2(i32 addrspace(1)*, i32 addrspace(1)*)
17 declare dso_local void @consume5(i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 addrspace(1)*)
18 declare dso_local void @use1(i32 addrspace(1)*, i8 addrspace(1)*)
19 declare dso_local void @bar(i8 addrspace(1)*, i8 addrspace(1)*)
21 ; test most simple relocate
22 define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
23 ; CHECK-VREG-LABEL: name:            test_relocate
24 ; CHECK-VREG:    %0:gr64 = COPY $rdi
25 ; CHECK-VREG:    %1:gr64 = STATEPOINT 0, 0, 0, @return_i1, 2, 0, 2, 0, 2, 0, 2, 1, %0(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def $al
26 ; CHECK-VREG:    %2:gr8 = COPY $al
27 ; CHECK-VREG:    $rdi = COPY %1
28 ; CHECK-VREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
30 ; CHECK-PREG-LABEL: name:            test_relocate
31 ; CHECK-PREG:    renamable $rbx = COPY $rdi
32 ; CHECK-PREG:    renamable $rbx = STATEPOINT 0, 0, 0, @return_i1, 2, 0, 2, 0, 2, 0, 2, 1, killed renamable $rbx(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def $al
33 ; CHECK-PREG:    renamable $bpl = COPY killed $al
34 ; CHECK-PREG:    $rdi = COPY killed renamable $rbx
35 ; CHECK-PREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
37 entry:
38   %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %a)]
39   %rel1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
40   %res1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
41   call void @consume(i32 addrspace(1)* %rel1)
42   ret i1 %res1
44 ; test pointer variables intermixed with pointer constants
45 define void @test_mixed(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) gc "statepoint-example" {
46 ; CHECK-VREG-LABEL: name:            test_mixed
47 ; CHECK-VREG:    %2:gr64 = COPY $rdx
48 ; CHECK-VREG:    %1:gr64 = COPY $rsi
49 ; CHECK-VREG:    %0:gr64 = COPY $rdi
50 ; CHECK-VREG:    %3:gr64, %4:gr64, %5:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 4, %2(tied-def 0), 2, 0, %1(tied-def 1), %0(tied-def 2), 2, 0, 2, 4, 0, 0, 1, 1, 2, 2, 3, 3, csr_64, implicit-def $rsp, implicit-def $ssp
51 ; CHECK-VREG:    %6:gr32 = MOV32r0 implicit-def dead $eflags
52 ; CHECK-VREG:    %7:gr64 = SUBREG_TO_REG 0, killed %6, %subreg.sub_32bit
53 ; CHECK-VREG:    $rdi = COPY %5
54 ; CHECK-VREG:    $rsi = COPY %7
55 ; CHECK-VREG:    $rdx = COPY %4
56 ; CHECK-VREG:    $rcx = COPY %7
57 ; CHECK-VREG:    $r8 = COPY %3
58 ; CHECK-VREG:    CALL64pcrel32 @consume5, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit $rcx, implicit $r8, implicit-def $rsp, implicit-def $ssp
60 ; CHECK-PREG-LABEL: name:            test_mixed
61 ; CHECK-PREG:    renamable $r14 = COPY $rdx
62 ; CHECK-PREG:    renamable $r15 = COPY $rsi
63 ; CHECK-PREG:    renamable $rbx = COPY $rdi
64 ; CHECK-PREG:    renamable $r14, renamable $r15, renamable $rbx = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 4, killed renamable $r14(tied-def 0), 2, 0, killed renamable $r15(tied-def 1), killed renamable $rbx(tied-def 2), 2, 0, 2, 4, 0, 0, 1, 1, 2, 2, 3, 3, csr_64, implicit-def $rsp, implicit-def $ssp
65 ; CHECK-PREG:    $rdi = COPY killed renamable $rbx
66 ; CHECK-PREG:    dead $esi = MOV32r0 implicit-def dead $eflags, implicit-def $rsi
67 ; CHECK-PREG:    $rdx = COPY killed renamable $r15
68 ; CHECK-PREG:    dead $ecx = MOV32r0 implicit-def dead $eflags, implicit-def $rcx
69 ; CHECK-PREG:    $r8 = COPY killed renamable $r14
70 ; CHECK-PREG:    CALL64pcrel32 @consume5, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit killed $rcx, implicit killed $r8, implicit-def $rsp, implicit-def $ssp
72 entry:
73   %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %a, i32 addrspace(1)* null, i32 addrspace(1)* %b, i32 addrspace(1)* null, i32 addrspace(1)* %c)]
74   %rel1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
75   %rel2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 1, i32 1)
76   %rel3 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 2, i32 2)
77   %rel4 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 3, i32 3)
78   %rel5 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 4, i32 4)
79   call void @consume5(i32 addrspace(1)* %rel1, i32 addrspace(1)* %rel2, i32 addrspace(1)* %rel3, i32 addrspace(1)* %rel4, i32 addrspace(1)* %rel5)
80   ret void
83 ; same as above, but for alloca
84 define i32 addrspace(1)* @test_alloca(i32 addrspace(1)* %ptr) gc "statepoint-example" {
85 ; CHECK-VREG-LABEL: name:            test_alloca
86 ; CHECK-VREG:    %0:gr64 = COPY $rdi
87 ; CHECK-VREG:    MOV64mr %stack.0.alloca, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.alloca)
88 ; CHECK-VREG:    %1:gr64 = STATEPOINT 0, 0, 0, @return_i1, 2, 0, 2, 0, 2, 0, 2, 1, %0(tied-def 0), 2, 1, 0, %stack.0.alloca, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def $al :: (volatile load store (s64) on %stack.0.alloca)
89 ; CHECK-VREG:    %2:gr8 = COPY $al
90 ; CHECK-VREG:    %3:gr64 = MOV64rm %stack.0.alloca, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.alloca)
91 ; CHECK-VREG:    $rdi = COPY %1
92 ; CHECK-VREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
94 ; CHECK-PREG-LABEL: name:            test_alloca
95 ; CHECK-PREG:    renamable $rbx = COPY $rdi
96 ; CHECK-PREG:    MOV64mr %stack.0.alloca, 1, $noreg, 0, $noreg, renamable $rbx :: (store (s64) into %ir.alloca)
97 ; CHECK-PREG:    renamable $rbx = STATEPOINT 0, 0, 0, @return_i1, 2, 0, 2, 0, 2, 0, 2, 1, killed renamable $rbx(tied-def 0), 2, 1, 0, %stack.0.alloca, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def dead $al :: (volatile load store (s64) on %stack.0.alloca)
98 ; CHECK-PREG:    renamable $r14 = MOV64rm %stack.0.alloca, 1, $noreg, 0, $noreg :: (dereferenceable load (s64) from %ir.alloca)
99 ; CHECK-PREG:    $rdi = COPY killed renamable $rbx
100 ; CHECK-PREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
102 entry:
103   %alloca = alloca i32 addrspace(1)*, align 8
104   store i32 addrspace(1)* %ptr, i32 addrspace(1)** %alloca
105   %safepoint_token = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)** %alloca, i32 addrspace(1)* %ptr)]
106   %rel1 = load i32 addrspace(1)*, i32 addrspace(1)** %alloca
107   %rel2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 1, i32 1)
108   call void @consume(i32 addrspace(1)* %rel2)
109   ret i32 addrspace(1)* %rel1
112 ; test base != derived
113 define void @test_base_derived(i32 addrspace(1)* %base, i32 addrspace(1)* %derived) gc "statepoint-example" {
114 ; CHECK-VREG-LABEL: name:            test_base_derived
115 ; CHECK-VREG:    %1:gr64 = COPY $rsi
116 ; CHECK-VREG:    %0:gr64 = COPY $rdi
117 ; CHECK-VREG:    %2:gr64, %3:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 2, %1(tied-def 0), %0(tied-def 1), 2, 0, 2, 1, 1, 0, csr_64, implicit-def $rsp, implicit-def $ssp
118 ; CHECK-VREG:    $rdi = COPY %2
119 ; CHECK-VREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
121 ; CHECK-PREG-LABEL: name:            test_base_derived
122 ; CHECK-PREG:    renamable $rbx = COPY $rsi
123 ; CHECK-PREG:    renamable $rbx, dead renamable $r14 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 2, killed renamable $rbx(tied-def 0), killed renamable $r14(tied-def 1), 2, 0, 2, 1, 1, 0, csr_64, implicit-def $rsp, implicit-def $ssp
124 ; CHECK-PREG:    $rdi = COPY killed renamable $rbx
125 ; CHECK-PREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
127   %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %base, i32 addrspace(1)* %derived)]
128   %reloc = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 1)
129   call void @consume(i32 addrspace(1)* %reloc)
130   ret void
133 ; deopt GC pointer not present in GC args must be spilled
134 define void @test_deopt_gcpointer(i32 addrspace(1)* %a, i32 addrspace(1)* %b) gc "statepoint-example" {
135 ; CHECK-VREG-LABEL: name:            test_deopt_gcpointer
136 ; CHECK-VREG:    %1:gr64 = COPY $rsi
137 ; CHECK-VREG:    %0:gr64 = COPY $rdi
138 ; CHECK-VREG:    %2:gr64, %3:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 1, %0, 2, 2, %1(tied-def 0), %0(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp
139 ; CHECK-VREG:    $rdi = COPY %2
140 ; CHECK-VREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
141 ; CHECK-VREG:    RET 0
143 ; CHECK-PREG-LABEL: name:            test_deopt_gcpointer
144 ; CHECK-PREG:    renamable $rbx = COPY $rsi
145 ; CHECK-PREG:    renamable $r14 = COPY $rdi
146 ; CHECK-PREG:    renamable $rbx, dead renamable $r14 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 1, killed renamable $r14, 2, 2, killed renamable $rbx(tied-def 0), renamable $r14(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp
147 ; CHECK-PREG:    $rdi = COPY killed renamable $rbx
148 ; CHECK-PREG:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
150   %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 addrspace(1)* %a), "gc-live" (i32 addrspace(1)* %b)]
151   %rel = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
152   call void @consume(i32 addrspace(1)* %rel)
153   ret void
156 ;; Two gc.relocates of the same input, should require only a single spill/fill
157 define void @test_gcrelocate_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-example" {
158 ; CHECK-VREG-LABEL: name:            test_gcrelocate_uniqueing
159 ; CHECK-VREG:    %0:gr64 = COPY $rdi
160 ; CHECK-VREG:    %1:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 2, %0, 2, 4278124286, 2, 1, %0(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
161 ; CHECK-VREG:    $rdi = COPY %1
162 ; CHECK-VREG:    $rsi = COPY %1
163 ; CHECK-VREG:    CALL64pcrel32 @consume2, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
165 ; CHECK-PREG-LABEL: name:            test_gcrelocate_uniqueing
166 ; CHECK-PREG:    renamable $rbx = COPY $rdi
167 ; CHECK-PREG:    renamable $rbx = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 2, killed renamable $rbx, 2, 4278124286, 2, 1, renamable $rbx(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
168 ; CHECK-PREG:    $rdi = COPY renamable $rbx
169 ; CHECK-PREG:    $rsi = COPY killed renamable $rbx
170 ; CHECK-PREG:    CALL64pcrel32 @consume2, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
172   %tok = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 addrspace(1)* %ptr, i32 undef), "gc-live" (i32 addrspace(1)* %ptr, i32 addrspace(1)* %ptr)]
173   %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0)
174   %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 1, i32 1)
175   call void @consume2(i32 addrspace(1)* %a, i32 addrspace(1)* %b)
176   ret void
179 ; Two gc.relocates of a bitcasted pointer should only require a single spill/fill
180 define void @test_gcptr_uniqueing(i32 addrspace(1)* %ptr) gc "statepoint-example" {
181 ; CHECK-VREG-LABEL: name:            test_gcptr_uniqueing
182 ; CHECK-VREG:    %0:gr64 = COPY $rdi
183 ; CHECK-VREG:    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
184 ; CHECK-VREG:    %1:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 2, %0, 2, 4278124286, 2, 1, %0(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
185 ; CHECK-VREG:    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
186 ; CHECK-VREG:    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
187 ; CHECK-VREG:    $rdi = COPY %1
188 ; CHECK-VREG:    $rsi = COPY %1
189 ; CHECK-VREG:    CALL64pcrel32 @use1, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp
191 ; CHECK-PREG-LABEL: name:            test_gcptr_uniqueing
192 ; CHECK-PREG:    renamable $rbx = COPY $rdi
193 ; CHECK-PREG:    renamable $rbx = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 2, killed renamable $rbx, 2, 4278124286, 2, 1, renamable $rbx(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
194 ; CHECK-PREG:    $rdi = COPY renamable $rbx
195 ; CHECK-PREG:    $rsi = COPY killed renamable $rbx
196 ; CHECK-PREG:    CALL64pcrel32 @use1, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
198   %ptr2 = bitcast i32 addrspace(1)* %ptr to i8 addrspace(1)*
199   %tok = tail call token (i64, i32, void ()*, i32, i32, ...)
200       @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 addrspace(1)* %ptr, i32 undef), "gc-live" (i32 addrspace(1)* %ptr, i8 addrspace(1)* %ptr2)]
201   %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %tok, i32 0, i32 0)
202   %b = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %tok, i32 1, i32 1)
203   call void @use1(i32 addrspace(1)* %a, i8 addrspace(1)* %b)
204   ret void
207 define i1 @test_cross_bb(i32 addrspace(1)* %a, i1 %external_cond) gc "statepoint-example" {
208 ; CHECK-VREG-LABEL: name:            test_cross_bb
209 ; CHECK-VREG:  bb.0.entry:
210 ; CHECK-VREG:         %1:gr32 = COPY $esi
211 ; CHECK-VREG-NEXT:    %0:gr64 = COPY $rdi
212 ; CHECK-VREG-NEXT:    %4:gr8 = COPY %1.sub_8bit
213 ; CHECK-VREG-NEXT:    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
214 ; CHECK-VREG-NEXT:    %2:gr64 = STATEPOINT 0, 0, 0, @return_i1, 2, 0, 2, 0, 2, 0, 2, 1, %0(tied-def 0), 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def $al
215 ; CHECK-VREG-NEXT:    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
216 ; CHECK-VREG-NEXT:    %5:gr8 = COPY $al
217 ; CHECK-VREG-NEXT:    %3:gr8 = COPY %5
218 ; CHECK-VREG-NEXT:    TEST8ri killed %4, 1, implicit-def $eflags
219 ; CHECK-VREG-NEXT:    JCC_1 %bb.2, 4, implicit $eflags
220 ; CHECK-VREG-NEXT:    JMP_1 %bb.1
221 ; CHECK-VREG:       bb.1.left:
222 ; CHECK-VREG-NEXT:    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
223 ; CHECK-VREG-NEXT:    $rdi = COPY %2
224 ; CHECK-VREG-NEXT:    CALL64pcrel32 @consume, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
225 ; CHECK-VREG-NEXT:    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
226 ; CHECK-VREG-NEXT:    $al = COPY %3
227 ; CHECK-VREG-NEXT:    RET 0, $al
228 ; CHECK-VREG:       bb.2.right:
229 ; CHECK-VREG-NEXT:    %6:gr8 = MOV8ri 1
230 ; CHECK-VREG-NEXT:    $al = COPY %6
231 ; CHECK-VREG-NEXT:    RET 0, $al
233 entry:
234   %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %a)]
235   br i1 %external_cond, label %left, label %right
237 left:
238   %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
239   %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
240   call void @consume(i32 addrspace(1)* %call1)
241   ret i1 %call2
243 right:
244   ret i1 true
247 ; No need to check post-regalloc output as it is the same
248 define i1 @duplicate_reloc() gc "statepoint-example" {
249 ; CHECK-VREG-LABEL: name:            duplicate_reloc
250 ; CHECK-VREG:  bb.0.entry:
251 ; CHECK-VREG:    STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
252 ; CHECK-VREG:    STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp
253 ; CHECK-VREG:    %0:gr8 = MOV8ri 1
254 ; CHECK-VREG:    $al = COPY %0
255 ; CHECK-VREG:    RET 0, $al
257 entry:
258   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* null, i32 addrspace(1)* null)]
259   %base = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
260   %derived = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 1)
261   %safepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %base, i32 addrspace(1)* %derived)]
262   %base_reloc = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2,  i32 0, i32 0)
263   %derived_reloc = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token2,  i32 0, i32 1)
264   %cmp1 = icmp eq i32 addrspace(1)* %base_reloc, null
265   %cmp2 = icmp eq i32 addrspace(1)* %derived_reloc, null
266   %cmp = and i1 %cmp1, %cmp2
267   ret i1 %cmp
270 ; Vectors cannot go in VRegs
271 ; No need to check post-regalloc output as it is lowered using old scheme
272 define <2 x i8 addrspace(1)*> @test_vector(<2 x i8 addrspace(1)*> %obj) gc "statepoint-example" {
273 ; CHECK-VREG-LABEL: name:            test_vector
274 ; CHECK-VREG:    %0:vr128 = COPY $xmm0
275 ; CHECK-VREG:    MOVAPSmr %stack.0, 1, $noreg, 0, $noreg, %0 :: (store (s128) into %stack.0)
276 ; CHECK-VREG:    STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 1, 1, 16, %stack.0, 0, 2, 0, 2, 1, 0, 0, csr_64, implicit-def $rsp, implicit-def $ssp :: (volatile load store (s128) on %stack.0)
277 ; CHECK-VREG:    %1:vr128 = MOVAPSrm %stack.0, 1, $noreg, 0, $noreg :: (load (s128) from %stack.0)
278 ; CHECK-VREG:    $xmm0 = COPY %1
279 ; CHECK-VREG:    RET 0, $xmm0
281 entry:
282   %safepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x i8 addrspace(1)*> %obj)]
283   %obj.relocated = call coldcc <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token %safepoint_token, i32 0, i32 0) ; (%obj, %obj)
284   ret <2 x i8 addrspace(1)*> %obj.relocated
288 ; test limit on amount of vregs
289 define void @test_limit(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c, i32 addrspace(1)* %d, i32 addrspace(1)*  %e) gc "statepoint-example" {
290 ; CHECK-VREG-LABEL: name:            test_limit
291 ; CHECK-VREG:    %4:gr64 = COPY $r8
292 ; CHECK-VREG:    %3:gr64 = COPY $rcx
293 ; CHECK-VREG:    %2:gr64 = COPY $rdx
294 ; CHECK-VREG:    %1:gr64 = COPY $rsi
295 ; CHECK-VREG:    %0:gr64 = COPY $rdi
296 ; CHECK-VREG:    MOV64mr %stack.0, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %stack.0)
297 ; CHECK-VREG:    %5:gr64, %6:gr64, %7:gr64, %8:gr64 = STATEPOINT 0, 0, 0, @func, 2, 0, 2, 0, 2, 0, 2, 5, %4(tied-def 0), %3(tied-def 1), %2(tied-def 2), %1(tied-def 3), 1, 8, %stack.0, 0, 2, 0, 2, 5, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, csr_64, implicit-def $rsp, implicit-def $ssp :: (volatile load store (s64) on %stack.0)
298 ; CHECK-VREG:    %9:gr64 = MOV64rm %stack.0, 1, $noreg, 0, $noreg :: (load (s64) from %stack.0)
299 ; CHECK-VREG:    $rdi = COPY %9
300 ; CHECK-VREG:    $rsi = COPY %8
301 ; CHECK-VREG:    $rdx = COPY %7
302 ; CHECK-VREG:    $rcx = COPY %6
303 ; CHECK-VREG:    $r8 = COPY %5
304 ; CHECK-VREG:    CALL64pcrel32 @consume5, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit $rdx, implicit $rcx, implicit $r8, implicit-def $rsp, implicit-def $ssp
305 ; CHECK-VREG:    RET 0
306 entry:
307   %safepoint_token = tail call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c, i32 addrspace(1)* %d, i32 addrspace(1)* %e)]
308   %rel1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 0, i32 0)
309   %rel2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 1, i32 1)
310   %rel3 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 2, i32 2)
311   %rel4 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 3, i32 3)
312   %rel5 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 4, i32 4)
313   call void @consume5(i32 addrspace(1)* %rel1, i32 addrspace(1)* %rel2, i32 addrspace(1)* %rel3, i32 addrspace(1)* %rel4, i32 addrspace(1)* %rel5)
314   ret void
317 ; Test that CopyFromReg emitted during ISEL processing of gc.relocate are properly ordered w.r.t. statepoint.
318 define i8 addrspace(1)* @test_isel_sched(i8 addrspace(1)* %0, i8 addrspace(1)* %1, i32 %2) gc "statepoint-example" {
319 ;CHECK-VREG-LABEL: name:            test_isel_sched
320 ;CHECK-VREG:  bb.0.entry:
321 ;CHECK-VREG:        %2:gr32 = COPY $edx
322 ;CHECK-VREG:        %1:gr64 = COPY $rsi
323 ;CHECK-VREG:        %0:gr64 = COPY $rdi
324 ;CHECK-VREG:        TEST32rr %2, %2, implicit-def $eflags
325 ;CHECK-VREG:        %5:gr64 = CMOV64rr %1, %0, 4, implicit $eflags
326 ;CHECK-VREG:        %6:gr32 = MOV32r0 implicit-def dead $eflags
327 ;CHECK-VREG:        %7:gr64 = SUBREG_TO_REG 0, killed %6, %subreg.sub_32bit
328 ;CHECK-VREG:        $rdi = COPY %7
329 ;CHECK-VREG:        $rsi = COPY %5
330 ;CHECK-VREG:        %3:gr64, %4:gr64 = STATEPOINT 10, 0, 2, @bar, $rdi, $rsi, 2, 0, 2, 0, 2, 0, 2, 2, %1(tied-def 0), %0(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp
331 ;CHECK-VREG:        TEST32rr %2, %2, implicit-def $eflags
332 ;CHECK-VREG:        %8:gr64 = CMOV64rr %3, %4, 4, implicit $eflags
333 ;CHECK-VREG:        $rax = COPY %8
334 ;CHECK-VREG:        RET 0, $rax
335 entry:
336   %cmp = icmp eq i32 %2, 0
337   %ptr = select i1 %cmp, i8 addrspace(1)* %0, i8 addrspace(1)* %1
338   %token = call token (i64, i32, void (i8 addrspace(1)*, i8 addrspace(1)*)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidp1i8p1i8f(i64 10, i32 0, void (i8 addrspace(1)*, i8 addrspace(1)*)* @bar, i32 2, i32 0, i8 addrspace(1)* null, i8 addrspace(1)* %ptr, i32 0, i32 0) [ "deopt"(), "gc-live"(i8 addrspace(1)* %0, i8 addrspace(1)* %1) ]
339   %rel0 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 0, i32 0)
340   %rel1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 1, i32 1)
341   %res = select i1 %cmp, i8 addrspace(1)* %rel0, i8 addrspace(1)* %rel1
342   ret i8 addrspace(1)* %res
345 declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
346 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
347 declare dso_local i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
348 declare dso_local i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32, i32)
349 declare <2 x i8 addrspace(1)*> @llvm.experimental.gc.relocate.v2p1i8(token, i32, i32)
350 declare dso_local i1 @llvm.experimental.gc.result.i1(token)
351 declare token @llvm.experimental.gc.statepoint.p0f_isVoidp1i8p1i8f(i64 immarg, i32 immarg, void (i8 addrspace(1)*, i8 addrspace(1)*)*, i32 immarg, i32 immarg, ...)