Skip to main content

7  Compiler Intrinsics (%)

Intrinsics are compiler-built-in operations prefixed with % that lower directly to LLVM target instructions or intrinsics with zero call overhead.

Rule Specification Diagnostic
Direct invocation Must be called immediately with (...) (%min(a, b)); bare %min is rejected E3100
Strict typing No implicit integer/float coercion; multi-argument intrinsics require matching numeric widths E3084
SIMD vector broadcasting Homogeneous tuples (T * N) act as hardware SIMD vectors; scalar arguments passed alongside (T * N) are automatically splatted across all N lanes —
#use io

low = %min(10, 20)
root = %sqrt(16.0)
bits = %popcount(7)
vec = (10, 20, 30)
clamped = %clamp(vec, 12, 25)
io::out $ (low, root, bits, clamped, %to_str(42))

7.1 Numeric and SIMD vector operations

Intrinsic Argument Types Return Type LLVM Lowering Notes
%min(a, b) Int / (Int * N) or Float / (Float * N) Same as args @llvm.smin / @llvm.minnum Broadcasts scalar with vector
%max(a, b) Int / (Int * N) or Float / (Float * N) Same as args @llvm.smax / @llvm.maxnum Broadcasts scalar with vector
%clamp(x, lo, hi) Int / (Int * N) or Float / (Float * N) Same as args @llvm.smin+smax / minnum+maxnum Bounds x to [lo, hi]
%abs(x) Int / (Int * N) or Float / (Float * N) Same as arg @llvm.abs / @llvm.fabs Magnitude of x
%shuffle(v, m) v: (T * N), m: (Int * M) literal (T * M) shufflevector T in Int, Float, <>; m is compile-time lane mask
%shuffle(a, b, m) a, b: (T * N), m: (Int * M) literal (T * M) shufflevector Two-source lane permutation (0..2*N-1)

7.2 Horizontal vector reductions

Intrinsic Argument Types Return Type LLVM Lowering Semantics
%all(v) (<> * N) <> @llvm.vector.reduce.and <+> iff all N flag lanes are <+>
%any(v) (<> * N) <> @llvm.vector.reduce.or <+> iff at least one flag lane is <+>
%sum(v) (Int * N) or (Float * N) Int or Float @llvm.vector.reduce.add / fadd Horizontal lane sum
%prod(v) (Int * N) or (Float * N) Int or Float @llvm.vector.reduce.mul / fmul Horizontal lane product
%dot(a, b) Matching (Int * N) or (Float * N) Int or Float Lane mul + horizontal add Euclidean dot product \(\sum a_i b_i\)

7.3 Floating-point math

All floating-point intrinsics require Float (f64), f32, or homogeneous SIMD tuples (Float * N) / (f32 * N). Integer arguments require explicit Float(n) conversion.

Intrinsic Argument Types Return Type LLVM Lowering
%sqrt(x) Float / (Float * N) Same as arg @llvm.sqrt
%fma(a, b, c) Float / (Float * N) Same as args @llvm.fma (fused \(a \cdot b + c\), single rounding)
%fmuladd(a, b, c) Float / (Float * N) Same as args @llvm.fmuladd
%floor(x) Float / (Float * N) Same as arg @llvm.floor
%ceil(x) Float / (Float * N) Same as arg @llvm.ceil
%trunc(x) Float / (Float * N) Same as arg @llvm.trunc
%round(x) Float / (Float * N) Same as arg @llvm.round
%copysign(m, s) Float / (Float * N) Same as args @llvm.copysign
%sin(x) Float / (Float * N) Same as arg @llvm.sin
%cos(x) Float / (Float * N) Same as arg @llvm.cos
%exp2(x) Float / (Float * N) Same as arg @llvm.exp2
%log2(x) Float / (Float * N) Same as arg @llvm.log2
%pow(x, y) Float / (Float * N) Same as args @llvm.pow

7.4 Bit manipulation, saturating arithmetic, and bitcasting

Intrinsic Argument Types Return Type LLVM Lowering Semantics
%popcount(x) Int / (Int * N) Same as arg @llvm.ctpop Count set 1 bits
%clz(x) Int / (Int * N) Same as arg @llvm.ctlz Count leading zeros
%ctz(x) Int / (Int * N) Same as arg @llvm.cttz Count trailing zeros
%bswap(x) Int / (Int * N) Same as arg @llvm.bswap Reverse byte order (endian swap)
%bitreverse(x) Int / (Int * N) Same as arg @llvm.bitreverse Reverse bit order
%rotl(x, n) Int / (Int * N) Same as x @llvm.fshl Funnel rotate left by n bits
%rotr(x, n) Int / (Int * N) Same as x @llvm.fshr Funnel rotate right by n bits
%uadd_sat(a, b) Int / (Int * N) Same as args @llvm.uadd.sat Unsigned saturating addition
%usub_sat(a, b) Int / (Int * N) Same as args @llvm.usub.sat Unsigned saturating subtraction (clamps at 0)
%bitcast(T, x) T: target type, x: equal-width scalar/tuple T bitcast Reinterprets raw bits without numeric conversion (E3084 on width mismatch)

7.5 Memory primitives and scalar formatting

Intrinsic Argument Types Return Type LLVM Lowering Semantics
%memcpy(dst, src, n) dst: Addr, src: Addr, n: Int Addr (dst) @llvm.memcpy Copies n bytes between non-overlapping regions
%memmove(dst, src, n) dst: Addr, src: Addr, n: Int Addr (dst) @llvm.memmove Copies n bytes (overlapping regions safe)
%memset(dst, val, n) dst: Addr, val: Int, n: Int Addr (dst) @llvm.memset Fills n bytes at dst with u8(val)
%ptrmask(ptr, mask) ptr: Addr, mask: Int Addr @llvm.ptrmask Masks pointer bits while preserving LLVM pointer provenance
%to_str(x) Int, i8..u64, Float, f32, Rune, String String Runtime arena format Formats scalar into arena String (E3105 on composites); backs "${expr}"