mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
3ad7648361
Extend FixupStatepointCallerSaved pass with ability to spill statepoint GC pointer arguments (optionally allowing them on CSRs). Special handling is required for invoke statepoints, because at MI level single landing pad may be shared by multiple statepoints, so we must ensure we spill landing pad's live-ins into the same stack slots. Full statepoint refactoring change set is available at D81603. Reviewed By: skatkov Differential Revision: https://reviews.llvm.org/D81647
189 lines
8.3 KiB
YAML
189 lines
8.3 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -o - %s -fixup-allow-gcptr-in-csr=false -run-pass fixup-statepoint-caller-saved | FileCheck %s
|
|
|
|
# NOTE: MIR in this test was hand edited to have two statepoints share single landing pad.
|
|
# This is forbidden in IR, but is allowed in MIR. I just was unable to reproduce conditions
|
|
# under which landing pad merge happens. So I did it manually.
|
|
#
|
|
--- |
|
|
; ModuleID = 'statepoint-fixup-shared-ehpad.ll'
|
|
source_filename = "statepoint-fixup-shared-ehpad.ll"
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-pc-linux-gnu"
|
|
|
|
declare void @foo()
|
|
|
|
declare void @bar()
|
|
|
|
declare i32 @personality_function()
|
|
|
|
define i8 addrspace(1)* @test_one(i32 %a, i8 addrspace(1)* %p, i8 addrspace(1)* %q) gc "statepoint-example" personality i32 ()* @personality_function {
|
|
entry:
|
|
%cmp = icmp eq i32 %a, 0
|
|
br i1 %cmp, label %zero, label %nonzero
|
|
|
|
zero: ; preds = %entry
|
|
%token = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* %p, i8 addrspace(1)* %q) ]
|
|
to label %normal_dest_a unwind label %exceptional_return_a
|
|
|
|
nonzero: ; preds = %entry
|
|
%token2 = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i8 addrspace(1)* %p, i8 addrspace(1)* %q) ]
|
|
to label %normal_dest_b unwind label %exceptional_return_b
|
|
|
|
normal_dest_a: ; preds = %zero
|
|
%p2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token, i32 0, i32 0) ; (%p, %p)
|
|
ret i8 addrspace(1)* %p2
|
|
|
|
exceptional_return_a: ; preds = %zero
|
|
%landing_pad = landingpad token
|
|
cleanup
|
|
%q2 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad, i32 1, i32 1) ; (%q, %q)
|
|
ret i8 addrspace(1)* %q2
|
|
|
|
normal_dest_b: ; preds = %nonzero
|
|
%p3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %token2, i32 0, i32 0) ; (%p, %p)
|
|
ret i8 addrspace(1)* %p3
|
|
|
|
exceptional_return_b: ; preds = %nonzero
|
|
%landing_pad2 = landingpad token
|
|
cleanup
|
|
%q3 = call i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %landing_pad2, i32 1, i32 1) ; (%q, %q)
|
|
ret i8 addrspace(1)* %q3
|
|
}
|
|
|
|
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 immarg, i32 immarg, void ()*, i32 immarg, i32 immarg, ...)
|
|
|
|
; Function Attrs: nounwind readonly
|
|
declare i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token, i32 immarg, i32 immarg) #0
|
|
|
|
attributes #0 = { nounwind readonly }
|
|
attributes #1 = { nounwind }
|
|
|
|
...
|
|
---
|
|
name: test_one
|
|
alignment: 16
|
|
exposesReturnsTwice: false
|
|
legalized: false
|
|
regBankSelected: false
|
|
selected: false
|
|
failedISel: false
|
|
tracksRegLiveness: true
|
|
hasWinCFI: false
|
|
registers: []
|
|
liveins:
|
|
- { reg: '$edi', virtual-reg: '' }
|
|
- { reg: '$rsi', virtual-reg: '' }
|
|
- { reg: '$rdx', virtual-reg: '' }
|
|
frameInfo:
|
|
isFrameAddressTaken: false
|
|
isReturnAddressTaken: false
|
|
hasStackMap: false
|
|
hasPatchPoint: false
|
|
stackSize: 0
|
|
offsetAdjustment: 0
|
|
maxAlignment: 1
|
|
adjustsStack: false
|
|
hasCalls: true
|
|
stackProtector: ''
|
|
maxCallFrameSize: 4294967295
|
|
cvBytesOfCalleeSavedRegisters: 0
|
|
hasOpaqueSPAdjustment: false
|
|
hasVAStart: false
|
|
hasMustTailInVarArgFunc: false
|
|
localFrameSize: 0
|
|
savePoint: ''
|
|
restorePoint: ''
|
|
fixedStack: []
|
|
stack: []
|
|
callSites: []
|
|
constants: []
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
; CHECK-LABEL: name: test_one
|
|
; CHECK: bb.1:
|
|
; CHECK: successors: %bb.3(0x40000000), %bb.4(0x40000000)
|
|
; CHECK: liveins: $rbx, $r14
|
|
; CHECK: EH_LABEL <mcsymbol Ltmp0>
|
|
; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
; CHECK: MOV64mr [[STACK0:%stack.[0-9]+]], 1, $noreg, 0, $noreg, killed $rbx :: (store 8 into [[STACK0]])
|
|
; CHECK: MOV64mr [[STACK1:%stack.[0-9]+]], 1, $noreg, 0, $noreg, killed $r14 :: (store 8 into [[STACK1]])
|
|
; CHECK: STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, 1, 8, [[STACK0]], 0, 1, 8, [[STACK0]], 0, 1, 8, [[STACK1]], 0, 1, 8, [[STACK1]], 0, csr_64, implicit-def $rsp, implicit-def $ssp :: (load store 8 on [[STACK0]]), (load store 8 on [[STACK1]])
|
|
; CHECK-DAG: $rbx = MOV64rm [[STACK0]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK0]])
|
|
; CHECK-DAG: $r14 = MOV64rm [[STACK1]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK1]])
|
|
; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
; CHECK: EH_LABEL <mcsymbol Ltmp1>
|
|
; CHECK: JMP_1 %bb.3
|
|
; CHECK: bb.2:
|
|
; CHECK: successors: %bb.5(0x40000000), %bb.4(0x40000000)
|
|
; CHECK: liveins: $rbx, $r14
|
|
; CHECK: EH_LABEL <mcsymbol Ltmp2>
|
|
; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
; CHECK-DAG: MOV64mr [[STACK0]], 1, $noreg, 0, $noreg, killed $rbx :: (store 8 into [[STACK0]])
|
|
; CHECK-DAG: MOV64mr [[STACK1]], 1, $noreg, 0, $noreg, killed $r14 :: (store 8 into [[STACK1]])
|
|
; CHECK: STATEPOINT 0, 0, 0, @bar, 2, 0, 2, 0, 2, 0, 1, 8, [[STACK0]], 0, 1, 8, [[STACK0]], 0, 1, 8, [[STACK1]], 0, 1, 8, [[STACK1]], 0, csr_64, implicit-def $rsp, implicit-def $ssp :: (load store 8 on [[STACK0]]), (load store 8 on [[STACK1]])
|
|
; CHECK-DAG: $rbx = MOV64rm [[STACK0]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK0]])
|
|
; CHECK-DAG: $r14 = MOV64rm [[STACK1]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK1]])
|
|
; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
; CHECK: EH_LABEL <mcsymbol Ltmp3>
|
|
; CHECK: JMP_1 %bb.5
|
|
; CHECK: bb.4 (landing-pad):
|
|
; CHECK: liveins: $rax, $rdx, $r14
|
|
; CHECK: EH_LABEL <mcsymbol Ltmp4>
|
|
; CHECK-DAG: $rbx = MOV64rm [[STACK0]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK0]])
|
|
; CHECK-DAG: $r14 = MOV64rm [[STACK1]], 1, $noreg, 0, $noreg :: (load 8 from [[STACK1]])
|
|
; CHECK: $rax = COPY killed renamable $r14
|
|
; CHECK: RET 0, $rax
|
|
bb.0:
|
|
successors: %bb.1, %bb.2
|
|
liveins: $edi, $rdx, $rsi
|
|
|
|
renamable $r14 = COPY $rdx
|
|
renamable $rbx = COPY $rsi
|
|
TEST32rr killed renamable $edi, renamable $edi, implicit-def $eflags
|
|
JCC_1 %bb.2, 5, implicit killed $eflags
|
|
JMP_1 %bb.1
|
|
|
|
bb.1:
|
|
successors: %bb.3, %bb.4
|
|
liveins: $rbx, $r14
|
|
|
|
EH_LABEL <mcsymbol Ltmp0>
|
|
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
renamable $rbx, renamable $r14 = STATEPOINT 0, 0, 0, @foo, 2, 0, 2, 0, 2, 0, killed renamable $rbx, renamable $rbx(tied-def 0), killed renamable $r14, renamable $r14(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
|
|
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
EH_LABEL <mcsymbol Ltmp1>
|
|
JMP_1 %bb.3
|
|
|
|
bb.2:
|
|
successors: %bb.5, %bb.4
|
|
liveins: $rbx, $r14
|
|
|
|
EH_LABEL <mcsymbol Ltmp2>
|
|
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
renamable $rbx, renamable $r14 = STATEPOINT 0, 0, 0, @bar, 2, 0, 2, 0, 2, 0, killed renamable $rbx, renamable $rbx(tied-def 0), killed renamable $r14, renamable $r14(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
|
|
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
|
|
EH_LABEL <mcsymbol Ltmp3>
|
|
JMP_1 %bb.5
|
|
|
|
bb.3:
|
|
liveins: $rbx
|
|
|
|
$rax = COPY killed renamable $rbx
|
|
RET 0, $rax
|
|
|
|
bb.4 (landing-pad):
|
|
liveins: $rax, $rdx, $r14
|
|
|
|
EH_LABEL <mcsymbol Ltmp4>
|
|
$rax = COPY killed renamable $r14
|
|
RET 0, $rax
|
|
|
|
bb.5:
|
|
liveins: $rbx
|
|
|
|
$rax = COPY killed renamable $rbx
|
|
RET 0, $rax
|
|
|
|
...
|