about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs10
2 files changed, 12 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 1e3b76e5f93..bf3b1e73b94 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -207,9 +207,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         {
             // These cases are all UB to actually hit, so don't emit code for them.
             // (The size mismatches are reachable via `transmute_unchecked`.)
-            // We can't use unreachable because that's a terminator, and we
-            // need something that can be in the middle of a basic block.
-            bx.assume(bx.cx().const_bool(false))
+            bx.unreachable_nonterminator();
         } else {
             // Since in this path we have a place anyway, we can store or copy to it,
             // making sure we use the destination place's alignment even if the
@@ -236,9 +234,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             || operand.layout.is_uninhabited()
             || cast.is_uninhabited()
         {
-            // We can't use unreachable because that's a terminator, and we
-            // need something that can be in the middle of a basic block.
-            bx.assume(bx.cx().const_bool(false));
+            bx.unreachable_nonterminator();
 
             // We still need to return a value of the appropriate type, but
             // it's already UB so do the easiest thing available.
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 9d367748c2a..0f1358ee508 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -136,6 +136,16 @@ pub trait BuilderMethods<'a, 'tcx>:
     ) -> Self::Value;
     fn unreachable(&mut self);
 
+    /// Like [`Self::unreachable`], but for use in the middle of a basic block.
+    fn unreachable_nonterminator(&mut self) {
+        // This is the preferred LLVM incantation for this per
+        // https://llvm.org/docs/Frontend/PerformanceTips.html#other-things-to-consider
+        // Other backends may override if they have a better way.
+        let const_true = self.cx().const_bool(true);
+        let poison_ptr = self.const_poison(self.cx().type_ptr());
+        self.store(const_true, poison_ptr, Align::ONE);
+    }
+
     fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;