Merge pull request #2683 from cfallin/br-table-unreachable

Fix bad jumptable block ref when DCE removes a block.
This commit is contained in:
Chris Fallin
2021-02-23 16:31:19 -08:00
committed by GitHub
3 changed files with 39 additions and 0 deletions

View File

@@ -68,6 +68,11 @@ impl JumpTableData {
pub fn iter_mut(&mut self) -> IterMut<Block> {
self.table.iter_mut()
}
/// Clears all entries in this jump table.
pub fn clear(&mut self) {
self.table.clear();
}
}
impl Display for JumpTableData {

View File

@@ -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();
}
}
}

View File

@@ -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