Files
wasmtime/cranelift/filetests/regalloc/spill.cton
Dan Gohman 10dcfcacdb Remove support for entity variables in filecheck.
Now that the parser doesn't renumber indices, there's no need for entity
variables like $v0.
2018-02-20 17:27:46 -08:00

221 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+
isa riscv 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
ebb0(v1: i32):
; check: ebb0($(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 = function %foo(i32)
ebb0(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 = function %xx(i32, i32)
ebb0(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) native
ebb0(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) native
ebb0(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
ebb0(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 EBB arguments than registers.
function %ebbargs(i32) -> i32 {
ebb0(v1: i32):
; check: v1 = spill
v2 = iconst.i32 1
jump ebb1(v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2)
ebb1(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 an EBB argument to make room for a branch operand.
function %brargs(i32) -> i32 {
ebb0(v1: i32):
; check: v1 = spill
v2 = iconst.i32 1
brnz v1, ebb1(v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2, v2)
return v1
ebb1(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
ebb0(v1: i32):
; check: ebb0($(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
}