Files
wasmtime/cranelift/filetests/filetests/regalloc/spill.clif
Chris Fallin cb48ea406e Switch default to new x86_64 backend.
This PR switches the default backend on x86, for both the
`cranelift-codegen` crate and for Wasmtime, to the new
(`MachInst`-style, `VCode`-based) backend that has been under
development and testing for some time now.

The old backend is still available by default in builds with the
`old-x86-backend` feature, or by requesting `BackendVariant::Legacy`
from the appropriate APIs.

As part of that switch, it adds some more runtime-configurable plumbing
to the testing infrastructure so that tests can be run using the
appropriate backend. `clif-util test` is now capable of parsing a
backend selector option from filetests and instantiating the correct
backend.

CI has been updated so that the old x86 backend continues to run its
tests, just as we used to run the new x64 backend separately.

At some point, we will remove the old x86 backend entirely, once we are
satisfied that the new backend has not caused any unforeseen issues and
we do not need to revert.
2021-04-02 11:35:53 -07:00

224 lines
5.6 KiB
Plaintext

test regalloc
; Test the spiler on an ISA with few registers.
; RV32E has 16 registers, where:
; - %x0 is hardwired to zero.
; - %x1 is the return address.
; - %x2 is the stack pointer.
; - %x3 is the global pointer.
; - %x4 is the thread pointer.
; - %x10-%x15 are function arguments.
;
; regex: V=v\d+
; regex: WS=\s+
target riscv32 legacy enable_e
; In straight-line code, the first value defined is spilled.
; That is in order:
; 1. The argument v1.
; 2. The link register.
; 3. The first computed value, v2
function %pyramid(i32) -> i32 {
; check: ss0 = spill_slot 4
; check: ss1 = spill_slot 4
; check: ss2 = spill_slot 4
; not: spill_slot
block0(v1: i32):
; check: block0($(rv1=$V): i32 [%x10], $(rlink=$V): i32 [%x1])
; check: ,ss0]$WS v1 = spill $rv1
; nextln: ,ss1]$WS $(link=$V) = spill $rlink
; not: spill
v2 = iadd_imm v1, 12
; check: $(r1v2=$V) = iadd_imm
; nextln: ,ss2]$WS v2 = spill $r1v2
; not: spill
v3 = iadd_imm v2, 12
v4 = iadd_imm v3, 12
v5 = iadd_imm v4, 12
v6 = iadd_imm v5, 12
v7 = iadd_imm v6, 12
v8 = iadd_imm v7, 12
v9 = iadd_imm v8, 12
v10 = iadd_imm v9, 12
v11 = iadd_imm v10, 12
v12 = iadd_imm v11, 12
v13 = iadd_imm v12, 12
v14 = iadd_imm v13, 12
v33 = iadd v13, v14
; check: iadd v13
v32 = iadd v33, v12
v31 = iadd v32, v11
v30 = iadd v31, v10
v29 = iadd v30, v9
v28 = iadd v29, v8
v27 = iadd v28, v7
v26 = iadd v27, v6
v25 = iadd v26, v5
v24 = iadd v25, v4
v23 = iadd v24, v3
v22 = iadd v23, v2
; check: $(r2v2=$V) = fill v2
; check: v22 = iadd v23, $r2v2
v21 = iadd v22, v1
; check: $(r2v1=$V) = fill v1
; check: v21 = iadd v22, $r2v1
; check: $(rlink2=$V) = fill $link
return v21
; check: return v21, $rlink2
}
; All values live across a call must be spilled
function %across_call(i32) {
fn0 = %foo(i32)
block0(v1: i32):
; check: v1 = spill
call fn0(v1)
; check: call fn0
call fn0(v1)
; check: fill v1
; check: call fn0
return
}
; The same value used for two function arguments.
function %doubleuse(i32) {
fn0 = %xx(i32, i32)
block0(v0: i32):
; check: $(c=$V) = copy v0
call fn0(v0, v0)
; check: call fn0(v0, $c)
return
}
; The same value used as indirect callee and argument.
function %doubleuse_icall1(i32) {
sig0 = (i32) system_v
block0(v0: i32):
; not:copy
call_indirect sig0, v0(v0)
return
}
; The same value used as indirect callee and two arguments.
function %doubleuse_icall2(i32) {
sig0 = (i32, i32) system_v
block0(v0: i32):
; check: $(c=$V) = copy v0
call_indirect sig0, v0(v0, v0)
; check: call_indirect sig0, v0(v0, $c)
return
}
; Two arguments on the stack.
function %stackargs(i32, i32, i32, i32, i32, i32, i32, i32) -> i32 {
; check: ss0 = incoming_arg 4
; check: ss1 = incoming_arg 4, offset 4
; not: incoming_arg
block0(v0: i32, v1: i32, v2: i32, v3: i32, v4: i32, v5: i32, v6: i32, v7: i32):
; unordered: fill v6
; unordered: fill v7
v10 = iadd v6, v7
return v10
}
; More block arguments than registers.
function %blockargs(i32) -> i32 {
block0(v1: i32):
; check: v1 = spill
v2 = iconst.i32 1
jump block1(v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2)
block1(v10: i32, v11: i32, v12: i32, v13: i32, v14: i32, v15: i32, v16: i32, v17: i32, v18: i32, v19: i32, v20: i32, v21: i32):
v22 = iadd v10, v11
v23 = iadd v22, v12
v24 = iadd v23, v13
v25 = iadd v24, v14
v26 = iadd v25, v15
v27 = iadd v26, v16
v28 = iadd v27, v17
v29 = iadd v28, v18
v30 = iadd v29, v19
v31 = iadd v30, v20
v32 = iadd v31, v21
v33 = iadd v32, v1
return v33
}
; Spilling a block argument to make room for a branch operand.
function %brargs(i32) -> i32 {
block0(v1: i32):
; check: v1 = spill
v2 = iconst.i32 1
brnz v1, block1(v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2)
jump block2
block2:
return v1
block1(v10: i32, v11: i32, v12: i32, v13: i32, v14: i32, v15: i32, v16: i32, v17: i32, v18: i32, v19: i32, v20: i32, v21: i32):
v22 = iadd v10, v11
v23 = iadd v22, v12
v24 = iadd v23, v13
v25 = iadd v24, v14
v26 = iadd v25, v15
v27 = iadd v26, v16
v28 = iadd v27, v17
v29 = iadd v28, v18
v30 = iadd v29, v19
v31 = iadd v30, v20
v32 = iadd v31, v21
v33 = iadd v32, v1
return v33
}
; In straight-line code, the first value defined is spilled.
; That is in order:
; 1. The argument v1.
; 2. The link register.
; 3. The first computed value, v2
function %use_spilled_value(i32) -> i32 {
; check: ss0 = spill_slot 4
; check: ss1 = spill_slot 4
; check: ss2 = spill_slot 4
block0(v1: i32):
; check: block0($(rv1=$V): i32 [%x10], $(rlink=$V): i32 [%x1])
; check: ,ss0]$WS v1 = spill $rv1
; nextln: ,ss1]$WS $(link=$V) = spill $rlink
; not: spill
v2 = iadd_imm v1, 12
; check: $(r1v2=$V) = iadd_imm
; nextln: ,ss2]$WS v2 = spill $r1v2
v3 = iadd_imm v2, 12
v4 = iadd_imm v3, 12
v5 = iadd_imm v4, 12
v6 = iadd_imm v5, 12
v7 = iadd_imm v6, 12
v8 = iadd_imm v7, 12
v9 = iadd_imm v8, 12
v10 = iadd_imm v9, 12
v11 = iadd_imm v10, 12
v12 = iadd_imm v11, 12
v13 = iadd_imm v12, 12
v14 = iadd_imm v13, 12
; Here we have maximum register pressure, and v2 has been spilled.
; What happens if we use it?
v33 = iadd v2, v14
v32 = iadd v33, v12
v31 = iadd v32, v11
v30 = iadd v31, v10
v29 = iadd v30, v9
v28 = iadd v29, v8
v27 = iadd v28, v7
v26 = iadd v27, v6
v25 = iadd v26, v5
v24 = iadd v25, v4
v23 = iadd v24, v3
v22 = iadd v23, v2
v21 = iadd v22, v1
v20 = iadd v21, v13
v19 = iadd v20, v2
return v21
}