Files
wasmtime/filetests/isa/riscv/legalize-abi.cton
Jakob Stoklund Olesen 12b2af3f8a Simplify branch arguments after splitting EBB arguments.
The EBB argument splitting may generate concat-split dependencies when
it repairs branch arguments in EBBs that have not yet been fully
legalized. Add a branch argument simplification step that can resolve
these dependency chains.

This means that all split and concatenation instructions will be dead
after legalization for types that have no legal instructions using them.
2017-03-22 15:29:06 -07:00

126 lines
3.5 KiB
Plaintext

; Test legalizer's handling of ABI boundaries.
test legalizer
isa riscv
; regex: V=vx?\d+
function int_split_args(i64) -> i64 {
ebb0(v0: i64):
; check: $ebb0($(v0l=$V): i32, $(v0h=$V): i32):
; check: iconcat $v0l, $v0h
v1 = iadd_imm v0, 1
; check: $(v1l=$V), $(v1h=$V) = isplit $v1
; check: return $v1l, $v1h
return v1
}
function split_call_arg(i32) {
fn1 = function foo(i64)
fn2 = function foo(i32, i64)
ebb0(v0: i32):
v1 = uextend.i64 v0
call fn1(v1)
; check: $(v1l=$V), $(v1h=$V) = isplit $v1
; check: call $fn1($v1l, $v1h)
call fn2(v0, v1)
; check: call $fn2($v0, $V, $V)
return
}
function split_ret_val() {
fn1 = function foo() -> i64
ebb0:
v1 = call fn1()
; check: $ebb0:
; nextln: $(v1l=$V), $(v1h=$V) = call $fn1()
; check: $(v1new=$V) = iconcat $v1l, $v1h
; check: $v1 = copy $v1new
jump ebb1(v1)
; The v1 copy gets resolved by split::simplify_branch_arguments().
; check: jump $ebb1($v1new)
ebb1(v10: i64):
jump ebb1(v10)
}
; First return value is fine, second one is expanded.
function split_ret_val2() {
fn1 = function foo() -> i32, i64
ebb0:
v1, v2 = call fn1()
; check: $ebb0:
; nextln: $v1, $(v2l=$V), $(v2h=$V) = call $fn1()
; check: $(v2new=$V) = iconcat $v2l, $v2h
jump ebb1(v1, v2)
; The v2 -> v2new alias is resolved by split::simplify_branch_arguments().
; check: jump $ebb1($v1, $v2new)
ebb1(v9: i32, v10: i64):
jump ebb1(v9, v10)
}
function int_ext(i8, i8 sext, i8 uext) -> i8 uext {
ebb0(v1: i8, v2: i8, v3: i8):
; check: $ebb0($v1: i8, $(v2x=$V): i32, $(v3x=$V): i32):
; check: ireduce.i8 $v2x
; check: ireduce.i8 $v3x
; check: $(v1x=$V) = uextend.i32 $v1
; check: return $v1x
return v1
}
; Function produces single return value, still need to copy.
function ext_ret_val() {
fn1 = function foo() -> i8 sext
ebb0:
v1 = call fn1()
; check: $ebb0:
; nextln: $(rv=$V) = call $fn1()
; check: $(v1new=$V) = ireduce.i8 $rv
; check: $v1 = copy $v1new
jump ebb1(v1)
; The v1 copy gets resolved by split::simplify_branch_arguments().
; check: jump $ebb1($v1new)
ebb1(v10: i8):
jump ebb1(v10)
}
function vector_split_args(i64x4) -> i64x4 {
ebb0(v0: i64x4):
; check: $ebb0($(v0al=$V): i32, $(v0ah=$V): i32, $(v0bl=$V): i32, $(v0bh=$V): i32, $(v0cl=$V): i32, $(v0ch=$V): i32, $(v0dl=$V): i32, $(v0dh=$V): i32):
; check: $(v0a=$V) = iconcat $v0al, $v0ah
; check: $(v0b=$V) = iconcat $v0bl, $v0bh
; check: $(v0ab=$V) = vconcat $v0a, $v0b
; check: $(v0c=$V) = iconcat $v0cl, $v0ch
; check: $(v0d=$V) = iconcat $v0dl, $v0dh
; check: $(v0cd=$V) = vconcat $v0c, $v0d
; check: $(v0abcd=$V) = vconcat $v0ab, $v0cd
v1 = iadd v0, v0
; check: $(v1ab=$V), $(v1cd=$V) = vsplit
; check: $(v1a=$V), $(v1b=$V) = vsplit $v1ab
; check: $(v1al=$V), $(v1ah=$V) = isplit $v1a
; check: $(v1bl=$V), $(v1bh=$V) = isplit $v1b
; check: $(v1c=$V), $(v1d=$V) = vsplit $v1cd
; check: $(v1cl=$V), $(v1ch=$V) = isplit $v1c
; check: $(v1dl=$V), $(v1dh=$V) = isplit $v1d
; check: return $v1al, $v1ah, $v1bl, $v1bh, $v1cl, $v1ch, $v1dl, $v1dh
return v1
}
function indirect(i32) {
sig1 = signature()
ebb0(v0: i32):
call_indirect sig1, v0()
return
}
; The first argument to call_indirect doesn't get altered.
function indirect_arg(i32, f32x2) {
sig1 = signature(f32x2)
ebb0(v0: i32, v1: f32x2):
call_indirect sig1, v0(v1)
; check: call_indirect $sig1, $v0($V, $V)
return
}