Comb
‘comb’ Dialect
Types and operations for comb dialect
This dialect defines the comb
dialect, which is intended to be a generic
representation of combinational logic outside of a particular use-case.
Operations
comb.add
(heir::comb::AddOp)
Syntax:
operation ::= `comb.add` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.and
(heir::comb::AndOp)
Syntax:
operation ::= `comb.and` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.concat
(heir::comb::ConcatOp)
Concatenate a variadic list of operands together.
Syntax:
operation ::= `comb.concat` $inputs attr-dict `:` qualified(type($inputs))
See the comb rationale document for details on operand ordering.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.extract
(heir::comb::ExtractOp)
Extract a range of bits into a smaller value, lowBit specifies the lowest bit included.
Syntax:
operation ::= `comb.extract` $input `from` $lowBit attr-dict `:` functional-type($input, $result)
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
lowBit | ::mlir::IntegerAttr | 32-bit signless integer attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.icmp
(heir::comb::ICmpOp)
Compare two integer values
Syntax:
operation ::= `comb.icmp` (`bin` $twoState^)? $predicate $lhs `,` $rhs attr-dict `:` qualified(type($lhs))
This operation compares two integers using a predicate. If the predicate is true, returns 1, otherwise returns 0. This operation always returns a one bit wide result.
%r = comb.icmp eq %a, %b : i4
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
predicate | ::mlir::heir::comb::ICmpPredicateAttr | hw.icmp comparison predicate |
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
lhs | signless integer |
rhs | signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.inv
(heir::comb::InvOp)
Syntax:
operation ::= `comb.inv` (`bin` $twoState^)? $input attr-dict `:` qualified(type($input))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.lut
(heir::comb::LUTOp)
Return an integer based on a lookup table
Syntax:
operation ::= `comb.lut` operands attr-dict `:` functional-type(operands, results)
This operation is similar to truth_table
, but it allows for an integer output instead of a boolean.
Requers an vector of integers as the lookup table, where each integer represents the output for a specific combination of inputs.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
coefficients | ::mlir::DenseI8ArrayAttr | i8 dense array attribute |
lookupTable | ::mlir::DenseI8ArrayAttr | i8 dense array attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of 8-bit signless integer |
Results:
Result | Description |
---|---|
result | 8-bit signless integer |
comb.mul
(heir::comb::MulOp)
Syntax:
operation ::= `comb.mul` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.mux
(heir::comb::MuxOp)
Return one or the other operand depending on a selector bit
Syntax:
operation ::= `comb.mux` (`bin` $twoState^)? $cond `,` $trueValue `,` $falseValue attr-dict `:` qualified(type($result))
%0 = mux %pred, %tvalue, %fvalue : i4
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
cond | 1-bit signless integer |
trueValue | any type |
falseValue | any type |
Results:
Result | Description |
---|---|
result | any type |
comb.nand
(heir::comb::NandOp)
Syntax:
operation ::= `comb.nand` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.nor
(heir::comb::NorOp)
Syntax:
operation ::= `comb.nor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.or
(heir::comb::OrOp)
Syntax:
operation ::= `comb.or` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.parity
(heir::comb::ParityOp)
Syntax:
operation ::= `comb.parity` (`bin` $twoState^)? $input attr-dict `:` qualified(type($input))
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.replicate
(heir::comb::ReplicateOp)
Concatenate the operand a constant number of times
Syntax:
operation ::= `comb.replicate` $input attr-dict `:` functional-type($input, $result)
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.truth_table
(heir::comb::TruthTableOp)
Return a true/false based on a lookup table
Syntax:
operation ::= `comb.truth_table` $inputs `->` $lookupTable attr-dict
%a = ... : i1
%b = ... : i1
%0 = comb.truth_table %a, %b -> 6 : ui4
This operation assumes that the lookup table is described as an integer of
2^n bits to fully specify the table. Inputs are sorted MSB -> LSB from left
to right and the offset into lookupTable
is computed from them. The
integer containing the truth table value’s LSB is the output for the input
“all false”, and the MSB is the output for the input “all true”.
No difference from array_get into an array of constants except for xprop behavior. If one of the inputs is unknown, but said input doesn’t make a difference in the output (based on the lookup table) the result should not be ‘x’ – it should be the well-known result.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, LUTOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
lookupTable | ::mlir::IntegerAttr | An Attribute containing a integer value |
Operands:
Operand | Description |
---|---|
inputs | variadic of 1-bit signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.xnor
(heir::comb::XNorOp)
Syntax:
operation ::= `comb.xnor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.xor
(heir::comb::XorOp)
Syntax:
operation ::= `comb.xor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
Enums
ICmpPredicate
Hw.icmp comparison predicate
Cases:
Symbol | Value | String |
---|---|---|
eq | 0 | eq |
ne | 1 | ne |
slt | 2 | slt |
sle | 3 | sle |
sgt | 4 | sgt |
sge | 5 | sge |
ult | 6 | ult |
ule | 7 | ule |
ugt | 8 | ugt |
uge | 9 | uge |
ceq | 10 | ceq |
cne | 11 | cne |
weq | 12 | weq |
wne | 13 | wne |
Comb types
BFloat16Type
Bfloat16 floating-point type
ComplexType
Complex number with a parameterized element type
Syntax:
complex-type ::= `complex` `<` type `>`
The value of complex
type represents a complex number with a parameterized
element type, which is composed of a real and imaginary value of that
element type. The element must be a floating point or integer scalar type.
Example:
complex<f32>
complex<i32>
Parameters:
Parameter | C++ type | Description |
---|---|---|
elementType | Type |
Float4E2M1FNType
4-bit floating point with 2-bit exponent and 1-bit mantissa
An 4-bit floating point type with 1 sign bit, 2 bits exponent and 1 bit mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E2M1
- exponent bias: 1
- infinities: Not supported
- NaNs: Not supported
- denormals when exponent is 0
Open Compute Project (OCP) microscaling formats (MX) specification: https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
Float6E2M3FNType
6-bit floating point with 2-bit exponent and 3-bit mantissa
An 6-bit floating point type with 1 sign bit, 2 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E2M3
- exponent bias: 1
- infinities: Not supported
- NaNs: Not supported
- denormals when exponent is 0
Open Compute Project (OCP) microscaling formats (MX) specification: https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
Float6E3M2FNType
6-bit floating point with 3-bit exponent and 2-bit mantissa
An 6-bit floating point type with 1 sign bit, 3 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E3M2
- exponent bias: 3
- infinities: Not supported
- NaNs: Not supported
- denormals when exponent is 0
Open Compute Project (OCP) microscaling formats (MX) specification: https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
Float8E3M4Type
8-bit floating point with 3 bits exponent and 4 bit mantissa
An 8-bit floating point type with 1 sign bit, 3 bits exponent and 4 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E3M4
- exponent bias: 3
- infinities: supported with exponent set to all 1s and mantissa 0s
- NaNs: supported with exponent bits set to all 1s and mantissa values of {0,1}⁴ except S.111.0000
- denormals when exponent is 0
Float8E4M3Type
8-bit floating point with 3 bit mantissa
An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E4M3
- exponent bias: 7
- infinities: supported with exponent set to all 1s and mantissa 0s
- NaNs: supported with exponent bits set to all 1s and mantissa of (001, 010, 011, 100, 101, 110, 111)
- denormals when exponent is 0
Float8E4M3B11FNUZType
8-bit floating point with 3 bit mantissa
An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:
- bit encoding: S1E4M3
- exponent bias: 11
- infinities: Not supported
- NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s
- denormals when exponent is 0
Related to: https://dl.acm.org/doi/10.5555/3454287.3454728
Float8E4M3FNType
8-bit floating point with 3 bit mantissa
An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values and only two NaN representations. This type has the following characteristics:
- bit encoding: S1E4M3
- exponent bias: 7
- infinities: Not supported
- NaNs: supported with exponent bits and mantissa bits set to all 1s
- denormals when exponent is 0
Described in: https://arxiv.org/abs/2209.05433
Float8E4M3FNUZType
8-bit floating point with 3 bit mantissa
An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:
- bit encoding: S1E4M3
- exponent bias: 8
- infinities: Not supported
- NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s
- denormals when exponent is 0
Described in: https://arxiv.org/abs/2209.05433
Float8E5M2Type
8-bit floating point with 2 bit mantissa
An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions with the following characteristics:
- bit encoding: S1E5M2
- exponent bias: 15
- infinities: supported with exponent set to all 1s and mantissa 0s
- NaNs: supported with exponent bits set to all 1s and mantissa of (01, 10, or 11)
- denormals when exponent is 0
Described in: https://arxiv.org/abs/2209.05433
Float8E5M2FNUZType
8-bit floating point with 2 bit mantissa
An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits mantissa. This is not a standard type as defined by IEEE-754, but it follows similar conventions, with the exception that there are no infinity values, no negative zero, and only one NaN representation. This type has the following characteristics:
- bit encoding: S1E5M2
- exponent bias: 16
- infinities: Not supported
- NaNs: Supported with sign bit set to 1, exponent bits and mantissa bits set to all 0s
- denormals when exponent is 0
Described in: https://arxiv.org/abs/2206.02915
Float8E8M0FNUType
8-bit floating point with 8-bit exponent, no mantissa or sign
An 8-bit floating point type with no sign bit, 8 bits exponent and no mantissa. This is not a standard type as defined by IEEE-754; it is intended to be used for representing scaling factors, so it cannot represent zeros and negative numbers. The values it can represent are powers of two in the range [-127,127] and NaN.
- bit encoding: S0E8M0
- exponent bias: 127
- infinities: Not supported
- NaNs: Supported with all bits set to 1
- denormals: Not supported
Open Compute Project (OCP) microscaling formats (MX) specification: https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
Float16Type
16-bit floating-point type
Float32Type
32-bit floating-point type
Float64Type
64-bit floating-point type
Float80Type
80-bit floating-point type
Float128Type
128-bit floating-point type
FloatTF32Type
TF32 floating-point type
FunctionType
Map from a list of inputs to a list of results
Syntax:
// Function types may have multiple results.
function-result-type ::= type-list-parens | non-function-type
function-type ::= type-list-parens `->` function-result-type
The function type can be thought of as a function signature. It consists of a list of formal parameter types and a list of formal result types.
Example:
func.func @add_one(%arg0 : i64) -> i64 {
%c1 = arith.constant 1 : i64
%0 = arith.addi %arg0, %c1 : i64
return %0 : i64
}
Parameters:
Parameter | C++ type | Description |
---|---|---|
inputs | ArrayRef<Type> | |
results | ArrayRef<Type> |
GraphType
Map from a list of inputs to a list of results
Syntax:
// Function types may have multiple results.
function-result-type ::= type-list-parens | non-function-type
function-type ::= type-list-parens `->` function-result-type
The function type can be thought of as a function signature. It consists of a list of formal parameter types and a list of formal result types.
Example:
func.func @add_one(%arg0 : i64) -> i64 {
%c1 = arith.constant 1 : i64
%0 = arith.addi %arg0, %c1 : i64
return %0 : i64
}
Parameters:
Parameter | C++ type | Description |
---|---|---|
inputs | ArrayRef<Type> | |
results | ArrayRef<Type> |
IndexType
Integer-like type with unknown platform-dependent bit width
Syntax:
// Target word-sized integer.
index-type ::= `index`
The index type is a signless integer whose size is equal to the natural machine word of the target ( rationale ) and is used by the affine constructs in MLIR.
Rationale: integers of platform-specific bit widths are practical to express sizes, dimensionalities and subscripts.
IntegerType
Integer type with arbitrary precision up to a fixed limit
Syntax:
// Sized integers like i1, i4, i8, i16, i32.
signed-integer-type ::= `si` [1-9][0-9]*
unsigned-integer-type ::= `ui` [1-9][0-9]*
signless-integer-type ::= `i` [1-9][0-9]*
integer-type ::= signed-integer-type |
unsigned-integer-type |
signless-integer-type
Integer types have a designated bit width and may optionally have signedness semantics.
Rationale: low precision integers (like i2
, i4
etc) are useful for
low-precision inference chips, and arbitrary precision integers are useful
for hardware synthesis (where a 13 bit multiplier is a lot cheaper/smaller
than a 16 bit one).
Parameters:
Parameter | C++ type | Description |
---|---|---|
width | unsigned | |
signedness | SignednessSemantics |
MemRefType
Shaped reference to a region of memory
Syntax:
layout-specification ::= attribute-value
memory-space ::= attribute-value
memref-type ::= `memref` `<` dimension-list-ranked type
(`,` layout-specification)? (`,` memory-space)? `>`
A memref
type is a reference to a region of memory (similar to a buffer
pointer, but more powerful). The buffer pointed to by a memref can be
allocated, aliased and deallocated. A memref can be used to read and write
data from/to the memory region which it references. Memref types use the
same shape specifier as tensor types. Note that memref<f32>
,
memref<0 x f32>
, memref<1 x 0 x f32>
, and memref<0 x 1 x f32>
are all
different types.
A memref
is allowed to have an unknown rank (e.g. memref<*xf32>
). The
purpose of unranked memrefs is to allow external library functions to
receive memref arguments of any rank without versioning the functions based
on the rank. Other uses of this type are disallowed or will have undefined
behavior.
Are accepted as elements:
- built-in integer types;
- built-in index type;
- built-in floating point types;
- built-in vector types with elements of the above types;
- another memref type;
- any other type implementing
MemRefElementTypeInterface
.
Layout
A memref may optionally have a layout that indicates how indices are
transformed from the multi-dimensional form into a linear address. The
layout must avoid internal aliasing, i.e., two distinct tuples of
in-bounds indices must be pointing to different elements in memory. The
layout is an attribute that implements MemRefLayoutAttrInterface
. The
bulitin dialect offers two kinds of layouts: strided and affine map, each
of which is available as an attribute. Other attributes may be used to
represent the layout as long as they can be converted to a
semi-affine map and implement the required
interface. Users of memref are expected to fallback to the affine
representation when handling unknown memref layouts. Multi-dimensional
affine forms are interpreted in row-major fashion.
In absence of an explicit layout, a memref is considered to have a
multi-dimensional identity affine map layout. Identity layout maps do not
contribute to the MemRef type identification and are discarded on
construction. That is, a type with an explicit identity map is
memref<?x?xf32, (i,j)->(i,j)>
is strictly the same as the one without a
layout, memref<?x?xf32>
.
Affine Map Layout
The layout may be represented directly as an affine map from the index space
to the storage space. For example, the following figure shows an index map
which maps a 2-dimensional index from a 2x2 index space to a 3x3 index
space, using symbols S0
and S1
as offsets.
Semi-affine maps are sufficiently flexible to represent a wide variety of dense storage layouts, including row- and column-major and tiled:
// MxN matrix stored in row major layout in memory:
#layout_map_row_major = (i, j) -> (i, j)
// MxN matrix stored in column major layout in memory:
#layout_map_col_major = (i, j) -> (j, i)
// MxN matrix stored in a 2-d blocked/tiled layout with 64x64 tiles.
#layout_tiled = (i, j) -> (i floordiv 64, j floordiv 64, i mod 64, j mod 64)
Strided Layout
Memref layout can be expressed using strides to encode the distance, in
number of elements, in (linear) memory between successive entries along a
particular dimension. For example, a row-major strided layout for
memref<2x3x4xf32>
is strided<[12, 4, 1]>
, where the last dimension is
contiguous as indicated by the unit stride and the remaining strides are
products of the sizes of faster-variying dimensions. Strided layout can also
express non-contiguity, e.g., memref<2x3, strided<[6, 2]>>
only accesses
even elements of the dense consecutive storage along the innermost
dimension.
The strided layout supports an optional offset that indicates the
distance, in the number of elements, between the beginning of the memref
and the first accessed element. When omitted, the offset is considered to
be zero. That is, memref<2, strided<[2], offset: 0>>
and
memref<2, strided<[2]>>
are strictly the same type.
Both offsets and strides may be dynamic, that is, unknown at compile time.
This is represented by using a question mark (?
) instead of the value in
the textual form of the IR.
The strided layout converts into the following canonical one-dimensional affine form through explicit linearization:
affine_map<(d0, ... dN)[offset, stride0, ... strideN] ->
(offset + d0 * stride0 + ... dN * strideN)>
Therefore, it is never subject to the implicit row-major layout interpretation.
Codegen of Unranked Memref
Using unranked memref in codegen besides the case mentioned above is highly discouraged. Codegen is concerned with generating loop nests and specialized instructions for high-performance, unranked memref is concerned with hiding the rank and thus, the number of enclosing loops required to iterate over the data. However, if there is a need to code-gen unranked memref, one possible path is to cast into a static ranked type based on the dynamic rank. Another possible path is to emit a single while loop conditioned on a linear index and perform delinearization of the linear index to a dynamic array containing the (unranked) indices. While this is possible, it is expected to not be a good idea to perform this during codegen as the cost of the translations is expected to be prohibitive and optimizations at this level are not expected to be worthwhile. If expressiveness is the main concern, irrespective of performance, passing unranked memrefs to an external C++ library and implementing rank-agnostic logic there is expected to be significantly simpler.
Unranked memrefs may provide expressiveness gains in the future and help bridge the gap with unranked tensors. Unranked memrefs will not be expected to be exposed to codegen but one may query the rank of an unranked memref (a special op will be needed for this purpose) and perform a switch and cast to a ranked memref as a prerequisite to codegen.
Example:
// With static ranks, we need a function for each possible argument type
%A = alloc() : memref<16x32xf32>
%B = alloc() : memref<16x32x64xf32>
call @helper_2D(%A) : (memref<16x32xf32>)->()
call @helper_3D(%B) : (memref<16x32x64xf32>)->()
// With unknown rank, the functions can be unified under one unranked type
%A = alloc() : memref<16x32xf32>
%B = alloc() : memref<16x32x64xf32>
// Remove rank info
%A_u = memref_cast %A : memref<16x32xf32> -> memref<*xf32>
%B_u = memref_cast %B : memref<16x32x64xf32> -> memref<*xf32>
// call same function with dynamic ranks
call @helper(%A_u) : (memref<*xf32>)->()
call @helper(%B_u) : (memref<*xf32>)->()
The core syntax and representation of a layout specification is a
semi-affine map. Additionally,
syntactic sugar is supported to make certain layout specifications more
intuitive to read. For the moment, a memref
supports parsing a strided
form which is converted to a semi-affine map automatically.
The memory space of a memref is specified by a target-specific attribute. It might be an integer value, string, dictionary or custom dialect attribute. The empty memory space (attribute is None) is target specific.
The notionally dynamic value of a memref value includes the address of the buffer allocated, as well as the symbols referred to by the shape, layout map, and index maps.
Examples of memref static type
// Identity index/layout map
#identity = affine_map<(d0, d1) -> (d0, d1)>
// Column major layout.
#col_major = affine_map<(d0, d1, d2) -> (d2, d1, d0)>
// A 2-d tiled layout with tiles of size 128 x 256.
#tiled_2d_128x256 = affine_map<(d0, d1) -> (d0 div 128, d1 div 256, d0 mod 128, d1 mod 256)>
// A tiled data layout with non-constant tile sizes.
#tiled_dynamic = affine_map<(d0, d1)[s0, s1] -> (d0 floordiv s0, d1 floordiv s1,
d0 mod s0, d1 mod s1)>
// A layout that yields a padding on two at either end of the minor dimension.
#padded = affine_map<(d0, d1) -> (d0, (d1 + 2) floordiv 2, (d1 + 2) mod 2)>
// The dimension list "16x32" defines the following 2D index space:
//
// { (i, j) : 0 <= i < 16, 0 <= j < 32 }
//
memref<16x32xf32, #identity>
// The dimension list "16x4x?" defines the following 3D index space:
//
// { (i, j, k) : 0 <= i < 16, 0 <= j < 4, 0 <= k < N }
//
// where N is a symbol which represents the runtime value of the size of
// the third dimension.
//
// %N here binds to the size of the third dimension.
%A = alloc(%N) : memref<16x4x?xf32, #col_major>
// A 2-d dynamic shaped memref that also has a dynamically sized tiled
// layout. The memref index space is of size %M x %N, while %B1 and %B2
// bind to the symbols s0, s1 respectively of the layout map #tiled_dynamic.
// Data tiles of size %B1 x %B2 in the logical space will be stored
// contiguously in memory. The allocation size will be
// (%M ceildiv %B1) * %B1 * (%N ceildiv %B2) * %B2 f32 elements.
%T = alloc(%M, %N) [%B1, %B2] : memref<?x?xf32, #tiled_dynamic>
// A memref that has a two-element padding at either end. The allocation
// size will fit 16 * 64 float elements of data.
%P = alloc() : memref<16x64xf32, #padded>
// Affine map with symbol 's0' used as offset for the first dimension.
#imapS = affine_map<(d0, d1) [s0] -> (d0 + s0, d1)>
// Allocate memref and bind the following symbols:
// '%n' is bound to the dynamic second dimension of the memref type.
// '%o' is bound to the symbol 's0' in the affine map of the memref type.
%n = ...
%o = ...
%A = alloc (%n)[%o] : <16x?xf32, #imapS>
Parameters:
Parameter | C++ type | Description |
---|---|---|
shape | ::llvm::ArrayRef<int64_t> | |
elementType | Type | |
layout | MemRefLayoutAttrInterface | |
memorySpace | Attribute |
NoneType
A unit type
Syntax:
none-type ::= `none`
NoneType is a unit type, i.e. a type with exactly one possible value, where its value does not have a defined dynamic representation.
Example:
func.func @none_type() {
%none_val = "foo.unknown_op"() : () -> none
return
}
OpaqueType
Type of a non-registered dialect
Syntax:
opaque-type ::= `opaque` `<` type `>`
Opaque types represent types of non-registered dialects. These are types represented in their raw string form, and can only usefully be tested for type equality.
Example:
opaque<"llvm", "struct<(i32, float)>">
opaque<"pdl", "value">
Parameters:
Parameter | C++ type | Description |
---|---|---|
dialectNamespace | StringAttr | |
typeData | ::llvm::StringRef |
RankedTensorType
Multi-dimensional array with a fixed number of dimensions
Syntax:
tensor-type ::= `tensor` `<` dimension-list type (`,` encoding)? `>`
dimension-list ::= (dimension `x`)*
dimension ::= `?` | decimal-literal
encoding ::= attribute-value
Values with tensor type represents aggregate N-dimensional data values, and
have a known element type and a fixed rank with a list of dimensions. Each
dimension may be a static non-negative decimal constant or be dynamically
determined (indicated by ?
).
The runtime representation of the MLIR tensor type is intentionally
abstracted - you cannot control layout or get a pointer to the data. For
low level buffer access, MLIR has a memref
type. This
abstracted runtime representation holds both the tensor data values as well
as information about the (potentially dynamic) shape of the tensor. The
dim
operation returns the size of a
dimension from a value of tensor type.
The encoding
attribute provides additional information on the tensor.
An empty attribute denotes a straightforward tensor without any specific
structure. But particular properties, like sparsity or other specific
characteristics of the data of the tensor can be encoded through this
attribute. The semantics are defined by a type and attribute interface
and must be respected by all passes that operate on tensor types.
TODO: provide this interface, and document it further.
Note: hexadecimal integer literals are not allowed in tensor type
declarations to avoid confusion between 0xf32
and 0 x f32
. Zero sizes
are allowed in tensors and treated as other sizes, e.g.,
tensor<0 x 1 x i32>
and tensor<1 x 0 x i32>
are different types. Since
zero sizes are not allowed in some other types, such tensors should be
optimized away before lowering tensors to vectors.
Example:
// Known rank but unknown dimensions.
tensor<? x ? x ? x ? x f32>
// Partially known dimensions.
tensor<? x ? x 13 x ? x f32>
// Full static shape.
tensor<17 x 4 x 13 x 4 x f32>
// Tensor with rank zero. Represents a scalar.
tensor<f32>
// Zero-element dimensions are allowed.
tensor<0 x 42 x f32>
// Zero-element tensor of f32 type (hexadecimal literals not allowed here).
tensor<0xf32>
// Tensor with an encoding attribute (where #ENCODING is a named alias).
tensor<?x?xf64, #ENCODING>
Parameters:
Parameter | C++ type | Description |
---|---|---|
shape | ::llvm::ArrayRef<int64_t> | |
elementType | Type | |
encoding | Attribute |
TupleType
Fixed-sized collection of other types
Syntax:
tuple-type ::= `tuple` `<` (type ( `,` type)*)? `>`
The value of tuple
type represents a fixed-size collection of elements,
where each element may be of a different type.
Rationale: Though this type is first class in the type system, MLIR
provides no standard operations for operating on tuple
types
(rationale).
Example:
// Empty tuple.
tuple<>
// Single element
tuple<f32>
// Many elements.
tuple<i32, f32, tensor<i1>, i5>
Parameters:
Parameter | C++ type | Description |
---|---|---|
types | ArrayRef<Type> |
UnrankedMemRefType
Shaped reference, with unknown rank, to a region of memory
Syntax:
unranked-memref-type ::= `memref` `<*x` type (`,` memory-space)? `>`
memory-space ::= attribute-value
A memref
type with an unknown rank (e.g. memref<*xf32>
). The purpose of
unranked memrefs is to allow external library functions to receive memref
arguments of any rank without versioning the functions based on the rank.
Other uses of this type are disallowed or will have undefined behavior.
See MemRefType for more information on memref types.
Examples:
memref<*f32>
// An unranked memref with a memory space of 10.
memref<*f32, 10>
Parameters:
Parameter | C++ type | Description |
---|---|---|
elementType | Type | |
memorySpace | Attribute |
UnrankedTensorType
Multi-dimensional array with unknown dimensions
Syntax:
tensor-type ::= `tensor` `<` `*` `x` type `>`
An unranked tensor is a type of tensor in which the set of dimensions have unknown rank. See RankedTensorType for more information on tensor types.
Examples:
tensor<*xf32>
Parameters:
Parameter | C++ type | Description |
---|---|---|
elementType | Type |
VectorType
Multi-dimensional SIMD vector type
Syntax:
vector-type ::= `vector` `<` vector-dim-list vector-element-type `>`
vector-element-type ::= float-type | integer-type | index-type
vector-dim-list := (static-dim-list `x`)?
static-dim-list ::= static-dim (`x` static-dim)*
static-dim ::= (decimal-literal | `[` decimal-literal `]`)
The vector type represents a SIMD style vector used by target-specific operation sets like AVX or SVE. While the most common use is for 1D vectors (e.g. vector<16 x f32>) we also support multidimensional registers on targets that support them (like TPUs). The dimensions of a vector type can be fixed-length, scalable, or a combination of the two. The scalable dimensions in a vector are indicated between square brackets ([ ]).
Vector shapes must be positive decimal integers. 0D vectors are allowed by
omitting the dimension: vector<f32>
.
Note: hexadecimal integer literals are not allowed in vector type
declarations, vector<0x42xi32>
is invalid because it is interpreted as a
2D vector with shape (0, 42)
and zero shapes are not allowed.
Examples:
// A 2D fixed-length vector of 3x42 i32 elements.
vector<3x42xi32>
// A 1D scalable-length vector that contains a multiple of 4 f32 elements.
vector<[4]xf32>
// A 2D scalable-length vector that contains a multiple of 2x8 f32 elements.
vector<[2]x[8]xf32>
// A 2D mixed fixed/scalable vector that contains 4 scalable vectors of 4 f32 elements.
vector<4x[4]xf32>
// A 3D mixed fixed/scalable vector in which only the inner dimension is
// scalable.
vector<2x[4]x8xf32>
Parameters:
Parameter | C++ type | Description |
---|---|---|
shape | ::llvm::ArrayRef<int64_t> | |
elementType | ::mlir::Type | VectorElementTypeInterface instance |
scalableDims | ::llvm::ArrayRef<bool> |
Comb ops
comb.add
(heir::comb::AddOp)
Syntax:
operation ::= `comb.add` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.and
(heir::comb::AndOp)
Syntax:
operation ::= `comb.and` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.concat
(heir::comb::ConcatOp)
Concatenate a variadic list of operands together.
Syntax:
operation ::= `comb.concat` $inputs attr-dict `:` qualified(type($inputs))
See the comb rationale document for details on operand ordering.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.extract
(heir::comb::ExtractOp)
Extract a range of bits into a smaller value, lowBit specifies the lowest bit included.
Syntax:
operation ::= `comb.extract` $input `from` $lowBit attr-dict `:` functional-type($input, $result)
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
lowBit | ::mlir::IntegerAttr | 32-bit signless integer attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.icmp
(heir::comb::ICmpOp)
Compare two integer values
Syntax:
operation ::= `comb.icmp` (`bin` $twoState^)? $predicate $lhs `,` $rhs attr-dict `:` qualified(type($lhs))
This operation compares two integers using a predicate. If the predicate is true, returns 1, otherwise returns 0. This operation always returns a one bit wide result.
%r = comb.icmp eq %a, %b : i4
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
predicate | ::mlir::heir::comb::ICmpPredicateAttr | hw.icmp comparison predicate |
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
lhs | signless integer |
rhs | signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.inv
(heir::comb::InvOp)
Syntax:
operation ::= `comb.inv` (`bin` $twoState^)? $input attr-dict `:` qualified(type($input))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.lut
(heir::comb::LUTOp)
Return an integer based on a lookup table
Syntax:
operation ::= `comb.lut` operands attr-dict `:` functional-type(operands, results)
This operation is similar to truth_table
, but it allows for an integer output instead of a boolean.
Requers an vector of integers as the lookup table, where each integer represents the output for a specific combination of inputs.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
coefficients | ::mlir::DenseI8ArrayAttr | i8 dense array attribute |
lookupTable | ::mlir::DenseI8ArrayAttr | i8 dense array attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of 8-bit signless integer |
Results:
Result | Description |
---|---|
result | 8-bit signless integer |
comb.mul
(heir::comb::MulOp)
Syntax:
operation ::= `comb.mul` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.mux
(heir::comb::MuxOp)
Return one or the other operand depending on a selector bit
Syntax:
operation ::= `comb.mux` (`bin` $twoState^)? $cond `,` $trueValue `,` $falseValue attr-dict `:` qualified(type($result))
%0 = mux %pred, %tvalue, %fvalue : i4
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
cond | 1-bit signless integer |
trueValue | any type |
falseValue | any type |
Results:
Result | Description |
---|---|
result | any type |
comb.nand
(heir::comb::NandOp)
Syntax:
operation ::= `comb.nand` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.nor
(heir::comb::NorOp)
Syntax:
operation ::= `comb.nor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.or
(heir::comb::OrOp)
Syntax:
operation ::= `comb.or` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.parity
(heir::comb::ParityOp)
Syntax:
operation ::= `comb.parity` (`bin` $twoState^)? $input attr-dict `:` qualified(type($input))
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.replicate
(heir::comb::ReplicateOp)
Concatenate the operand a constant number of times
Syntax:
operation ::= `comb.replicate` $input attr-dict `:` functional-type($input, $result)
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:
Operand | Description |
---|---|
input | signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.truth_table
(heir::comb::TruthTableOp)
Return a true/false based on a lookup table
Syntax:
operation ::= `comb.truth_table` $inputs `->` $lookupTable attr-dict
%a = ... : i1
%b = ... : i1
%0 = comb.truth_table %a, %b -> 6 : ui4
This operation assumes that the lookup table is described as an integer of
2^n bits to fully specify the table. Inputs are sorted MSB -> LSB from left
to right and the offset into lookupTable
is computed from them. The
integer containing the truth table value’s LSB is the output for the input
“all false”, and the MSB is the output for the input “all true”.
No difference from array_get into an array of constants except for xprop behavior. If one of the inputs is unknown, but said input doesn’t make a difference in the output (based on the lookup table) the result should not be ‘x’ – it should be the well-known result.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, LUTOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
lookupTable | ::mlir::IntegerAttr | An Attribute containing a integer value |
Operands:
Operand | Description |
---|---|
inputs | variadic of 1-bit signless integer |
Results:
Result | Description |
---|---|
result | 1-bit signless integer |
comb.xnor
(heir::comb::XNorOp)
Syntax:
operation ::= `comb.xnor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
comb.xor
(heir::comb::XorOp)
Syntax:
operation ::= `comb.xor` (`bin` $twoState^)? $inputs attr-dict `:` qualified(type($result))
Traits: AlwaysSpeculatableImplTrait
, Commutative
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:
Attribute | MLIR Type | Description |
---|---|---|
twoState | ::mlir::UnitAttr | unit attribute |
Operands:
Operand | Description |
---|---|
inputs | variadic of signless integer |
Results:
Result | Description |
---|---|
result | signless integer |
Comb additional definitions
ICmpPredicate
Hw.icmp comparison predicate
Cases:
Symbol | Value | String |
---|---|---|
eq | 0 | eq |
ne | 1 | ne |
slt | 2 | slt |
sle | 3 | sle |
sgt | 4 | sgt |
sge | 5 | sge |
ult | 6 | ult |
ule | 7 | ule |
ugt | 8 | ugt |
uge | 9 | uge |
ceq | 10 | ceq |
cne | 11 | cne |
weq | 12 | weq |
wne | 13 | wne |