moved crates in lib/ to src/, renamed crates, modified some files' text (#660)
moved crates in lib/ to src/, renamed crates, modified some files' text (#660)
This commit is contained in:
19
cranelift/filetests/filetests/verifier/bad_layout.clif
Normal file
19
cranelift/filetests/filetests/verifier/bad_layout.clif
Normal file
@@ -0,0 +1,19 @@
|
||||
test verifier
|
||||
|
||||
function %test(i32) {
|
||||
ebb0(v0: i32):
|
||||
jump ebb1 ; error: terminator
|
||||
return
|
||||
ebb1:
|
||||
jump ebb2
|
||||
brz v0, ebb3
|
||||
ebb2:
|
||||
jump ebb3
|
||||
ebb3:
|
||||
return
|
||||
}
|
||||
|
||||
function %test(i32) { ; Ok
|
||||
ebb0(v0: i32):
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
test verifier
|
||||
|
||||
; Test verification that uses properly dominate defs.
|
||||
|
||||
function %non_dominating(i32) -> i32 system_v {
|
||||
ebb0(v0: i32):
|
||||
v1 = iadd.i32 v2, v0 ; error: uses value v2 from non-dominating
|
||||
v2 = iadd.i32 v1, v0
|
||||
return v2
|
||||
}
|
||||
|
||||
function %inst_uses_its_own_values(i32) -> i32 system_v {
|
||||
ebb0(v0: i32):
|
||||
v1 = iadd.i32 v1, v0 ; error: uses value v1 from itself
|
||||
return v1
|
||||
}
|
||||
76
cranelift/filetests/filetests/verifier/flags.clif
Normal file
76
cranelift/filetests/filetests/verifier/flags.clif
Normal file
@@ -0,0 +1,76 @@
|
||||
test verifier
|
||||
target i686
|
||||
|
||||
; Simple, correct use of CPU flags.
|
||||
function %simple(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
|
||||
[Op1ret#c3] return v3
|
||||
}
|
||||
|
||||
; Overlapping flag values of different types.
|
||||
function %overlap(i32, f32) -> i32 {
|
||||
ebb0(v0: i32, v1: f32):
|
||||
[Op1rcmp#39] v2 = ifcmp v0, v0
|
||||
[Op2fcmp#42e] v3 = ffcmp v1, v1
|
||||
[Op2setf_abcd#490] v4 = trueff gt v3 ; error: conflicting live CPU flags: v2 and v3
|
||||
[Op2seti_abcd#490] v5 = trueif ugt v2
|
||||
[Op1rr#21] v6 = band v4, v5
|
||||
[Op2urm_noflags_abcd#4b6] v7 = bint.i32 v6
|
||||
[Op1ret#c3] return v7
|
||||
}
|
||||
|
||||
; CPU flags clobbered by arithmetic.
|
||||
function %clobbered(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1rr#01] v2 = iadd v0, v0 ; error: encoding clobbers live CPU flags in v1
|
||||
[Op2seti_abcd#490] v3 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v4 = bint.i32 v3
|
||||
[Op1ret#c3] return v4
|
||||
}
|
||||
|
||||
; CPU flags not clobbered by load.
|
||||
function %live_across_load(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1ld#8b] v2 = load.i32 v0
|
||||
[Op2seti_abcd#490] v3 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v4 = bint.i32 v3
|
||||
[Op1ret#c3] return v4
|
||||
}
|
||||
|
||||
; Correct use of CPU flags across EBB.
|
||||
function %live_across_ebb(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
ebb1:
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
|
||||
[Op1ret#c3] return v3
|
||||
}
|
||||
|
||||
function %live_across_ebb_backwards(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1jmpb#eb] jump ebb2
|
||||
ebb1:
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
|
||||
[Op1ret#c3] return v3
|
||||
ebb2:
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
}
|
||||
|
||||
; Flags live into loop.
|
||||
function %live_into_loop(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
[Op1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
ebb1:
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
}
|
||||
19
cranelift/filetests/filetests/verifier/globals.clif
Normal file
19
cranelift/filetests/filetests/verifier/globals.clif
Normal file
@@ -0,0 +1,19 @@
|
||||
test verifier
|
||||
target x86_64
|
||||
|
||||
function %load_base_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i32 notrap aligned gv0
|
||||
gv2 = load.i32 notrap aligned gv1 ; error: base gv1 has type i32, which is not the pointer type i64
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %global_value_wrong_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
|
||||
ebb0(v0: i64):
|
||||
v1 = global_value.i32 gv0 ; error: global_value instruction with type i32 references global value with type i64
|
||||
return
|
||||
}
|
||||
45
cranelift/filetests/filetests/verifier/heap.clif
Normal file
45
cranelift/filetests/filetests/verifier/heap.clif
Normal file
@@ -0,0 +1,45 @@
|
||||
test verifier
|
||||
target x86_64
|
||||
|
||||
function %heap_base_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i32 notrap aligned gv0
|
||||
heap0 = static gv1, offset_guard 0x1000, bound 0x1_0000, index_type i32 ; error: heap base has type i32, which is not the pointer type i64
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %invalid_base(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
heap0 = dynamic gv1, bound gv0, offset_guard 0x1000, index_type i64 ; error: invalid base global value gv1
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %invalid_bound(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i64 ; error: invalid bound global value gv1
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %heap_bound_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i16 notrap aligned gv0
|
||||
heap0 = dynamic gv0, bound gv1, offset_guard 0x1000, index_type i32 ; error: heap index type i32 differs from the type of its bound, i16
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %heap_addr_index_type(i64 vmctx, i64) {
|
||||
gv0 = vmctx
|
||||
heap0 = static gv0, offset_guard 0x1000, bound 0x1_0000, index_type i32
|
||||
|
||||
ebb0(v0: i64, v1: i64):
|
||||
v2 = heap_addr.i64 heap0, v1, 0; error: index type i64 differs from heap index type i32
|
||||
return
|
||||
}
|
||||
16
cranelift/filetests/filetests/verifier/memory.clif
Normal file
16
cranelift/filetests/filetests/verifier/memory.clif
Normal file
@@ -0,0 +1,16 @@
|
||||
test verifier
|
||||
|
||||
function %cycle() {
|
||||
gv0 = load.i32 notrap aligned gv1 ; error: global value cycle: [gv0, gv1]
|
||||
gv1 = load.i32 notrap aligned gv0-32
|
||||
|
||||
ebb1:
|
||||
return
|
||||
}
|
||||
|
||||
function %self_cycle() {
|
||||
gv0 = load.i32 notrap aligned gv0 ; error: global value cycle: [gv0]
|
||||
|
||||
ebb1:
|
||||
return
|
||||
}
|
||||
46
cranelift/filetests/filetests/verifier/table.clif
Normal file
46
cranelift/filetests/filetests/verifier/table.clif
Normal file
@@ -0,0 +1,46 @@
|
||||
test verifier
|
||||
target x86_64
|
||||
|
||||
function %table_base_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i32 notrap aligned gv0
|
||||
table0 = dynamic gv1, element_size 1, bound gv1, index_type i32 ; error: table base has type i32, which is not the pointer type i64
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %invalid_base(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
table0 = dynamic gv1, bound gv0, element_size 1, index_type i64 ; error: invalid base global value gv1
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %invalid_bound(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
table0 = dynamic gv0, bound gv1, element_size 1, index_type i64 ; error: invalid bound global value gv1
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %table_bound_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i16 notrap aligned gv0
|
||||
table0 = dynamic gv0, bound gv1, element_size 1, index_type i32 ; error: table index type i32 differs from the type of its bound, i16
|
||||
|
||||
ebb0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %table_addr_index_type(i64 vmctx, i64) {
|
||||
gv0 = vmctx
|
||||
gv1 = load.i32 notrap aligned gv0
|
||||
table0 = dynamic gv0, element_size 1, bound gv1, index_type i32
|
||||
|
||||
ebb0(v0: i64, v1: i64):
|
||||
v2 = table_addr.i64 table0, v1, +0; error: index type i64 differs from table index type i32
|
||||
return
|
||||
}
|
||||
115
cranelift/filetests/filetests/verifier/type_check.clif
Normal file
115
cranelift/filetests/filetests/verifier/type_check.clif
Normal file
@@ -0,0 +1,115 @@
|
||||
test verifier
|
||||
|
||||
function %entry_block_signature_mismatch(i32) {
|
||||
ebb0: ; error: entry block parameters (0) must match function signature (1)
|
||||
return
|
||||
}
|
||||
|
||||
function %entry_block_arg_type(i32) {
|
||||
ebb0(v0: f32): ; error: entry block parameter 0 expected to have type i32, got f32
|
||||
return
|
||||
}
|
||||
|
||||
function %incorrect_arg_type(i32, b1) -> i32 {
|
||||
ebb0(v0: i32, v1: b1):
|
||||
v2 = iadd v0, v1 ; error: arg 1 (v1) has type b1, expected i32
|
||||
return v2
|
||||
}
|
||||
|
||||
function %incorrect_return_type() -> f32 {
|
||||
ebb0:
|
||||
v0 = iconst.i32 1
|
||||
return v0 ; error: arg 0 (v0) has type i32, must match function signature of f32
|
||||
}
|
||||
|
||||
function %too_many_return_values() {
|
||||
ebb0:
|
||||
v0 = iconst.i32 1
|
||||
return v0 ; error: arguments of return must match function signature
|
||||
}
|
||||
|
||||
function %too_few_return_values() -> f32, i64 {
|
||||
ebb0:
|
||||
return ; error: arguments of return must match function signature
|
||||
}
|
||||
|
||||
function %type_mismatch_controlling_variable() {
|
||||
ebb0:
|
||||
v0 = iconst.i32 5
|
||||
v1 = iconst.i64 6
|
||||
v2 = iadd v0, v1 ; error: arg 1 (v1) has type i64, expected i32
|
||||
return
|
||||
}
|
||||
|
||||
function %fn_call_too_few_args() {
|
||||
fn2 = %great_fn(i32, f32)
|
||||
ebb0:
|
||||
call fn2() ; error: mismatched argument count for `call fn2()`: got 0, expected 2
|
||||
return
|
||||
}
|
||||
|
||||
function %fn_call_too_many_args() {
|
||||
fn5 = %best_fn()
|
||||
ebb0:
|
||||
v0 = iconst.i64 56
|
||||
v1 = f32const 0.0
|
||||
call fn5(v0, v1) ; error: mismatched argument count for `call fn5(v0, v1)`: got 2, expected 0
|
||||
return
|
||||
}
|
||||
|
||||
function %fn_call_incorrect_arg_type(i64) {
|
||||
sig9 = (f32)
|
||||
ebb0(v0: i64):
|
||||
v1 = iconst.i32 56
|
||||
call_indirect sig9, v0(v1) ; error: arg 0 (v1) has type i32, expected f32
|
||||
return
|
||||
}
|
||||
|
||||
; TODO: Should we instead just verify that jump tables contain no EBBs that take arguments? This
|
||||
; error doesn't occur if no instruction uses the jump table.
|
||||
function %jump_table_args() {
|
||||
jt1 = jump_table [ebb1]
|
||||
ebb0:
|
||||
v0 = iconst.i32 0
|
||||
br_table v0, ebb2, jt1 ; error: takes no arguments, but had target ebb1 with 1 arguments
|
||||
|
||||
ebb1(v5: i32):
|
||||
return
|
||||
ebb2:
|
||||
return
|
||||
}
|
||||
|
||||
function %jump_args() {
|
||||
ebb0:
|
||||
v0 = iconst.i16 10
|
||||
v3 = iconst.i64 20
|
||||
jump ebb1(v0, v3) ; error: arg 0 (v0) has type i16, expected i64
|
||||
; error: arg 1 (v3) has type i64, expected i16
|
||||
ebb1(v10: i64, v11: i16):
|
||||
return
|
||||
}
|
||||
|
||||
function %jump_args2() {
|
||||
ebb0:
|
||||
v0 = iconst.i16 10
|
||||
v3 = iconst.i64 20
|
||||
brz v0, ebb1(v0, v3) ; error: arg 0 (v0) has type i16, expected i64
|
||||
; error: arg 1 (v3) has type i64, expected i16
|
||||
jump ebb1(v3, v0)
|
||||
ebb1(v10: i64, v11: i16):
|
||||
return
|
||||
}
|
||||
|
||||
function %bad_extend() {
|
||||
ebb0:
|
||||
v0 = iconst.i32 10
|
||||
v1 = uextend.i16 v0 ; error: input i32 must be smaller than output i16
|
||||
return
|
||||
}
|
||||
|
||||
function %bad_reduce() {
|
||||
ebb0:
|
||||
v0 = iconst.i32 10
|
||||
v1 = ireduce.i64 v0 ; error: input i32 must be larger than output i64
|
||||
return
|
||||
}
|
||||
17
cranelift/filetests/filetests/verifier/undeclared_vmctx.clif
Normal file
17
cranelift/filetests/filetests/verifier/undeclared_vmctx.clif
Normal file
@@ -0,0 +1,17 @@
|
||||
test verifier
|
||||
|
||||
; Using a vmctx global value without declaring it first leads to an error.
|
||||
function %vmglobal_err(i64) -> i64 {
|
||||
gv4 = vmctx ; error: undeclared vmctx reference
|
||||
ebb0(v0: i64):
|
||||
v1 = global_value.i64 gv4
|
||||
return v1
|
||||
}
|
||||
|
||||
; If it is declared, all is fine.
|
||||
function %vmglobal_ok(i64 vmctx) -> i64 {
|
||||
gv4 = vmctx
|
||||
ebb0(v0: i64):
|
||||
v1 = global_value.i64 gv4
|
||||
return v1
|
||||
}
|
||||
45
cranelift/filetests/filetests/verifier/unreachable_code.clif
Normal file
45
cranelift/filetests/filetests/verifier/unreachable_code.clif
Normal file
@@ -0,0 +1,45 @@
|
||||
test verifier
|
||||
|
||||
function %test() -> i32 { ; Ok
|
||||
ebb0:
|
||||
v0 = iconst.i32 0
|
||||
v1 = iconst.i32 0
|
||||
jump ebb2
|
||||
|
||||
ebb2:
|
||||
jump ebb4
|
||||
|
||||
ebb4:
|
||||
jump ebb2
|
||||
|
||||
ebb3(v2: i32):
|
||||
v4 = iadd.i32 v1, v2
|
||||
jump ebb9(v4)
|
||||
|
||||
ebb9(v7: i32):
|
||||
v9 = iadd.i32 v2, v7
|
||||
return v9
|
||||
|
||||
}
|
||||
|
||||
; Using a function argument in an unreachable block is ok.
|
||||
function %arg(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
v1 = iadd_imm v0, 1
|
||||
return v1
|
||||
|
||||
ebb1:
|
||||
v10 = iadd_imm v0, 10
|
||||
return v10
|
||||
}
|
||||
|
||||
; Using an EBB argument from an unreachable block is not ok.
|
||||
function %arg2(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
v1 = iadd v0, v10 ; error: uses value arg from non-dominating
|
||||
return v1
|
||||
|
||||
ebb1(v10: i32):
|
||||
v11 = iadd v0, v10
|
||||
return v11
|
||||
}
|
||||
Reference in New Issue
Block a user