Fix underflow when calculating the number of no-op jumps folded

When removing unwinds to no-op blocks and folding jumps to no-op blocks,
remove the unwind target first. Otherwise we cannot determine if target
has been already folded or not.

Previous implementation incorrectly assumed that all resume targets had
been folded already, occasionally resulting in an underflow:

remove_noop_landing_pads: removed 18446744073709551613 jumps and 3 landing pads
This commit is contained in:
Tomasz Miąsko 2020-09-16 00:00:00 +00:00
parent 90b1f5ae59
commit ff1a9e406b

View File

@ -102,6 +102,16 @@ impl RemoveNoopLandingPads {
let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect(); let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
for bb in postorder { for bb in postorder {
debug!(" processing {:?}", bb); debug!(" processing {:?}", bb);
if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
if let Some(unwind_bb) = *unwind {
if nop_landing_pads.contains(unwind_bb) {
debug!(" removing noop landing pad");
landing_pads_removed += 1;
*unwind = None;
}
}
}
for target in body[bb].terminator_mut().successors_mut() { for target in body[bb].terminator_mut().successors_mut() {
if *target != resume_block && nop_landing_pads.contains(*target) { if *target != resume_block && nop_landing_pads.contains(*target) {
debug!(" folding noop jump to {:?} to resume block", target); debug!(" folding noop jump to {:?} to resume block", target);
@ -110,15 +120,6 @@ impl RemoveNoopLandingPads {
} }
} }
if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
if *unwind == Some(resume_block) {
debug!(" removing noop landing pad");
jumps_folded -= 1;
landing_pads_removed += 1;
*unwind = None;
}
}
let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads); let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
if is_nop_landing_pad { if is_nop_landing_pad {
nop_landing_pads.insert(bb); nop_landing_pads.insert(bb);