xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/statepoint-call-lowering.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; This file contains a collection of basic tests to ensure we didn't
3*9880d681SAndroid Build Coastguard Worker; screw up normal call lowering when there are no deopt or gc arguments.
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
6*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-pc-linux-gnu"
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker%struct = type { i64, i64 }
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Workerdeclare zeroext i1 @return_i1()
11*9880d681SAndroid Build Coastguard Workerdeclare zeroext i32 @return_i32()
12*9880d681SAndroid Build Coastguard Workerdeclare i32* @return_i32ptr()
13*9880d681SAndroid Build Coastguard Workerdeclare float @return_float()
14*9880d681SAndroid Build Coastguard Workerdeclare %struct @return_struct()
15*9880d681SAndroid Build Coastguard Workerdeclare void @varargf(i32, ...)
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerdefine i1 @test_i1_return() gc "statepoint-example" {
18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i1_return
19*9880d681SAndroid Build Coastguard Worker; This is just checking that a i1 gets lowered normally when there's no extra
20*9880d681SAndroid Build Coastguard Worker; state arguments to the statepoint
21*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
22*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_i1
23*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rcx
24*9880d681SAndroid Build Coastguard Worker; CHECK: retq
25*9880d681SAndroid Build Coastguard Workerentry:
26*9880d681SAndroid Build Coastguard Worker  %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)
27*9880d681SAndroid Build Coastguard Worker  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
28*9880d681SAndroid Build Coastguard Worker  ret i1 %call1
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerdefine i32 @test_i32_return() gc "statepoint-example" {
32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i32_return
33*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
34*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_i32
35*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rcx
36*9880d681SAndroid Build Coastguard Worker; CHECK: retq
37*9880d681SAndroid Build Coastguard Workerentry:
38*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, i32 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i32f(i64 0, i32 0, i32 ()* @return_i32, i32 0, i32 0, i32 0, i32 0)
39*9880d681SAndroid Build Coastguard Worker  %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(token %safepoint_token)
40*9880d681SAndroid Build Coastguard Worker  ret i32 %call1
41*9880d681SAndroid Build Coastguard Worker}
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workerdefine i32* @test_i32ptr_return() gc "statepoint-example" {
44*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i32ptr_return
45*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
46*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_i32ptr
47*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rcx
48*9880d681SAndroid Build Coastguard Worker; CHECK: retq
49*9880d681SAndroid Build Coastguard Workerentry:
50*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, i32* ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_p0i32f(i64 0, i32 0, i32* ()* @return_i32ptr, i32 0, i32 0, i32 0, i32 0)
51*9880d681SAndroid Build Coastguard Worker  %call1 = call i32* @llvm.experimental.gc.result.p0i32(token %safepoint_token)
52*9880d681SAndroid Build Coastguard Worker  ret i32* %call1
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Workerdefine float @test_float_return() gc "statepoint-example" {
56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_float_return
57*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
58*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_float
59*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rax
60*9880d681SAndroid Build Coastguard Worker; CHECK: retq
61*9880d681SAndroid Build Coastguard Workerentry:
62*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, float ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_f32f(i64 0, i32 0, float ()* @return_float, i32 0, i32 0, i32 0, i32 0)
63*9880d681SAndroid Build Coastguard Worker  %call1 = call float @llvm.experimental.gc.result.f32(token %safepoint_token)
64*9880d681SAndroid Build Coastguard Worker  ret float %call1
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workerdefine %struct @test_struct_return() gc "statepoint-example" {
68*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_struct_return
69*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
70*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_struct
71*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rcx
72*9880d681SAndroid Build Coastguard Worker; CHECK: retq
73*9880d681SAndroid Build Coastguard Workerentry:
74*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, %struct ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_structf(i64 0, i32 0, %struct ()* @return_struct, i32 0, i32 0, i32 0, i32 0)
75*9880d681SAndroid Build Coastguard Worker  %call1 = call %struct @llvm.experimental.gc.result.struct(token %safepoint_token)
76*9880d681SAndroid Build Coastguard Worker  ret %struct %call1
77*9880d681SAndroid Build Coastguard Worker}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Workerdefine i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_relocate
81*9880d681SAndroid Build Coastguard Worker; Check that an ununsed relocate has no code-generation impact
82*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
83*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_i1
84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .Ltmp11:
85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: popq %rcx
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq
87*9880d681SAndroid Build Coastguard Workerentry:
88*9880d681SAndroid Build Coastguard Worker  %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, i32 addrspace(1)* %a)
89*9880d681SAndroid Build Coastguard Worker  %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 7, i32 7)
90*9880d681SAndroid Build Coastguard Worker  %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
91*9880d681SAndroid Build Coastguard Worker  ret i1 %call2
92*9880d681SAndroid Build Coastguard Worker}
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Workerdefine void @test_void_vararg() gc "statepoint-example" {
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_void_vararg
96*9880d681SAndroid Build Coastguard Worker; Check a statepoint wrapping a *void* returning vararg function works
97*9880d681SAndroid Build Coastguard Worker; CHECK: callq varargf
98*9880d681SAndroid Build Coastguard Workerentry:
99*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, void (i32, ...)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64 0, i32 0, void (i32, ...)* @varargf, i32 2, i32 0, i32 42, i32 43, i32 0, i32 0)
100*9880d681SAndroid Build Coastguard Worker  ;; if we try to use the result from a statepoint wrapping a
101*9880d681SAndroid Build Coastguard Worker  ;; non-void-returning varargf, we will experience a crash.
102*9880d681SAndroid Build Coastguard Worker  ret void
103*9880d681SAndroid Build Coastguard Worker}
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Workerdefine i1 @test_i1_return_patchable() gc "statepoint-example" {
106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_i1_return_patchable
107*9880d681SAndroid Build Coastguard Worker; A patchable variant of test_i1_return
108*9880d681SAndroid Build Coastguard Worker; CHECK: pushq %rax
109*9880d681SAndroid Build Coastguard Worker; CHECK: nopl
110*9880d681SAndroid Build Coastguard Worker; CHECK: popq %rcx
111*9880d681SAndroid Build Coastguard Worker; CHECK: retq
112*9880d681SAndroid Build Coastguard Workerentry:
113*9880d681SAndroid Build Coastguard Worker  %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 3, i1 ()*null, i32 0, i32 0, i32 0, i32 0)
114*9880d681SAndroid Build Coastguard Worker  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
115*9880d681SAndroid Build Coastguard Worker  ret i1 %call1
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Workerdeclare void @consume(i32 addrspace(1)* %obj)
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerdefine i1 @test_cross_bb(i32 addrspace(1)* %a, i1 %external_cond) gc "statepoint-example" {
121*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_cross_bb
122*9880d681SAndroid Build Coastguard Worker; CHECK: movq
123*9880d681SAndroid Build Coastguard Worker; CHECK: callq return_i1
124*9880d681SAndroid Build Coastguard Worker; CHECK: %left
125*9880d681SAndroid Build Coastguard Worker; CHECK: movq
126*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: callq consume
127*9880d681SAndroid Build Coastguard Worker; CHECK: retq
128*9880d681SAndroid Build Coastguard Workerentry:
129*9880d681SAndroid Build Coastguard Worker  %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, i32 addrspace(1)* %a)
130*9880d681SAndroid Build Coastguard Worker  br i1 %external_cond, label %left, label %right
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerleft:
133*9880d681SAndroid Build Coastguard Worker  %call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token,  i32 7, i32 7)
134*9880d681SAndroid Build Coastguard Worker  %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
135*9880d681SAndroid Build Coastguard Worker  call void @consume(i32 addrspace(1)* %call1)
136*9880d681SAndroid Build Coastguard Worker  ret i1 %call2
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Workerright:
139*9880d681SAndroid Build Coastguard Worker  ret i1 true
140*9880d681SAndroid Build Coastguard Worker}
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
144*9880d681SAndroid Build Coastguard Workerdeclare i1 @llvm.experimental.gc.result.i1(token)
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_i32f(i64, i32, i32 ()*, i32, i32, ...)
147*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.experimental.gc.result.i32(token)
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_p0i32f(i64, i32, i32* ()*, i32, i32, ...)
150*9880d681SAndroid Build Coastguard Workerdeclare i32* @llvm.experimental.gc.result.p0i32(token)
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_f32f(i64, i32, float ()*, i32, i32, ...)
153*9880d681SAndroid Build Coastguard Workerdeclare float @llvm.experimental.gc.result.f32(token)
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_structf(i64, i32, %struct ()*, i32, i32, ...)
156*9880d681SAndroid Build Coastguard Workerdeclare %struct @llvm.experimental.gc.result.struct(token)
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Workerdeclare token @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(i64, i32, void (i32, ...)*, i32, i32, ...)
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workerdeclare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
161