HomeArchiveBlog


Original contents are licensed under CC BY-NC 4.0. All rights reserved © 2026 Kai.
Back to Archives
Allo Typing Rules

Type promotion rules for the new Allo frontend.

Sat May 09 2026
Sat May 09 2026
AlloTypingType PromotionHLSC++
On this page
  • Typing Rules
    • Type Categories
    • Common Helpers
    • HLS Rules
      • HLS Integer Add/Sub
      • HLS Integer Mul
      • HLS Other Numeric Operators
      • HLS Shift Operators
      • HLS Unary and Logical Operators
    • C++ Rules
      • C++ Arithmetic Operators
      • C++ Comparisons, Bitwise, and Shifts
      • C++ Unary, Logical, and Math Operators
    • Operator Coverage Summary
    • Notes for Implementers

Typing Rules

Allo uses explicit type-promotion tables when lowering frontend expressions. The active table is selected by KernelOptions(typing_style=...):

@kernel(options=allo.KernelOptions(typing_style="hls"))  # default
def hls_kernel(...):
    ...


@kernel(options=allo.KernelOptions(typing_style="cpp"))
def cpp_kernel(...):
    ...

The two supported styles are:

  • hls: hardware-oriented promotion. Integer +, -, and * are widened to preserve full intermediate precision and are lowered as balanced trees.
  • cpp: C++-like promotion. Integer binary operations select a common integer type and lower according to the expression tree.

If no rule exists for an operator/type combination, compilation fails with a diagnostic such as No hls type promotion rule for operator ....

Type Categories

Typing rules operate on frontend DType categories:

CategoryExamplesNotes
Signed integeri8, i32, apint(23, signed=True)Arbitrary-width signed APInt.
Unsigned integeru1, u32, apint(17)Arbitrary-width unsigned APInt.
Floating pointf16, bf16, f32, f64APFloat values supported by the frontend.
IndexindexOpaque index type used for loop bounds and indexing.
Booleanbool, u1bool is the frontend alias of u1.

The rules below describe element types. For shaped values, the same element promotion is used inside elementwise or linalg operations; shape compatibility is checked separately by the operator.

Common Helpers

Several rules reuse a common integer type selector.

For two integer types with widths L and R:

InputsCommon integer result
Both signedsigned max(L, R)
Both unsignedunsigned max(L, R)
One signed, one unsigned, and unsigned_width >= signed_widthunsigned unsigned_width
One signed, one unsigned, and unsigned_width < signed_widthsigned signed_width

Examples:

Expression typesCommon integer
i16, i32i32
u8, u32u32
i32, u32u32
i32, u16i32

Floating-point common rules are shared by both styles:

  • float op float promotes to the wider float.
  • float op integer keeps the float type.
  • Special math functions convert integers to f32 if their bit width is at most 32, otherwise to f64; floating inputs keep their type.

index has dedicated rules rather than behaving like an integer of a fixed width.

HLS Rules

HLS is the default typing style. It is designed to make arithmetic bit growth explicit for hardware generation.

HLS Integer Add/Sub

For integer-only + and -, HLS uses an n-ary promotion rule over the whole add/sub expression, not just pairwise promotion.

For an expression with N terms:

  1. The result is signed if any operand is signed or any term is subtracted.
  2. If the result is signed, every unsigned operand contributes width + 1 to account for sign conversion.
  3. The result width is max(adjusted_term_widths) + ceil_log2(N).
  4. All terms are cast to that result type.
  5. Subtracted terms are negated.
  6. The final sum is lowered as a balanced addition tree.

Examples:

Expression typesHLS result
i32 + i32i33
u32 + u32u33
u8 + i8i10
i32 + i32 - i32i34
u8 + u8 + u8 + u8u10

The balanced-tree behavior matters for generated hardware. For:

out[0] = a + b + c + d

HLS lowering forms a pairwise tree similar to:

t0 = a + b
t1 = c + d
out = t0 + t1

For a mixed add/sub expression:

out[0] = a + b - c + d

All terms are first cast to the n-ary result type, c is negated, and the normalized terms are reduced by the same balanced addition tree.

Floating-point add/sub is not reassociated by default. When fast_math=False, any expression that may be floating-point is lowered according to the original expression tree. With fast_math=True, floating-point expressions may use the same n-ary lowering path.

HLS Integer Mul

For integer-only multiplication, HLS also uses an n-ary promotion rule:

  1. The result is signed if any operand is signed.
  2. The result width is the sum of all operand widths.
  3. All operands are cast to the result type.
  4. The multiply is lowered as a balanced multiplication tree.

