diff --git a/cranelift/codegen/src/ir/jumptable.rs b/cranelift/codegen/src/ir/jumptable.rs index d102617df4..bf05169d36 100644 --- a/cranelift/codegen/src/ir/jumptable.rs +++ b/cranelift/codegen/src/ir/jumptable.rs @@ -68,6 +68,11 @@ impl JumpTableData { pub fn iter_mut(&mut self) -> IterMut { self.table.iter_mut() } + + /// Clears all entries in this jump table. + pub fn clear(&mut self) { + self.table.clear(); + } } impl Display for JumpTableData { diff --git a/cranelift/codegen/src/unreachable_code.rs b/cranelift/codegen/src/unreachable_code.rs index 63e3e230f8..3c3f4d9d6b 100644 --- a/cranelift/codegen/src/unreachable_code.rs +++ b/cranelift/codegen/src/unreachable_code.rs @@ -43,4 +43,17 @@ pub fn eliminate_unreachable_code( // Finally, remove the block from the layout. pos.func.layout.remove_block(block); } + + // Remove all jumptable block-list contents that refer to unreachable + // blocks; the jumptable itself must have been unused (or used only in an + // unreachable block) if so. Note that we are not necessarily removing *all* + // unused jumptables, because that would require computing their + // reachability as well; we are just removing enough to clean up references + // to deleted blocks. + for jt_data in func.jump_tables.values_mut() { + let invalid_ref = jt_data.iter().any(|block| !domtree.is_reachable(*block)); + if invalid_ref { + jt_data.clear(); + } + } } diff --git a/cranelift/filetests/filetests/isa/x64/unused_jt_unreachable_block.clif b/cranelift/filetests/filetests/isa/x64/unused_jt_unreachable_block.clif new file mode 100644 index 0000000000..96478ba8ce --- /dev/null +++ b/cranelift/filetests/filetests/isa/x64/unused_jt_unreachable_block.clif @@ -0,0 +1,21 @@ +test compile +target x86_64 +feature "experimental_x64" + +;; From: https://github.com/bytecodealliance/wasmtime/issues/2670 + +function %f() system_v { + jt0 = jump_table [block1] + +block0: + return + +block1: + trap unreachable +} + +; check: pushq %rbp +; nextln: movq %rsp, %rbp +; nextln: movq %rbp, %rsp +; nextln: popq %rbp +; nextln: ret