The carry and borrow values are boolean, so we have to convert them to an integer type with bint(c) before we can add them to the result. Also tweak the default legalizer action for unsupported types: Only attempt a narrowing pattern for lane types > 32 bits. This was found by @angusholder's new type checks in the verifier.
126 lines
3.5 KiB
Plaintext
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 = bxor 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
|
|
}
|