@@ -129,6 +129,7 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
129129 let ssa = SsaLocals :: new ( tcx, body, typing_env) ;
130130 // Clone dominators because we need them while mutating the body.
131131 let dominators = body. basic_blocks . dominators ( ) . clone ( ) ;
132+ let maybe_loop = !loop_:: maybe_loop_headers ( body) . is_empty ( ) ;
132133
133134 let arena = DroplessArena :: default ( ) ;
134135 let mut state =
@@ -141,6 +142,10 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
141142
142143 let reverse_postorder = body. basic_blocks . reverse_postorder ( ) . to_vec ( ) ;
143144 for bb in reverse_postorder {
145+ // N.B. With loops, reverse postorder cannot produce a valid topological order.
146+ if maybe_loop {
147+ state. invalidate_derefs ( ) ;
148+ }
144149 let data = & mut body. basic_blocks . as_mut_preserves_cfg ( ) [ bb] ;
145150 state. visit_basic_block_data ( bb, data) ;
146151 }
@@ -1924,7 +1929,9 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
19241929 // Currently, only preserving derefs for trivial terminators like SwitchInt and Goto.
19251930 let safe_to_preserve_derefs = matches ! (
19261931 terminator. kind,
1927- TerminatorKind :: SwitchInt { .. } | TerminatorKind :: Goto { .. }
1932+ TerminatorKind :: SwitchInt { .. }
1933+ | TerminatorKind :: Goto { .. }
1934+ | TerminatorKind :: Unreachable
19281935 ) ;
19291936 if !safe_to_preserve_derefs {
19301937 self . invalidate_derefs ( ) ;
0 commit comments