Skip to content

Commit 06c5119

Browse files
author
Serguei Katkov
committed
[Statepoint lowering] Require spill of deopt value in case its type is not legal
If the type of the deopt operand has an illegal type and we want to use register for it then it needs to be legalized. This is not supported currently by legalizer and it is not actually clear how to legalize this type of values. Instead we just spill such values and use spill slot location in statepoint. Originally tests were created by Philip Reames. Reviewers: reames, dantrushin Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D97541
1 parent d49270b commit 06c5119

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,9 @@ lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops,
618618
};
619619

620620
auto requireSpillSlot = [&](const Value *V) {
621+
if (!Builder.DAG.getTargetLoweringInfo().isTypeLegal(
622+
Builder.getValue(V).getValueType()))
623+
return true;
621624
if (isGCValue(V))
622625
return !LowerAsVReg.count(Builder.getValue(V));
623626
return !(LiveInDeopt || UseRegistersForDeoptValues);
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -O3 < %s | FileCheck %s
3+
4+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5+
target triple = "x86_64-unknown-unknown"
6+
7+
; Check that we don't crash on handling of various types of constants
8+
; (including non-integer constants)
9+
define void @test_legal_constants() gc "statepoint-example" {
10+
; CHECK-LABEL: test_legal_constants:
11+
; CHECK: # %bb.0:
12+
; CHECK-NEXT: pushq %rax
13+
; CHECK-NEXT: .cfi_def_cfa_offset 16
14+
; CHECK-NEXT: callq foo@PLT
15+
; CHECK-NEXT: .Ltmp0:
16+
; CHECK-NEXT: popq %rax
17+
; CHECK-NEXT: .cfi_def_cfa_offset 8
18+
; CHECK-NEXT: retq
19+
%statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 0) #0 [ "deopt" (float 2.0, double 3.0, i8 5, i16 22, i32 8, i64 9, i8 addrspace(1)* null) ]
20+
ret void
21+
}
22+
23+
; Ensure we can allocate and assign values in registers for each type
24+
define void @test_registers(float %v1, double %v2, i8 %v3, i16 %v4, i32 %v5, i64 %v6, i8 addrspace(1)* %v7) gc "statepoint-example" {
25+
; CHECK-LABEL: test_registers:
26+
; CHECK: # %bb.0:
27+
; CHECK-NEXT: pushq %rax
28+
; CHECK-NEXT: .cfi_def_cfa_offset 16
29+
; CHECK-NEXT: movq %r8, (%rsp)
30+
; CHECK-NEXT: callq foo@PLT
31+
; CHECK-NEXT: .Ltmp1:
32+
; CHECK-NEXT: popq %rax
33+
; CHECK-NEXT: .cfi_def_cfa_offset 8
34+
; CHECK-NEXT: retq
35+
%statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 0) #0 [ "deopt" (float %v1, double %v2, i8 %v3, i16 %v4, i32 %v5, i64 %v6, i8 addrspace(1)* %v7) ]
36+
ret void
37+
}
38+
39+
; For constants which definitely *don't* fit in registers, can we still
40+
; encode them in the stackmap?
41+
define void @test_illegal_constants() gc "statepoint-example" {
42+
; CHECK-LABEL: test_illegal_constants:
43+
; CHECK: # %bb.0:
44+
; CHECK-NEXT: subq $248, %rsp
45+
; CHECK-NEXT: .cfi_def_cfa_offset 256
46+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
47+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
48+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
49+
; CHECK-NEXT: movq $144, {{[0-9]+}}(%rsp)
50+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
51+
; CHECK-NEXT: movq $144, {{[0-9]+}}(%rsp)
52+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
53+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
54+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
55+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
56+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
57+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
58+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
59+
; CHECK-NEXT: movq $144, {{[0-9]+}}(%rsp)
60+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
61+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
62+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
63+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
64+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
65+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
66+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
67+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
68+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
69+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
70+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
71+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
72+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
73+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
74+
; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp)
75+
; CHECK-NEXT: movq $144, {{[0-9]+}}(%rsp)
76+
; CHECK-NEXT: callq foo@PLT
77+
; CHECK-NEXT: .Ltmp2:
78+
; CHECK-NEXT: addq $248, %rsp
79+
; CHECK-NEXT: .cfi_def_cfa_offset 8
80+
; CHECK-NEXT: retq
81+
%statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 0) #0 [ "deopt" (i128 144, i256 144, i512 144, i1024 144) ]
82+
ret void
83+
}
84+
85+
; Ensure we don't crash w/a value which can't fit in a
86+
; register, and must be spilled.
87+
define void @test_illegal_values(i128 %v1, i256 %v2, i512 %v3, i1024 %v4) gc "statepoint-example" {
88+
; CHECK-LABEL: test_illegal_values:
89+
; CHECK: # %bb.0:
90+
; CHECK-NEXT: subq $248, %rsp
91+
; CHECK-NEXT: .cfi_def_cfa_offset 256
92+
; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp)
93+
; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp)
94+
; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp)
95+
; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp)
96+
; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp)
97+
; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp)
98+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
99+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
100+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
101+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
102+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
103+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
104+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
105+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
106+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
107+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
108+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
109+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
110+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
111+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
112+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
113+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
114+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
115+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
116+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
117+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
118+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
119+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
120+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
121+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
122+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
123+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
124+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
125+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
126+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
127+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
128+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
129+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
130+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
131+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
132+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
133+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
134+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
135+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
136+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
137+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
138+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
139+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
140+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
141+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
142+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
143+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
144+
; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
145+
; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp)
146+
; CHECK-NEXT: callq foo@PLT
147+
; CHECK-NEXT: .Ltmp3:
148+
; CHECK-NEXT: addq $248, %rsp
149+
; CHECK-NEXT: .cfi_def_cfa_offset 8
150+
; CHECK-NEXT: retq
151+
%statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @foo, i32 0, i32 2, i32 0, i32 0) #0 [ "deopt" (i128 %v1, i256 %v2, i512 %v3, i1024 %v4) ]
152+
ret void
153+
}
154+
155+
156+
;; TODO: Add a test for illegal register values (i.e. spilling). A
157+
;; trivial one currently crashes.
158+
159+
declare void @foo()
160+
161+
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 , i32 , void ()*, i32 , i32 , ...)
162+
163+
attributes #0 = { "deopt-lowering"="live-in" }

0 commit comments

Comments
 (0)