Mass rename Ebb and relatives to Block (#1365)
* Manually rename BasicBlock to BlockPredecessor BasicBlock is a pair of (Ebb, Inst) that is used to represent the basic block subcomponent of an Ebb that is a predecessor to an Ebb. Eventually we will be able to remove this struct, but for now it makes sense to give it a non-conflicting name so that we can start to transition Ebb to represent a basic block. I have not updated any comments that refer to BasicBlock, as eventually we will remove BlockPredecessor and replace with Block, which is a basic block, so the comments will become correct. * Manually rename SSABuilder block types to avoid conflict SSABuilder has its own Block and BlockData types. These along with associated identifier will cause conflicts in a later commit, so they are renamed to be more verbose here. * Automatically rename 'Ebb' to 'Block' in *.rs * Automatically rename 'EBB' to 'block' in *.rs * Automatically rename 'ebb' to 'block' in *.rs * Automatically rename 'extended basic block' to 'basic block' in *.rs * Automatically rename 'an basic block' to 'a basic block' in *.rs * Manually update comment for `Block` `Block`'s wikipedia article required an update. * Automatically rename 'an `Block`' to 'a `Block`' in *.rs * Automatically rename 'extended_basic_block' to 'basic_block' in *.rs * Automatically rename 'ebb' to 'block' in *.clif * Manually rename clif constant that contains 'ebb' as substring to avoid conflict * Automatically rename filecheck uses of 'EBB' to 'BB' 'regex: EBB' -> 'regex: BB' '$EBB' -> '$BB' * Automatically rename 'EBB' 'Ebb' to 'block' in *.clif * Automatically rename 'an block' to 'a block' in *.clif * Fix broken testcase when function name length increases Test function names are limited to 16 characters. This causes the new longer name to be truncated and fail a filecheck test. An outdated comment was also fixed.
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
test verifier
|
||||
|
||||
function %test_1(i32) {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
return ; error: terminator
|
||||
return
|
||||
}
|
||||
function %test_2(i32) {
|
||||
ebb0(v0: i32):
|
||||
jump ebb2 ; error: a terminator instruction was encountered before the end of ebb0
|
||||
brz v0, ebb3
|
||||
ebb2:
|
||||
jump ebb3
|
||||
ebb3:
|
||||
block0(v0: i32):
|
||||
jump block2 ; error: a terminator instruction was encountered before the end of block0
|
||||
brz v0, block3
|
||||
block2:
|
||||
jump block3
|
||||
block3:
|
||||
return
|
||||
}
|
||||
|
||||
function %test_3(i32) { ; Ok
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,21 +2,21 @@ test verifier
|
||||
|
||||
; bitcast between two types of equal size if ok
|
||||
function %valid_bitcast1(i32) -> f32 { ; Ok
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
v1 = bitcast.f32 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; bitcast to a type larger than the operand is ok
|
||||
function %valid_bitcast2(i32) -> i64 { ; Ok
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
v1 = bitcast.i64 v0
|
||||
return v1
|
||||
}
|
||||
|
||||
; bitcast to a smaller type is not ok
|
||||
function %bad_bitcast(i64) -> i32 {
|
||||
ebb0(v0: i64):
|
||||
block0(v0: i64):
|
||||
v1 = bitcast.i32 v0 ; error: The bitcast argument v0 doesn't fit in a type of 32 bits
|
||||
return v1
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@ test verifier
|
||||
; Test verification that uses properly dominate defs.
|
||||
|
||||
function %non_dominating(i32) -> i32 system_v {
|
||||
ebb0(v0: i32):
|
||||
block0(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):
|
||||
block0(v0: i32):
|
||||
v1 = iadd.i32 v1, v0 ; error: uses value v1 from itself
|
||||
return v1
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ target i686
|
||||
|
||||
; Simple, correct use of CPU flags.
|
||||
function %simple(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
|
||||
@@ -12,7 +12,7 @@ function %simple(i32) -> i32 {
|
||||
|
||||
; Overlapping flag values of different types.
|
||||
function %overlap(i32, f32) -> i32 {
|
||||
ebb0(v0: i32, v1: f32):
|
||||
block0(v0: i32, v1: f32):
|
||||
[DynRexOp1rcmp#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
|
||||
@@ -24,7 +24,7 @@ function %overlap(i32, f32) -> i32 {
|
||||
|
||||
; CPU flags clobbered by arithmetic.
|
||||
function %clobbered(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[DynRexOp1rr#01] v2 = iadd v0, v0 ; error: encoding clobbers live CPU flags in v1
|
||||
[Op2seti_abcd#490] v3 = trueif ugt v1
|
||||
@@ -34,7 +34,7 @@ function %clobbered(i32) -> i32 {
|
||||
|
||||
; CPU flags not clobbered by load.
|
||||
function %live_across_load(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1ld#8b] v2 = load.i32 v0
|
||||
[Op2seti_abcd#490] v3 = trueif ugt v1
|
||||
@@ -42,35 +42,35 @@ function %live_across_load(i32) -> i32 {
|
||||
[Op1ret#c3] return v4
|
||||
}
|
||||
|
||||
; Correct use of CPU flags across EBB.
|
||||
function %live_across_ebb(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
; Correct use of CPU flags across block.
|
||||
function %live_across_block(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
ebb1:
|
||||
[Op1jmpb#eb] jump block1
|
||||
block1:
|
||||
[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:
|
||||
function %live_across_block_backwards(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
[Op1jmpb#eb] jump block2
|
||||
block1:
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op2urm_noflags_abcd#4b6] v3 = bint.i32 v2
|
||||
[Op1ret#c3] return v3
|
||||
ebb2:
|
||||
block2:
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
[Op1jmpb#eb] jump block1
|
||||
}
|
||||
|
||||
; Flags live into loop.
|
||||
function %live_into_loop(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
[DynRexOp1rcmp#39] v1 = ifcmp v0, v0
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
ebb1:
|
||||
[Op1jmpb#eb] jump block1
|
||||
block1:
|
||||
[Op2seti_abcd#490] v2 = trueif ugt v1
|
||||
[Op1jmpb#eb] jump ebb1
|
||||
[Op1jmpb#eb] jump block1
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ function %load_base_type(i64 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
function %global_value_wrong_type(i64 vmctx) {
|
||||
gv0 = vmctx
|
||||
|
||||
ebb0(v0: i64):
|
||||
block0(v0: i64):
|
||||
v1 = global_value.i32 gv0 ; error: global_value instruction with type i32 references global value with type i64
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ function %heap_base_type(i64 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ function %heap_bound_type(i64 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ 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):
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = heap_addr.i64 heap0, v1, 0; error: index type i64 differs from heap index type i32
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
test verifier
|
||||
|
||||
function %br_invalid_default(i64) {
|
||||
jt0 = jump_table [ebb1, ebb1]
|
||||
jt0 = jump_table [block1, block1]
|
||||
|
||||
ebb0(v0: i64):
|
||||
br_table.i64 v0, ebb2, jt0 ; error: invalid ebb reference ebb2
|
||||
ebb1:
|
||||
block0(v0: i64):
|
||||
br_table.i64 v0, block2, jt0 ; error: invalid block reference block2
|
||||
block1:
|
||||
return
|
||||
}
|
||||
|
||||
function %br(i64) {
|
||||
jt0 = jump_table [ebb1, ebb2] ; error: invalid ebb reference ebb2
|
||||
jt0 = jump_table [block1, block2] ; error: invalid block reference block2
|
||||
|
||||
ebb0(v0: i64):
|
||||
br_table.i64 v0, ebb1, jt0
|
||||
ebb1:
|
||||
block0(v0: i64):
|
||||
br_table.i64 v0, block1, jt0
|
||||
block1:
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ function %cycle() {
|
||||
gv0 = load.i32 notrap aligned gv1 ; error: global value cycle: [gv0, gv1]
|
||||
gv1 = load.i32 notrap aligned gv0-32
|
||||
|
||||
ebb1:
|
||||
block1:
|
||||
return
|
||||
}
|
||||
|
||||
function %self_cycle() {
|
||||
gv0 = load.i32 notrap aligned gv0 ; error: global value cycle: [gv0]
|
||||
|
||||
ebb1:
|
||||
block1:
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ set enable_simd=true
|
||||
target x86_64
|
||||
|
||||
function %scalar_to_vector() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i32 42
|
||||
v1 = scalar_to_vector.f32x4 v0 ; error: arg 0 (v0) has type i32, expected f32
|
||||
return
|
||||
|
||||
@@ -3,7 +3,7 @@ set enable_simd
|
||||
target x86_64
|
||||
|
||||
function %insertlane_i32x4() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = vconst.i32x4 [0 0 0 0]
|
||||
v1 = iconst.i32 42
|
||||
v2 = insertlane v0, 4, v1 ; error: The lane 4 does not index into the type i32x4
|
||||
@@ -11,7 +11,7 @@ ebb0:
|
||||
}
|
||||
|
||||
function %insertlane_b16x8() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = vconst.b16x8 [false false false false false false false false]
|
||||
v1 = bconst.b16 true
|
||||
v2 = insertlane v0, 8, v1 ; error: The lane 8 does not index into the type b16x8
|
||||
@@ -19,7 +19,7 @@ ebb0:
|
||||
}
|
||||
|
||||
function %insertlane_f64x2() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = vconst.f64x2 0x00
|
||||
v1 = f64const 0x0.1
|
||||
v2 = insertlane v0, 2, v1 ; error: The lane 2 does not index into the type f64x2
|
||||
@@ -27,14 +27,14 @@ ebb0:
|
||||
}
|
||||
|
||||
function %extractlane_i32x4() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = vconst.i32x4 [0 0 0 0]
|
||||
v1 = extractlane v0, 4 ; error: The lane 4 does not index into the type i32x4
|
||||
return
|
||||
}
|
||||
|
||||
function %extractlane_b8x16() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = vconst.b8x16 0x00
|
||||
v1 = extractlane v0, 16 ; error: The lane 16 does not index into the type b8x16
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@ function %table_base_type(i64 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ function %table_bound_type(i64 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):
|
||||
block0(v0: i64):
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ function %table_addr_index_type(i64 vmctx, i64) {
|
||||
gv1 = load.i32 notrap aligned gv0
|
||||
table0 = dynamic gv0, element_size 1, bound gv1, index_type i32
|
||||
|
||||
ebb0(v0: i64, v1: i64):
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = table_addr.i64 table0, v1, +0; error: index type i64 differs from table index type i32
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
test verifier
|
||||
|
||||
function %entry_block_signature_mismatch(i32) {
|
||||
ebb0: ; error: entry block parameters (0) must match function signature (1)
|
||||
block0: ; 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
|
||||
block0(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):
|
||||
block0(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:
|
||||
block0:
|
||||
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:
|
||||
block0:
|
||||
v0 = iconst.i32 1
|
||||
return v0 ; error: arguments of return must match function signature
|
||||
}
|
||||
|
||||
function %too_few_return_values() -> f32, i64 {
|
||||
ebb0:
|
||||
block0:
|
||||
return ; error: arguments of return must match function signature
|
||||
}
|
||||
|
||||
function %type_mismatch_controlling_variable() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i32 5
|
||||
v1 = iconst.i64 6
|
||||
v2 = iadd v0, v1 ; error: arg 1 (v1) has type i64, expected i32
|
||||
@@ -43,14 +43,14 @@ function %type_mismatch_controlling_variable() {
|
||||
|
||||
function %fn_call_too_few_args() {
|
||||
fn2 = %great_fn(i32, f32)
|
||||
ebb0:
|
||||
block0:
|
||||
call fn2() ; error: mismatched argument count for `call fn2()`: got 0, expected 2
|
||||
return
|
||||
}
|
||||
|
||||
function %fn_call_too_many_args() {
|
||||
fn5 = %best_fn()
|
||||
ebb0:
|
||||
block0:
|
||||
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
|
||||
@@ -59,56 +59,56 @@ function %fn_call_too_many_args() {
|
||||
|
||||
function %fn_call_incorrect_arg_type(i64) {
|
||||
sig9 = (f32)
|
||||
ebb0(v0: i64):
|
||||
block0(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
|
||||
; TODO: Should we instead just verify that jump tables contain no blocks that take arguments? This
|
||||
; error doesn't occur if no instruction uses the jump table.
|
||||
function %jump_table_args() {
|
||||
jt1 = jump_table [ebb1]
|
||||
ebb0:
|
||||
jt1 = jump_table [block1]
|
||||
block0:
|
||||
v0 = iconst.i32 0
|
||||
br_table v0, ebb2, jt1 ; error: takes no arguments, but had target ebb1 with 1 arguments
|
||||
br_table v0, block2, jt1 ; error: takes no arguments, but had target block1 with 1 arguments
|
||||
|
||||
ebb1(v5: i32):
|
||||
block1(v5: i32):
|
||||
return
|
||||
ebb2:
|
||||
block2:
|
||||
return
|
||||
}
|
||||
|
||||
function %jump_args() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i16 10
|
||||
v3 = iconst.i64 20
|
||||
jump ebb1(v0, v3) ; error: arg 0 (v0) has type i16, expected i64
|
||||
jump block1(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):
|
||||
block1(v10: i64, v11: i16):
|
||||
return
|
||||
}
|
||||
|
||||
function %jump_args2() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i16 10
|
||||
v3 = iconst.i64 20
|
||||
brz v0, ebb1(v0, v3) ; error: arg 0 (v0) has type i16, expected i64
|
||||
brz v0, block1(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):
|
||||
jump block1(v3, v0)
|
||||
block1(v10: i64, v11: i16):
|
||||
return
|
||||
}
|
||||
|
||||
function %bad_extend() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i32 10
|
||||
v1 = uextend.i16 v0 ; error: input i32 must be smaller than output i16
|
||||
return
|
||||
}
|
||||
|
||||
function %bad_reduce() {
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i32 10
|
||||
v1 = ireduce.i64 v0 ; error: input i32 must be larger than output i64
|
||||
return
|
||||
|
||||
@@ -3,7 +3,7 @@ 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):
|
||||
block0(v0: i64):
|
||||
v1 = global_value.i64 gv4
|
||||
return v1
|
||||
}
|
||||
@@ -11,7 +11,7 @@ ebb0(v0: i64):
|
||||
; If it is declared, all is fine.
|
||||
function %vmglobal_ok(i64 vmctx) -> i64 {
|
||||
gv4 = vmctx
|
||||
ebb0(v0: i64):
|
||||
block0(v0: i64):
|
||||
v1 = global_value.i64 gv4
|
||||
return v1
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
test verifier
|
||||
|
||||
function %test() -> i32 { ; Ok
|
||||
ebb0:
|
||||
block0:
|
||||
v0 = iconst.i32 0
|
||||
v1 = iconst.i32 0
|
||||
jump ebb2
|
||||
jump block2
|
||||
|
||||
ebb2:
|
||||
jump ebb4
|
||||
block2:
|
||||
jump block4
|
||||
|
||||
ebb4:
|
||||
jump ebb2
|
||||
block4:
|
||||
jump block2
|
||||
|
||||
ebb3(v2: i32):
|
||||
block3(v2: i32):
|
||||
v4 = iadd.i32 v1, v2
|
||||
jump ebb9(v4)
|
||||
jump block9(v4)
|
||||
|
||||
ebb9(v7: i32):
|
||||
block9(v7: i32):
|
||||
v9 = iadd.i32 v2, v7
|
||||
return v9
|
||||
|
||||
@@ -24,22 +24,22 @@ ebb9(v7: i32):
|
||||
|
||||
; Using a function argument in an unreachable block is ok.
|
||||
function %arg(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
v1 = iadd_imm v0, 1
|
||||
return v1
|
||||
|
||||
ebb1:
|
||||
block1:
|
||||
v10 = iadd_imm v0, 10
|
||||
return v10
|
||||
}
|
||||
|
||||
; Using an EBB argument from an unreachable block is not ok.
|
||||
; Using a block argument from an unreachable block is not ok.
|
||||
function %arg2(i32) -> i32 {
|
||||
ebb0(v0: i32):
|
||||
block0(v0: i32):
|
||||
v1 = iadd v0, v10 ; error: uses value arg from non-dominating
|
||||
return v1
|
||||
|
||||
ebb1(v10: i32):
|
||||
block1(v10: i32):
|
||||
v11 = iadd v0, v10
|
||||
return v11
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user