Examples:

Expression typesHLS result
i32 * i32i64
u16 * u16u32
i32 * i32 * i32i96
u8 * i8 * u4i20

HLS Other Numeric Operators

For div, floordiv, mod, pow, comparisons, bitwise operators, and max/min, HLS uses the common numeric rules unless a more specific rule is listed below.

Operator groupHLS promotion
div, floordiv, modCommon numeric type, including index rules.
powCommon numeric type, but index is not accepted.
eq, ne, lt, le, gt, geOperands use common numeric type; result is bool/u1.
max, minCommon numeric type; operation result has that type.
bitwise_and, bitwise_or, bitwise_xorCommon integer type for integer pairs; index only with index.

HLS Shift Operators

Shift operators keep the left-hand type.

InputsResult
signed integer shifted by signed/unsigned integer or indexleft-hand signed type
unsigned integer shifted by signed/unsigned integer or indexleft-hand unsigned type
index shifted by indexindex

index shifted by a plain integer is not currently covered by the rule table.

HLS Unary and Logical Operators

OperatorHLS rule
Unary - on signed/unsigned integersigned integer with width + 1
Unary - on floatsame float type
Unary ~same signed/unsigned/index type
logical_and, logical_oraccepts integer/float numeric pairs and index/index; result is bool/u1
logical_notaccepts integer, float, and index; result is bool/u1
abssame signed/unsigned/float type; index is not accepted

Special math functions in HLS accept signed integers, unsigned integers, and floats. They do not accept index.

C++ Rules

C++ typing style uses the common numeric rules more uniformly. It does not use the HLS integer bit-growth rules for +, -, or *.

C++ Arithmetic Operators

Operator groupC++ promotion
add, sub, mul, div, floordiv, modCommon numeric type, including index rules.
powCommon numeric type, including index rules.
max, minCommon numeric type; operation result has that type.

Examples:

Expression typesC++ result
i32 + i32i32
u32 + u32u32
i32 + u32u32
i16 * i32i32
f32 + i32f32
f32 + f64f64

Promotion is pairwise when an expression contains more than two operands. For a + b + c, the frontend promotes a + b first, then promotes that result with c.

C++ Comparisons, Bitwise, and Shifts

Operator groupC++ promotion
eq, ne, lt, le, gt, geOperands use common numeric type; result is bool/u1.
bitwise_and, bitwise_or, bitwise_xorCommon integer type for integer pairs; index only with index.
lshift, rshiftSame as HLS: result is the left-hand type, with the same supported input pairs.

C++ Unary, Logical, and Math Operators

OperatorC++ rule
Unary -same signed/unsigned/index/float type
Unary ~same signed/unsigned/index type
logical_and, logical_oraccepts integer/float numeric pairs and index/index; result is bool/u1
logical_notaccepts integer, float, and index; result is bool/u1
abssame signed/unsigned/float type; index is not accepted
Special math functionsinteger/index inputs convert to f32 or f64; float inputs keep their type

Because index has a very large opaque primitive width internally, special math functions on index promote to f64 under the current C++ rule table.

Operator Coverage Summary

Operator keyHLSC++
add, subInteger n-ary bit growth; otherwise numeric rulesCommon numeric
mulInteger n-ary full-width product; otherwise numeric rulesCommon numeric
div, floordiv, modCommon numericCommon numeric
powCommon numeric, no indexCommon numeric
eq, ne, lt, le, gt, geCommon numeric operands, bool resultCommon numeric operands, bool result
lshift, rshiftLeft-hand typeLeft-hand type
bitwise_and, bitwise_or, bitwise_xorCommon integer or index/indexCommon integer or index/index
negInteger grows to signed width + 1; float unchangedType unchanged
invertType unchanged for integer/indexType unchanged for integer/index
logical_and, logical_or, logical_notbool resultbool result
Special math functionsIntegers/floats onlyIntegers, index, and floats
absType unchanged for integer/floatType unchanged for integer/float

Notes for Implementers

  • TypeRuleTable.promote() first asks the style-specific n-ary promoter. Only HLS provides one, and it only handles integer add, sub, and mul.
  • If the n-ary promoter returns None, promotion falls back to pairwise lookup from left to right.
  • Comparisons and logical operations use the promoted type to materialize or cast operands, but their final value type is bool/u1.
  • Shift operations do not compute a common type. The result follows the left-hand operand.
  • Unary plus is a no-op in lowering and does not use a promotion-table entry.