This simple snippet:
fn main() {
match Some(1) {
Some(x) => println!("{}", x),
None => unsafe { std::hint::unreachable_unchecked() }
}
}
Debug build:
$ rustc main.rs --emit=llvm-ir
Relevant llvm-IR code
switch i64 %5, label %bb2 [
i64 0, label %bb1
i64 1, label %bb3
]
bb1: ; preds = %start
; call core::hint::unreachable_unchecked
call void @_ZN4core4hint21unreachable_unchecked17h54c9e342b94a1675E()
unreachable
bb2: ; preds = %start
unreachable
; core::hint::unreachable_unchecked
; Function Attrs: inlinehint noreturn nonlazybind uwtable
define internal void @_ZN4core4hint21unreachable_unchecked17h54c9e342b94a1675E() unnamed_addr #2 {
start:
unreachable
}
It uses llvm unreachable instruction.
In release build:
$ rustc main.rs --emit=llvm-ir -C opt-level=2
It's already optimized away:
; main::main
; Function Attrs: nonlazybind uwtable
define internal void @_ZN4main4main17h6b07ac6c6f06cdd6E() unnamed_addr #0 {
start:
%_12 = alloca [1 x { i8*, i8* }], align 8
%_5 = alloca %"core::fmt::Arguments", align 8
%x = alloca i32, align 4
%0 = bitcast i32* %x to i8*
call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0)
store i32 1, i32* %x, align 4
%1 = bitcast %"core::fmt::Arguments"* %_5 to i8*
call void @llvm.lifetime.start.p0i8(i64 48, i8* nonnull %1)
%2 = bitcast [1 x { i8*, i8* }]* %_12 to i8*
call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %2)
%3 = bitcast [1 x { i8*, i8* }]* %_12 to i32**
store i32* %x, i32** %3, align 8
%4 = getelementptr inbounds [1 x { i8*, i8* }], [1 x { i8*, i8* }]* %_12, i64 0, i64 0, i32 1
store i8* bitcast (i1 (i32*, %"core::fmt::Formatter"*)* @"_ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17hd5184f5375b0c2fdE" to i8*), i8** %4, align 8
%5 = bitcast %"core::fmt::Arguments"* %_5 to [0 x { [0 x i8]*, i64 }]**
store [0 x { [0 x i8]*, i64 }]* bitcast (<{ i8*, [8 x i8], i8*, [8 x i8] }>* @2 to [0 x { [0 x i8]*, i64 }]*), [0 x { [0 x i8]*, i64 }]** %5, align 8, !alias.scope !6, !noalias !9
%6 = getelementptr inbounds %"core::fmt::Arguments", %"core::fmt::Arguments"* %_5, i64 0, i32 1, i32 1
store i64 2, i64* %6, align 8, !alias.scope !6, !noalias !9
%7 = getelementptr inbounds %"core::fmt::Arguments", %"core::fmt::Arguments"* %_5, i64 0, i32 3, i32 0
store i64* null, i64** %7, align 8, !alias.scope !6, !noalias !9
%8 = getelementptr inbounds %"core::fmt::Arguments", %"core::fmt::Arguments"* %_5, i64 0, i32 5, i32 0
%9 = bitcast [0 x { i8*, i8* }]** %8 to [1 x { i8*, i8* }]**
store [1 x { i8*, i8* }]* %_12, [1 x { i8*, i8* }]** %9, align 8, !alias.scope !6, !noalias !9
%10 = getelementptr inbounds %"core::fmt::Arguments", %"core::fmt::Arguments"* %_5, i64 0, i32 5, i32 1
store i64 1, i64* %10, align 8, !alias.scope !6, !noalias !9
; call std::io::stdio::_print
call void @_ZN3std2io5stdio6_print17h717dfda30ab823acE(%"core::fmt::Arguments"* noalias nocapture nonnull dereferenceable(48) %_5)
call void @llvm.lifetime.end.p0i8(i64 48, i8* nonnull %1)
call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %2)
call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0)
ret void
}