← Back to AILP Home

Integer Dispatch & Jump Tables

The most common pick selects on an integer. Arms may be single literals or ranges, and the backend chooses an efficient lowering automatically.

Literal arms

func:failsafe = int32(tbb32:err) { exit 1i32; };
func:main = int32() {
    int32:code = 3;
    pick (code) {
        (0) { exit 0i32; },
        (1) { exit 1i32; },
        (2) { exit 2i32; },
        (3) { exit 3i32; },
        (*) { exit 9i32; }
    }
    exit 0i32;
};

Jump-table lowering

When a pick has several dense integer-literal arms, the IR generator lowers it to an LLVM switch instruction, which LLVM may further turn into a jump table. This makes dispatch O(1) rather than a chain of comparisons.

A pick stays on the jump-table path only when its arms are plain integer literals. The following force the slower compare-chain lowering:

This choice is invisible to program behaviour — it is purely a performance detail.

Ranges and exhaustiveness

The exhaustiveness checker reasons over the full integer domain. A range arm covers a closed interval:

pick (x) {
    (0..9)   { exit 0i32; },
    (10..99) { exit 1i32; },
    (*)      { exit 2i32; }
}

If the literal and range arms together cover the whole domain, the * arm is not required; otherwise the compiler lists the missing intervals, e.g. Missing cases: 100..2147483647.

Duplicate and unreachable arms

Two arms matching the same value are an error (ARIA-PICK-002), and an arm shadowed by an earlier catch-all is reported as unreachable (ARIA-PICK-003).

(K test 031 covers integer dispatch.)