| status | active |
|---|---|
| audience | public |
| last-verified | 2026-04-09 |
Get started with Viper's Intermediate Language (IL) in minutes. This guide shows you how to write, verify, and execute IL programs.
Viper IL is a typed, readable intermediate language that serves as the core of the Viper toolchain:
- Frontends (Zia, BASIC, etc.) compile to IL
- VM executes IL directly
- Verifier checks IL for safety and correctness
- Transforms (SimplifyCFG, Liveness, etc.) optimize IL
- Backends compile IL to native code
IL is designed to be human-readable and easy to inspect, making it ideal for learning compiler concepts and debugging.
Create a file hello.il:
il 0.2.0
extern @Viper.Terminal.PrintStr(str) -> void
global const str @.msg = "Hello, Viper IL!"
func @main() -> i64 {
entry:
%msg = const_str @.msg
call @Viper.Terminal.PrintStr(%msg)
ret 0
}Compatibility:
- When built with
-DVIPER_RUNTIME_NS_DUAL=ON, legacy@rt_*externs are accepted as aliases of@Viper.*. - New code should emit
@Viper.*.
il-verify hello.ilThe verifier checks types, control flow, and instruction well-formedness. No output means success!
viper -run hello.ilOutput:
Hello, Viper IL!
Every IL file starts with a version declaration:
il 0.2.0This pins the expected IL grammar version.
Declare runtime functions you'll call:
extern @Viper.Terminal.PrintI64(i64) -> void
extern @Viper.String.Concat(str, str) -> strDefine immutable data:
global const str @.hello = "Hello!"
global const i64 @.answer = 42Functions contain basic blocks and instructions:
func @square(i64 %x) -> i64 {
entry:
%result = imul.ovf %x, %x
ret %result
}Key points:
@name— Function symbol%var— SSA register (assigned once, used many times)entry:— First basic block labelret— Return terminator (required at end of block)- Signed integer arithmetic uses overflow-checked opcodes (
iadd.ovf,isub.ovf,imul.ovf); the plainadd/sub/mulopcodes are rejected by the verifier.
func @add(i64 %a, i64 %b) -> i64 {
entry:
%sum = iadd.ovf %a, %b
ret %sum
}func @max(i64 %a, i64 %b) -> i64 {
entry:
%cond = scmp_gt %a, %b
cbr %cond, greater, less_or_equal
greater:
ret %a
less_or_equal:
ret %b
}func @square(i64 %x) -> i64 {
entry:
%result = imul.ovf %x, %x
ret %result
}
func @call_square(i64 %y) -> i64 {
entry:
%result = call @square(%y)
ret %result
}func @classify(i64 %n) -> i64 {
entry:
%n32:i32 = cast.si_narrow.chk %n
switch.i32 %n32, ^default, 0 -> ^zero, 1 -> ^one, 2 -> ^two
default:
ret 99
zero:
ret 0
one:
ret 10
two:
ret 20
}Check IL files for correctness:
il-verify program.ilThe verifier catches:
- Type mismatches
- Missing terminators
- Invalid control flow
- Undefined references
Pretty-print IL files:
il-dis program.ilRun IL programs on the VM:
viper -run program.ilApply optimization passes:
viper il-opt program.il --passes "simplify-cfg" -o optimized.ilPreset pipelines via viper il-opt:
# O1 (default): SimplifyCFG → Mem2Reg → SimplifyCFG → SCCP → ConstFold →
# Peephole → DCE → SimplifyCFG → SCCP → Inline → Peephole →
# DCE → SimplifyCFG
viper il-opt program.il --pipeline O1 -o program.o1.il
# O2: SimplifyCFG → Mem2Reg → SimplifyCFG → LoopSimplify → LICM → LoopRotate →
# IndVars → LoopUnroll → SimplifyCFG → SCCP → CheckOpt → EHOpt → DCE →
# SimplifyCFG → SiblingRecursion → Inline → SimplifyCFG → SCCP →
# ConstFold → Peephole → DCE → SimplifyCFG → GVN → Reassociate →
# EarlyCSE → DSE → DCE → LateCleanup
viper il-opt program.il --pipeline O2 -o program.o2.il
# Custom sequence
viper il-opt program.il --passes "simplify-cfg,sccp,dce" -o out.ilAvailable passes: check-opt, constfold, dce, dse, earlycse, ehopt, gvn, indvars, inline, late-cleanup, licm, licm-safe, loop-rotate, loop-simplify, loop-unroll, mem2reg, peephole, reassociate, sccp, simplify-cfg
Focused validation pipelines are also addressable by name: rehab-mem2reg, rehab-peephole, and rehab-licm.
Learn More:
- IL Reference — Complete instruction catalog
- IL Guide — Comprehensive guide with examples
- Frontend How-To — Build your own frontend
Explore:
- Check
src/tests/golden/il/for more IL examples - Run
viper --helpfor all available options - Experiment with optimization passes