llvm/llvm-project
compiler-rt
compiler-rt/ is the LLVM project's compiler runtime — the helper code that gets emitted alongside compiled programs and that the compiler implicitly links in. It bundles three largely independent groups: builtins (helpers for arithmetic the target can't do natively), sanitizer runtimes (ASan, MSan, TSan, UBSan, etc.), and profile / coverage runtimes (instrumentation-based profiling, source-based coverage).
Purpose
When clang compiles int x = a / b; for an architecture that lacks a native integer-division instruction, it emits a call to __divsi3. That function lives in compiler-rt's builtins. When clang compiles with -fsanitize=address, it links the program against libclang_rt.asan-*.so, also from compiler-rt. Same story for profiling, XRay, and the rest. compiler-rt is a single subproject that hosts all of these.
Directory layout
compiler-rt/
├── lib/
│ ├── builtins/ # __udivsi3, __divti3, __floatdidf, ...
│ ├── asan/ # AddressSanitizer
│ ├── asan_abi/ # Stable ABI shim for ASan
│ ├── tsan/ # ThreadSanitizer
│ ├── msan/ # MemorySanitizer
│ ├── ubsan/ # UndefinedBehaviorSanitizer
│ ├── ubsan_minimal/ # Minimal UBSan for production binaries
│ ├── lsan/ # LeakSanitizer (also runs as a leak-detection mode of ASan)
│ ├── dfsan/ # DataFlowSanitizer
│ ├── nsan/ # NumericSanitizer (FP precision instability)
│ ├── rtsan/ # RealtimeSanitizer
│ ├── tysan/ # TypeSanitizer
│ ├── safestack/ # SafeStack runtime
│ ├── sanitizer_common/ # Shared infrastructure for all sanitizers
│ ├── interception/ # Function-interception primitives (used by sanitizers)
│ ├── stats/ # `-fsanitize=stats` collector
│ ├── memprof/ # Heap-profiling sanitizer
│ ├── ctx_profile/ # Context-sensitive PGO runtime
│ ├── profile/ # instrument-based PGO + source-based coverage
│ ├── gwp_asan/ # Sampling-based ASan-lite
│ ├── scudo/ # Scudo hardened allocator
│ ├── orc/ # ORC JIT runtime helpers
│ ├── xray/ # XRay function-tracing runtime
│ ├── fuzzer/ # libFuzzer
│ ├── crt/ # Bare-metal CRT objects (crtbegin.o, crtend.o, ...)
│ ├── cfi/ # Control-Flow Integrity runtime
│ └── ...
├── include/ # Public headers (sanitizer interface, profile, xray)
├── test/ # End-to-end tests, organized per runtime
├── cmake/
└── README.txtWhat's in each piece
builtins
compiler-rt/lib/builtins/ implements helper symbols for arithmetic and conversions that the codegen emits when the host ISA doesn't have a direct instruction. The set is large: __udivsi3, __divsi3, __udivdi3, __moddi3, __umoddi3, __divti3, __floatdidf, __floatdisf, __floattidf, __fixsfti, atomic helpers, __udivmoddi4, __cmpdf2, ...
sanitizers
The sanitizer runtimes are big and largely share infrastructure (sanitizer_common, interception). Each has its own model:
- ASan — shadow memory marks each byte as poisoned/unpoisoned; ASan's
mallocpaints freshly allocated regions and the runtime checks every load/store against the shadow. - MSan — tracks one-bit "is uninitialized" shadow per byte. Catches reads of uninitialized memory.
- TSan — happens-before tracking for thread-race detection, with a vector clock per thread.
- UBSan — instrumentation that calls a tiny runtime to report undefined behavior (signed overflow, OOB array access, null-this, etc.).
ubsan_minimalis a production-friendly variant. - DFSan — taint tracking via labels propagated alongside data.
- NSan — compares results of FP operations against a higher-precision shadow to flag numerical instabilities.
- RTSan — flags "non-realtime" calls inside code annotated as realtime.
Profile and coverage
compiler-rt/lib/profile/ implements the runtime side of -fprofile-instr-generate and -fprofile-generate. It writes raw profile data that's consumed by llvm-profdata. The same library hosts source-based coverage (-fprofile-instr-generate -fcoverage-mapping).
XRay
compiler-rt/lib/xray/ is a low-overhead, function-level dynamic-tracing runtime. Each compiled function gets a no-op patch point that XRay rewrites at runtime to enable/disable instrumentation.
libFuzzer
compiler-rt/lib/fuzzer/ is the in-process coverage-guided fuzzing engine consumed by -fsanitize=fuzzer.
How it builds
compiler-rt is a runtime library, so it's built via LLVM_ENABLE_RUNTIMES, not LLVM_ENABLE_PROJECTS. A typical configuration:
-DLLVM_ENABLE_RUNTIMES=compiler-rt
-DCOMPILER_RT_BUILD_BUILTINS=ON
-DCOMPILER_RT_BUILD_SANITIZERS=ON
-DCOMPILER_RT_BUILD_PROFILE=ON
-DCOMPILER_RT_BUILD_XRAY=ONSanitizers in particular are sensitive to host config; expect to set -DCOMPILER_RT_BUILD_*=OFF for the components you don't need to keep build times reasonable.
How it works (sanitizer flow)
graph LR
src[User source] -->|"-fsanitize=address"| clang[clang]
clang -->|"insert shadow checks +<br/>replace malloc/free"| ir[Instrumented IR]
ir --> obj[Instrumented object]
obj --> link[Link]
link --> bin[Sanitized binary]
bin -->|runtime malloc/free,<br/>shadow paints,<br/>error reporting| rt[compiler-rt asan]
rt -->|on error| report[Crash report + symbolize]Integration points
- Clang / Flang emit calls into compiler-rt for builtins, sanitizer instrumentation, profile counters, and XRay sleds.
- lld (
lld) is the linker that ties the runtime in. - Offload / OpenMP can consume sanitizer pieces for accelerator code where the runtime supports it.
- Scudo and GWP-ASan are deployable in production binaries even without the full sanitizer overhead.
Entry points for modification
- Adding a builtin: source under
compiler-rt/lib/builtins/. Most of these are small and follow a consistent pattern. - Adding a sanitizer check: split between Clang-side instrumentation (under
llvm/lib/Transforms/Instrumentation/and Clang's-fsanitize=plumbing) and the runtime side here. - Tuning shadow layout / allocator: live in
lib/asan/,lib/sanitizer_common/,lib/scudo/. These are sensitive to ABI breakage on existing platforms.
Reference
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
openmp
Next
bolt