A compiler intrinsic is a function made available through the compiler rather than an ordinary language or library implementation. It gives a program access to functionality the compiler knows about, including features of the target CPU. Atomic operations and exception-handling facilities are examples. section 12.9.2
Intrinsics are useful when ordinary Rust cannot express the required behavior. A small operating-system kernel can call intrinsics::abort() from its panic handler. Another program can use setjmp() and longjmp() to jump out of deeply nested calls instead of returning through each call in turn. section 11.2.3 section 12.9
Using an LLVM intrinsic in Rust requires explicit setup:
- Enable the relevant unstable feature at the crate level. This requires a nightly compiler toolchain. section 12.9.2 section 11.2.3
- Declare an externally provided function with its type signature. For setjmp() and longjmp(), extern "C" selects C calling conventions, while link_name identifies the LLVM function. section 12.9.2
- Call those declared functions inside an unsafe block: Rust knows their signatures, but not enough about their behavior to make their use safe automatically. section 12.9.2
Listing 12.15 Declaring the LLVM intrinsic functions within listing 12.17
extern "C" {
#[link_name = "llvm.eh.sjlj.setjmp"] #1
pub fn setjmp(_: *mut i8) -> i32; #2
#[link_name = "llvm.eh.sjlj.longjmp"] #1
pub fn longjmp(_: *mut i8);
}
Compare each Rust declaration with its link_name. The Rust function name is what the program calls; the attribute names the LLVM intrinsic being linked. section 12.9.2
Listing 11.4 Creating an OS kernel that paints a block of color
1 #![no_std] #1
2 #![no_main] #1
3 #![feature(core_intrinsics)] #2
4
5 use core::intrinsics; #2
6 use core::panic::PanicInfo; #3
7
8 #[panic_handler]
9 #[no_mangle]
10 pub fn panic(_info: &PanicInfo) -> ! {
11 intrinsics::abort(); #4
12 }
13
14 #[no_mangle]
15 pub extern "C" fn _start() -> ! {
16 let framebuffer = 0xb8000 as *mut u8;
17
18 unsafe {
19 framebuffer
20 .offset(1) #5
21 .write_volatile(0x30); #6
22 }
23
24 loop {}
25 }
See a second use in a small kernel: a feature gate enables core intrinsics, and the panic handler calls intrinsics::abort(). section 11.2.3
This access comes with a trade-off. LLVM’s exposed internals are not covered by Rust’s stability guarantees and may change. Use an intrinsic when its extra capability is needed, not as a routine substitute for ordinary Rust. section 11.2.3 section 11.7
