Add BuilderMethods::unreachable_nonterminator

So places that need `unreachable` but in the middle of a basic block can call that instead of figuring out the best way to do it.
This commit is contained in:
Scott McMurray
2025-07-10 09:17:28 -07:00
parent 58d7c2d5a7
commit f5fc8727db
3 changed files with 32 additions and 27 deletions

View File

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

View File

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