about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src/instsimplify.rs
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2024-02-07 10:24:23 -0500
committerBen Kimock <kimockb@gmail.com>2024-02-08 11:49:05 -0500
commit580067c76f0f5b8b356c202c8fce939325f63f29 (patch)
treeac1d51569649ef742c89d97ce623924575b9dbfd /compiler/rustc_mir_transform/src/instsimplify.rs
parent9842a5ca7ff99916fe866f70833fb9dfd9031e23 (diff)
downloadrust-580067c76f0f5b8b356c202c8fce939325f63f29.tar.gz
rust-580067c76f0f5b8b356c202c8fce939325f63f29.zip
InstSimplify rustc_nounwind calls
Diffstat (limited to 'compiler/rustc_mir_transform/src/instsimplify.rs')
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index a28db0defc9..f65eb5cbea9 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -2,10 +2,12 @@
 
 use crate::simplify::simplify_duplicate_switch_targets;
 use rustc_middle::mir::*;
+use rustc_middle::ty::layout;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt};
 use rustc_span::symbol::Symbol;
 use rustc_target::abi::FieldIdx;
+use rustc_target::spec::abi::Abi;
 
 pub struct InstSimplify;
 
@@ -38,6 +40,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
                 block.terminator.as_mut().unwrap(),
                 &mut block.statements,
             );
+            ctx.simplify_nounwind_call(block.terminator.as_mut().unwrap());
             simplify_duplicate_switch_targets(block.terminator.as_mut().unwrap());
         }
     }
@@ -252,6 +255,28 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         terminator.kind = TerminatorKind::Goto { target: destination_block };
     }
 
+    fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) {
+        let TerminatorKind::Call { func, unwind, .. } = &mut terminator.kind else {
+            return;
+        };
+
+        let Some((def_id, _)) = func.const_fn_def() else {
+            return;
+        };
+
+        let body_ty = self.tcx.type_of(def_id).skip_binder();
+        let body_abi = match body_ty.kind() {
+            ty::FnDef(..) => body_ty.fn_sig(self.tcx).abi(),
+            ty::Closure(..) => Abi::RustCall,
+            ty::Coroutine(..) => Abi::Rust,
+            _ => bug!("unexpected body ty: {:?}", body_ty),
+        };
+
+        if !layout::fn_can_unwind(self.tcx, Some(def_id), body_abi) {
+            *unwind = UnwindAction::Unreachable;
+        }
+    }
+
     fn simplify_intrinsic_assert(
         &self,
         terminator: &mut Terminator<'tcx>,