cir.alloc.exception
(cir::AllocExceptionOp)Allocates an exception according to Itanium ABI
Syntax:
operation ::= `cir.alloc.exception` $size `->` qualified(type($addr)) attr-dict
Implements a slightly higher level __cxa_allocate_exception:
void *__cxa_allocate_exception(size_t thrown_size);
If operation fails, program terminates, not throw.
Example:
// if (b == 0) {
// ...
// throw "...";
cir.if %10 {
%11 = cir.alloc_exception 8 -> !cir.ptr<!void>
... // store exception content into %11
cir.throw %11 : !cir.ptr<!cir.ptr<!u8i>>, ...
Attribute | MLIR Type | Description |
---|---|---|
size | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Result | Description |
---|---|
addr | CIR pointer type |
cir.alloca
(cir::AllocaOp)Defines a scope-local variable
Syntax:
operation ::= `cir.alloca` $allocaType `,` qualified(type($addr)) `,`
($dynAllocSize^ `:` type($dynAllocSize) `,`)?
`[` $name
(`,` `init` $init^)?
`]`
(`ast` $ast^)? attr-dict
The cir.alloca
operation defines a scope-local variable.
The presence init
attribute indicates that the local variable represented by this alloca was originally initialized in C/C++ source code. In such cases, the first use contains the initialization (a cir.store, a cir.call to a ctor, etc).
The dynAllocSize
specifies the size to dynamically allocate on the stack and ignores the allocation size based on the original type. This is useful when handling VLAs and is omitted when declaring regular local variables.
The result type is a pointer to the input's type.
Example:
// int count = 3;
%0 = cir.alloca i32, !cir.ptr<i32>, ["count", init] {alignment = 4 : i64}
// int *ptr;
%1 = cir.alloca !cir.ptr<i32>, !cir.ptr<!cir.ptr<i32>>, ["ptr"] {alignment = 8 : i64}
...
Interfaces: PromotableAllocationOpInterface
Attribute | MLIR Type | Description |
---|---|---|
allocaType | ::mlir::TypeAttr | any type attribute |
name | ::mlir::StringAttr | string attribute |
init | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute whose minimum value is 0 |
ast | ::mlir::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
Operand | Description |
---|---|
dynAllocSize | primitive int |
Result | Description |
---|---|
addr | CIR pointer type |
cir.array.ctor
(cir::ArrayCtor)Initialize array elements with C++ constructors
Syntax:
operation ::= `cir.array.ctor` `(` $addr `:` qualified(type($addr)) `)` $body attr-dict
Initialize each array element using the same C++ constructor. This operation has one region, with one single block. The block has an incoming argument for the current array index to initialize.
Operand | Description |
---|---|
addr | !cir.ptr<!cir.eh_info> |
cir.array.dtor
(cir::ArrayDtor)Destroy array elements with C++ dtors
Syntax:
operation ::= `cir.array.dtor` `(` $addr `:` qualified(type($addr)) `)` $body attr-dict
Destroy each array element using the same C++ destructor. This operation has one region, with one single block. The block has an incoming argument for the current array index to initialize.
Operand | Description |
---|---|
addr | !cir.ptr<!cir.eh_info> |
cir.atomic.cmp_xchg
(cir::AtomicCmpXchg)Atomic compare exchange
Syntax:
operation ::= `cir.atomic.cmp_xchg` `(`
$ptr `:` qualified(type($ptr)) `,`
$expected `:` type($expected) `,`
$desired `:` type($desired) `,`
`success` `=` $succ_order `,`
`failure` `=` $fail_order
`)`
(`weak` $weak^)?
(`volatile` $is_volatile^)?
`:` `(` type($old) `,` type($cmp) `)` attr-dict
C/C++ Atomic compare and exchange operation. Implements builtins like __atomic_compare_exchange_n
and __atomic_compare_exchange
.
Example: %old, %cmp = cir.atomic.cmp_xchg(%ptr : !cir.ptr<!some_struct>, %expected : !u64i, %desired : !u64i, success = seq_cst, failure = seq_cst) weak : (!u64i, !cir.bool)
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
succ_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
fail_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
weak | ::mlir::UnitAttr | unit attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
ptr | CIR pointer type |
expected | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
desired | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
old | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cmp | CIR bool type |
cir.atomic.fetch
(cir::AtomicFetch)Atomic fetch with unary and binary operations
Syntax:
operation ::= `cir.atomic.fetch` `(`
$binop `,`
$ptr `:` type($ptr) `,`
$val `:` type($val) `,`
$mem_order `)`
(`volatile` $is_volatile^)?
(`fetch_first` $fetch_first^)?
`:` type($result) attr-dict
Represents __atomic_<binop>_fetch
and __atomic_fetch_<binop>
builtins, where binop
is on of the binary opcodes : add
, sub
, and
, xor
, or
, nand
, max
and min
.
ptr
is an integer or fp pointer, followed by val
, which must be an integer or fp (only supported for add
and sub
). The operation can also be marked volatile
.
If fetch_first
is present, the operation works like __atomic_fetch_binop
and returns the value that had previously been in *ptr, otherwise it returns the final result of the computation (__atomic_binop_fetch
).
Example: %res = cir.atomic.fetch(add, %ptr : !cir.ptr<!s32i>, %val : !s32i, seq_cst) : !s32i
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
binop | ::mlir::cir::AtomicFetchKindAttr | Binary opcode for atomic fetch operations |
mem_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
is_volatile | ::mlir::UnitAttr | unit attribute |
fetch_first | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
ptr | {int,void}* |
val | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
cir.atomic.xchg
(cir::AtomicXchg)Atomic exchange
Syntax:
operation ::= `cir.atomic.xchg` `(`
$ptr `:` qualified(type($ptr)) `,`
$val `:` type($val) `,`
$mem_order `)`
(`volatile` $is_volatile^)?
`:` type($result) attr-dict
Atomic exchange operations. Implements C/C++ builtins such as __atomic_exchange
and __atomic_exchange_n
.
Example: %res = cir.atomic.xchg(%ptr : !cir.ptr<!some_struct>, %val : !u64i, seq_cst) : !u64i
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
mem_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
is_volatile | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
ptr | CIR pointer type |
val | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.await
(cir::AwaitOp)Wraps C++ co_await implicit logic
Syntax:
operation ::= `cir.await` `(` $kind `,`
`ready` `:` $ready `,`
`suspend` `:` $suspend `,`
`resume` `:` $resume `,`
`)`
attr-dict
The under the hood effect of using C++ co_await expr
roughly translates to:
// co_await expr;
auto &&x = CommonExpr();
if (!x.await_ready()) {
...
x.await_suspend(...);
...
}
x.await_resume();
cir.await
represents this logic by using 3 regions:
Breaking this up in regions allow individual scrutiny of conditions which might lead to folding some of them out. Lowerings coming out of CIR, e.g. LLVM, should use the suspend
region to track more lower level codegen (e.g. intrinsic emission for coro.save/coro.suspend).
There are also 4 flavors of cir.await
available:
init
: compiler generated initial suspend via implicit co_await
.user
: also known as normal, representing user written co_await's.yield
: user written co_yield
expressions.final
: compiler generated final suspend via implicit co_await
.From the C++ snippet we get:
cir.scope {
... // auto &&x = CommonExpr();
cir.await(user, ready : {
... // x.await_ready()
}, suspend : {
... // x.await_suspend()
}, resume : {
... // x.await_resume()
})
}
Note that resulution of the common expression is assumed to happen as part of the enclosing await scope.
Traits: NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::AwaitKindAttr | await kind |
cir.base_class_addr
(cir::BaseClassAddrOp)Get the base class address for a class/struct
Syntax:
operation ::= `cir.base_class_addr` `(`
$derived_addr `:` qualified(type($derived_addr))
`)` `->` qualified(type($base_addr)) attr-dict
The cir.base_class_addr
operaration gets the address of a particular base class given a derived class pointer.
Example:
TBD
Operand | Description |
---|---|
derived_addr | CIR pointer type |
Result | Description |
---|---|
base_addr | CIR pointer type |
cir.binop
(cir::BinOp)Binary operations (arith and logic)
Syntax:
operation ::= `cir.binop` `(` $kind `,` $lhs `,` $rhs `)`
(`nsw` $no_signed_wrap^)?
(`nuw` $no_unsigned_wrap^)?
`:` type($lhs) attr-dict
cir.binop performs the binary operation according to the specified opcode kind: [mul, div, rem, add, sub, and, xor, or].
It requires two input operands and has one result, all types should be the same.
%7 = cir.binop(add, %1, %2) : !s32i
%7 = cir.binop(mul, %1, %2) : !u8i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::BinOpKindAttr | binary operation (arith and logic) kind |
no_unsigned_wrap | ::mlir::UnitAttr | unit attribute |
no_signed_wrap | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
lhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
rhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.binop.overflow
(cir::BinOpOverflowOp)Perform binary integral arithmetic with overflow checking
Syntax:
operation ::= `cir.binop.overflow` `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,`
`(` type($result) `,` type($overflow) `)`
attr-dict
cir.binop.overflow
performs binary arithmetic operations with overflow checking on integral operands.
The kind
argument specifies the kind of arithmetic operation to perform. It can be either add
, sub
, or mul
. The lhs
and rhs
arguments specify the input operands of the arithmetic operation. The types of lhs
and rhs
must be the same.
cir.binop.overflow
produces two SSA values. result
is the result of the arithmetic operation truncated to its specified type. overflow
is a boolean value indicating whether overflow happens during the operation.
The exact semantic of this operation is as follows:
lhs
and rhs
are promoted to an imaginary integral type that has infinite precision.result
. The truncated result is assigned to result
.overflow
is assigned to false. Otherwise, overflow
is assigned to true.Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::BinOpOverflowKindAttr | checked binary arithmetic operation kind |
Operand | Description |
---|---|
lhs | Integer type with arbitrary precision up to a fixed limit |
rhs | Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
overflow | CIR bool type |
cir.bit.clrsb
(cir::BitClrsbOp)Get the number of leading redundant sign bits in the input
Syntax:
operation ::= `cir.bit.clrsb` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the number of leading redundant sign bits in the input integer.
The input integer must be a signed integer. The most significant bit of the input integer is the sign bit. The cir.bit.clrsb
operation returns the number of redundant sign bits in the input, that is, the number of bits following the most significant bit that are identical to it.
The bit width of the input integer must be either 32 or 64.
Examples:
!s32i = !cir.int<s, 32>
// %0 = 0xDEADBEEF, 0b1101_1110_1010_1101_1011_1110_1110_1111
%0 = cir.const #cir.int<3735928559> : !s32i
// %1 will be 1 because there is 1 bit following the most significant bit
// that is identical to it.
%1 = cir.bit.clrsb(%0 : !s32i) : !s32i
// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
%2 = cir.const #cir.int<1> : !s32i
// %3 will be 30
%3 = cir.bit.clrsb(%2 : !s32i) : !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 32-bit signed integer or 64-bit signed integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.bit.clz
(cir::BitClzOp)Get the number of leading 0-bits in the input
Syntax:
operation ::= `cir.bit.clz` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the number of leading 0-bits in the input.
The input integer must be an unsigned integer. The cir.bit.clz
operation returns the number of consecutive 0-bits at the most significant bit position in the input.
This operation invokes undefined behavior if the input value is 0.
Example:
!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>
// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 28
%1 = cir.bit.clz(%0 : !u32i) : !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.bit.ctz
(cir::BitCtzOp)Get the number of trailing 0-bits in the input
Syntax:
operation ::= `cir.bit.ctz` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the number of trailing 0-bits in the input.
The input integer must be an unsigned integer. The cir.bit.ctz
operation returns the number of consecutive 0-bits at the least significant bit position in the input.
This operation invokes undefined behavior if the input value is 0.
Example:
!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>
// %0 = 0b1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 3
%1 = cir.bit.ctz(%0 : !u32i) : !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.bit.ffs
(cir::BitFfsOp)Get the position of the least significant 1-bit of input
Syntax:
operation ::= `cir.bit.ffs` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the position of the least significant 1-bit of the input.
The input integer must be a signed integer. The cir.bit.ffs
operation returns one plus the index of the least significant 1-bit of the input signed integer. As a special case, if the input integer is 0, cir.bit.ffs
returns 0.
Example:
!s32i = !cir.int<s, 32>
// %0 = 0x0010_1000
%0 = cir.const #cir.int<40> : !s32i
// #1 will be 4 since the 4th least significant bit is 1.
%1 = cir.bit.ffs(%0 : !s32i) : !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 32-bit signed integer or 64-bit signed integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.bit.parity
(cir::BitParityOp)Get the parity of input
Syntax:
operation ::= `cir.bit.parity` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the parity of the input. The parity of an integer is the number of 1-bits in it modulo 2.
The input must be an unsigned integer.
Example:
!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>
// %0 = 0x0110_1000
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 1 since there are 3 1-bits in %0
%1 = cir.bit.parity(%0 : !u32i) : !u32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 32-bit unsigned integer or 64-bit unsigned integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.bit.popcount
(cir::BitPopcountOp)Get the number of 1-bits in input
Syntax:
operation ::= `cir.bit.popcount` `(` $input `:` type($input) `)` `:` type($result) attr-dict
Compute the number of 1-bits in the input.
The input must be an unsigned integer.
Example:
!u32i = !cir.int<u, 32>
// %0 = 0x0110_1000
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 3 since there are 3 1-bits in %0
%1 = cir.bit.popcount(%0 : !u32i) : !u32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer |
Result | Description |
---|---|
result | 32-bit signed integer |
cir.brcond
(cir::BrCondOp)Conditional branch
Syntax:
operation ::= `cir.brcond` $cond
$destTrue (`(` $destOperandsTrue^ `:` type($destOperandsTrue) `)`)?
`,`
$destFalse (`(` $destOperandsFalse^ `:` type($destOperandsFalse) `)`)?
attr-dict
The cir.brcond %cond, ^bb0, ^bb1
branches to ‘bb0' block in case %cond (which must be a !cir.bool type) evaluates to true, otherwise it branches to ‘bb1'.
Example:
...
cir.brcond %a, ^bb3, ^bb4
^bb3:
cir.return
^bb4:
cir.yield
Traits: AlwaysSpeculatableImplTrait
, AttrSizedOperandSegments
, Terminator
Interfaces: BranchOpInterface
, ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
cond | CIR bool type |
destOperandsTrue | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
destOperandsFalse | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Successor | Description |
---|---|
destTrue | any successor |
destFalse | any successor |
cir.br
(cir::BrOp)Unconditional branch
Syntax:
operation ::= `cir.br` $dest (`(` $destOperands^ `:` type($destOperands) `)`)? attr-dict
The cir.br
branches unconditionally to a block. Used to represent C/C++ goto's and general block branching.
Example:
...
cir.br ^bb3
^bb3:
cir.return
Traits: AlwaysSpeculatableImplTrait
, Terminator
Interfaces: BranchOpInterface
, ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
destOperands | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Successor | Description |
---|---|
dest | any successor |
cir.break
(cir::BreakOp)C/C++ break
statement equivalent
Syntax:
operation ::= `cir.break` attr-dict
The cir.break
operation is used to cease the control flow to the parent operation, exiting its region's control flow. It is only allowed if it is within a breakable operation (loops and switch
).
Traits: Terminator
cir.bswap
(cir::ByteswapOp)Reverse the bytes that constitute the operand integer
Syntax:
operation ::= `cir.bswap` `(` $input `:` type($input) `)` `:` type($result) attr-dict
The cir.bswap
operation takes an integer as operand, and returns it with the order of bytes that constitute the operand reversed.
The operand integer must be an unsigned integer. Its widths must be either 16, 32, or 64.
Example:
!u32i = !cir.int<u, 32>
// %0 = 0x12345678
%0 = cir.const #cir.int<305419896> : !u32i
// %1 should be 0x78563412
%1 = cir.bswap(%0 : !u32i) : !u32i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.asm
(cir::InlineAsmOp)The cir.asm
operation represents C/C++ asm inline.
CIR constraints strings follow barelly the same rules that are established for the C level assembler constraints with several differences caused by clang::AsmStmt processing.
Thus, numbers that appears in the constraint string may also refer to:
Operand attributes is a storage, where each element corresponds to the operand with the same index. The first index relates to the operation result (if any). Note, the operands themselves are stored as VariadicOfVariadic in the next order: output, input and then in/out operands.
Note, when several output operands are present, the result type may be represented as an anon struct type.
Example:
__asm__("foo" : : : );
__asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
__asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
!ty_22anon2E022 = !cir.struct<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
!ty_22anon2E122 = !cir.struct<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>}>
...
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
%1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init]
...
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.load %1 : !cir.ptr<!s32i>, !s32i
cir.asm(x86_att,
out = [],
in = [],
in_out = [],
{"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects
cir.asm(x86_att,
out = [],
in = [],
in_out = [%2 : !s32i],
{"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) -> !ty_22anon2E022
cir.asm(x86_att,
out = [],
in = [%3 : !s32i],
in_out = [%2 : !s32i],
{"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !ty_22anon2E122
Traits: RecursiveMemoryEffects
Attribute | MLIR Type | Description |
---|---|---|
asm_string | ::mlir::StringAttr | string attribute |
constraints | ::mlir::StringAttr | string attribute |
side_effects | ::mlir::UnitAttr | unit attribute |
asm_flavor | ::mlir::cir::AsmFlavorAttr | ATT or Intel |
operand_attrs | ::mlir::ArrayAttr | array attribute |
operands_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
Operand | Description |
---|---|
operands | variadic of any type |
Result | Description |
---|---|
res | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.call
(cir::CallOp)Call operation
Direct and indirect calls.
For direct calls, the call
operation represents a direct call to a function that is within the same symbol scope as the call. The operands and result types of the call must match the specified function type. The callee is encoded as a aymbol reference attribute named "callee".
For indirect calls, the first mlir::Operation
operand is the call target.
Given the way indirect calls are encoded, avoid using mlir::Operation
methods to walk the operands for this operation, instead use the methods provided by CIRCallOpInterface
. ``
Example:
// Direct call
%2 = cir.call @my_add(%0, %1) : (f32, f32) -> f32
...
// Indirect call
%20 = cir.call %18(%17)
Interfaces: CIRCallOpInterface
, CallOpInterface
, SymbolUserOpInterface
Attribute | MLIR Type | Description |
---|---|---|
exception | ::mlir::UnitAttr | unit attribute |
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
extra_attrs | ::mlir::cir::ExtraFuncAttributesAttr | Represents aggregated attributes for a function |
ast | ::mlir::cir::ASTCallExprInterface | ASTCallExprInterface instance |
Operand | Description |
---|---|
arg_ops | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.cast
(cir::CastOp)Conversion between values of different types
Syntax:
operation ::= `cir.cast` `(` $kind `,` $src `:` type($src) `)`
`,` type($result) attr-dict
Apply C/C++ usual conversions rules between values. Currently supported kinds:
array_to_ptrdecay
bitcast
integral
int_to_bool
int_to_float
floating
float_to_int
float_to_bool
ptr_to_int
ptr_to_bool
bool_to_int
bool_to_float
address_space
float_to_complex
int_to_complex
float_complex_to_real
int_complex_to_real
float_complex_to_bool
int_complex_to_bool
float_complex
float_complex_to_int_complex
int_complex
int_complex_to_float_complex
This is effectively a subset of the rules from llvm-project/clang/include/clang/AST/OperationKinds.def
; but note that some of the conversions aren't implemented in terms of cir.cast
, lvalue-to-rvalue
for instance is modeled as a regular cir.load
.
%4 = cir.cast (int_to_bool, %3 : i32), !cir.bool
...
%x = cir.cast(array_to_ptrdecay, %0 : !cir.ptr<!cir.array<i32 x 10>>), !cir.ptr<i32>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
, PromotableOpInterface
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::CastKindAttr | cast kind |
Operand | Description |
---|---|
src | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.catch_param
(cir::CatchParamOp)Represents catch clause formal parameter
Syntax:
operation ::= `cir.catch_param` ($kind^)?
($exception_ptr^)?
(`->` qualified(type($param))^)?
attr-dict
The cir.catch_param
can operate in two modes: within catch regions of cir.try
or anywhere else with the begin
or end
markers. The begin
version requires an exception pointer of cir.ptr<!void>
.
Example:
// TBD
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::CatchParamKindAttr | Designate limits for begin/end of catch param handling |
Operand | Description |
---|---|
exception_ptr | void* |
Result | Description |
---|---|
param | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.ceil
(cir::CeilOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.ceil` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.clear_cache
(cir::ClearCacheOp)Clear cache operation
Syntax:
operation ::= `cir.clear_cache` $begin `:` qualified(type($begin)) `,`
$end `,`
attr-dict
CIR representation for __builtin___clear_cache
.
Operand | Description |
---|---|
begin | void* |
end | void* |
cir.cmp
(cir::CmpOp)Compare values two values and produce a boolean result
Syntax:
operation ::= `cir.cmp` `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,` type($result) attr-dict
cir.cmp
compares two input operands of the same type and produces a cir.bool
result. The kinds of comparison available are: [lt,gt,ge,eq,ne]
%7 = cir.cmp(gt, %1, %2) : i32, !cir.bool
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::CmpOpKindAttr | compare operation kind |
Operand | Description |
---|---|
lhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
rhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.cmp3way
(cir::CmpThreeWayOp)Compare two values with C++ three-way comparison semantics
Syntax:
operation ::= `cir.cmp3way` `(` $lhs `:` type($lhs) `,` $rhs `,` qualified($info) `)`
`:` type($result) attr-dict
The cir.cmp3way
operation models the <=>
operator in C++20. It takes two operands with the same type and produces a result indicating the ordering between the two input operands.
The result of the operation is a signed integer that indicates the ordering between the two input operands.
There are two kinds of ordering: strong ordering and partial ordering. Comparing different types of values yields different kinds of orderings. The info
parameter gives the ordering kind and other necessary information about the comparison.
Example:
!s32i = !cir.int<s, 32>
#cmp3way_strong = #cmp3way_info<strong, lt = -1, eq = 0, gt = 1>
#cmp3way_partial = #cmp3way_info<strong, lt = -1, eq = 0, gt = 1, unordered = 2>
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.const #cir.int<1> : !s32i
%2 = cir.cmp3way(%0 : !s32i, %1, #cmp3way_strong) : !s8i
%3 = cir.const #cir.fp<0.0> : !cir.float
%4 = cir.const #cir.fp<1.0> : !cir.float
%5 = cir.cmp3way(%3 : !cir.float, %4, #cmp3way_partial) : !s8i
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
info | ::mlir::cir::CmpThreeWayInfoAttr | Holds information about a three-way comparison operation |
Operand | Description |
---|---|
lhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
rhs | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | primitive signed int |
cir.complex.binop
(cir::ComplexBinOp)Binary operations on operands of complex type
Syntax:
operation ::= `cir.complex.binop` $kind $lhs `,` $rhs `range` `(` $range `)` (`promoted` $promoted^)?
`:` qualified(type($lhs)) attr-dict
The cir.complex.binop
operation represents a binary operation on operands of C complex type (e.g. float _Complex
). The operation can only represent binary multiplication or division on complex numbers; other binary operations, such as addition and subtraction, are represented by the cir.binop
operation.
The operation requires two input operands and has one result. The types of all the operands and the result should be of the same !cir.complex
type.
The operation also takes a range
attribute that specifies the complex range of the binary operation.
Examples:
%2 = cir.complex.binop add %0, %1 : !cir.complex<!cir.float>
%2 = cir.complex.binop mul %0, %1 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::ComplexBinOpKindAttr | complex number binary operation kind |
range | ::mlir::cir::ComplexRangeKindAttr | complex multiplication and division implementation |
promoted | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
lhs | CIR complex type |
rhs | CIR complex type |
Result | Description |
---|---|
result | CIR complex type |
cir.complex.create
(cir::ComplexCreateOp)Create a complex value from its real and imaginary parts
Syntax:
operation ::= `cir.complex.create` $real `,` $imag
`:` qualified(type($real)) `->` qualified(type($result)) attr-dict
cir.complex.create
operation takes two operands that represent the real and imaginary part of a complex number, and yields the complex number.
Example:
%0 = cir.const #cir.fp<1.000000e+00> : !cir.double
%1 = cir.const #cir.fp<2.000000e+00> : !cir.double
%2 = cir.complex.create %0, %1 : !cir.complex<!cir.double>
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
real | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
imag | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | CIR complex type |
cir.complex.imag
(cir::ComplexImagOp)Extract the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag` $operand `:` qualified(type($operand)) `->` qualified(type($result))
attr-dict
cir.complex.imag
operation takes an operand of !cir.complex
type and yields the imaginary part of it.
Example:
%1 = cir.complex.imag %0 : !cir.complex<!cir.float> -> !cir.float
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
operand | CIR complex type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
cir.complex.imag_ptr
(cir::ComplexImagPtrOp)Derive a pointer to the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.imag_ptr
operation takes a pointer operand that points to a complex value of type !cir.complex
and yields a pointer to the imaginary part of the operand.
Example:
%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
operand | !cir.complex* |
Result | Description |
---|---|
result | {int,void}* |
cir.complex.real
(cir::ComplexRealOp)Extract the real part of a complex value
Syntax:
operation ::= `cir.complex.real` $operand `:` qualified(type($operand)) `->` qualified(type($result))
attr-dict
cir.complex.real
operation takes an operand of !cir.complex
type and yields the real part of it.
Example:
%1 = cir.complex.real %0 : !cir.complex<!cir.float> -> !cir.float
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
operand | CIR complex type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or Integer type with arbitrary precision up to a fixed limit |
cir.complex.real_ptr
(cir::ComplexRealPtrOp)Derive a pointer to the real part of a complex value
Syntax:
operation ::= `cir.complex.real_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.real_ptr
operation takes a pointer operand that points to a complex value of type !cir.complex
and yields a pointer to the real part of the operand.
Example:
%1 = cir.complex.real_ptr %0 : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
operand | !cir.complex* |
Result | Description |
---|---|
result | {int,void}* |
cir.condition
(cir::ConditionOp)Loop continuation condition.
Syntax:
operation ::= `cir.condition` `(` $condition `)` attr-dict
The cir.condition
terminates conditional regions. It takes a single cir.bool
operand and, depending on its value, may branch to different regions:
cond
region of a cir.loop
, it continues the loop if true, or exits it if false.ready
region of a cir.await
, it branches to the resume
region when true, and to the suspend
region when false.Example:
cir.loop for(cond : {
cir.condition(%arg0) // Branches to `step` region or exits.
}, step : {
[...]
}) {
[...]
}
cir.await(user, ready : {
cir.condition(%arg0) // Branches to `resume` or `suspend` region.
}, suspend : {
[...]
}, resume : {
[...]
},)
Traits: Terminator
Interfaces: RegionBranchTerminatorOpInterface
Operand | Description |
---|---|
condition | CIR bool type |
cir.const
(cir::ConstantOp)Defines a CIR constant
Syntax:
operation ::= `cir.const` attr-dict $value
The cir.const
operation turns a literal into an SSA value. The data is attached to the operation as an attribute.
%0 = cir.const 42 : i32
%1 = cir.const 4.2 : f32
%2 = cir.const nullptr : !cir.ptr<i32>
Traits: AlwaysSpeculatableImplTrait
, ConstantLike
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
value | ::mlir::TypedAttr | TypedAttr instance |
Result | Description |
---|---|
res | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.continue
(cir::ContinueOp)C/C++ continue
statement equivalent
Syntax:
operation ::= `cir.continue` attr-dict
The cir.continue
operation is used to continue execution to the next iteration of a loop. It is only allowed within cir.loop
regions.
Traits: Terminator
cir.copy
(cir::CopyOp)Copies contents from a CIR pointer to another
Syntax:
operation ::= `cir.copy` $src `to` $dst (`volatile` $is_volatile^)?
attr-dict `:` qualified(type($dst))
Given two CIR pointers, src
and dst
, cir.copy
will copy the memory pointed by src
to the memory pointed by dst
.
The amount of bytes copied is inferred from the pointee type. Naturally, the pointee type of both src
and dst
must match and must implement the DataLayoutTypeInterface
.
Examples:
// Copying contents from one struct to another:
cir.copy %0 to %1 : !cir.ptr<!struct_ty>
Traits: SameTypeOperands
Interfaces: PromotableMemOpInterface
Attribute | MLIR Type | Description |
---|---|---|
is_volatile | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
dst | CIR pointer type |
src | CIR pointer type |
cir.copysign
(cir::CopysignOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.copysign` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
rhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.cos
(cir::CosOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.cos` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.do
(cir::DoWhileOp)C/C++ do-while loop
Syntax:
operation ::= `cir.do` $body `while` $cond attr-dict
Represents a C/C++ do-while loop. Identical to cir.while
but the condition is evaluated after the body.
Example:
cir.do {
cir.break
^bb2:
cir.yield
} while {
cir.condition %cond : cir.bool
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface
, LoopOpInterface
, RegionBranchOpInterface
cir.dyn_cast
(cir::DynamicCastOp)Perform dynamic cast on struct pointers
Syntax:
operation ::= `cir.dyn_cast` `(`
$kind `,` $src `:` type($src)
(`,` qualified($info)^)?
(`relative_layout` $relative_layout^)?
`)`
`->` qualified(type($result)) attr-dict
The cir.dyn_cast
operation models part of the semantics of the dynamic_cast
operator in C++. It can be used to perform 3 kinds of casts on struct pointers:
The input of the operation must be a struct pointer. The result of the operation is either a struct pointer or a void pointer.
The parameter kind
specifies the semantics of this operation. If its value is ptr
, then the operation models dynamic casts on pointers. Otherwise, if its value is ref
, the operation models dynamic casts on references. Specifically:
kind
is ref
, the operation will invoke undefined behavior. A sanitizer check will be emitted if sanitizer is on.kind
is ref
, the operation will throw a bad_cast
exception.The info
argument gives detailed information about the requested dynamic cast operation. It is an optional #cir.dyn_cast_info
attribute that is only present when the operation models a down-cast or a side-cast.
The relative_layout
argument specifies whether the Itanium C++ ABI vtable uses relative layout. It is only meaningful when the operation models a cast-to-complete operation.
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::DynamicCastKindAttr | dynamic cast kind |
info | ::mlir::cir::DynamicCastInfoAttr | ABI specific information about a dynamic cast |
relative_layout | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
src | !cir.struct* |
Result | Description |
---|---|
result | CIR pointer type |
cir.eh.inflight_exception
(cir::EhInflightOp)Materialize the catch clause formal parameter
Syntax:
operation ::= `cir.eh.inflight_exception` (`cleanup` $cleanup^)?
($sym_type_list^)?
attr-dict
cir.eh.inflight_exception
returns two values:
exception_ptr
: The exception pointer for the inflight exceptiontype_id
: pointer to the exception object This operation is expected to be the first one basic blocks on the exception path out of cir.try_call
operations.The cleanup
attribute indicates that clean up code might run before the values produced by this operation are used to gather exception information. This helps CIR to pass down more accurate information for LLVM lowering to landingpads.
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
cleanup | ::mlir::UnitAttr | unit attribute |
sym_type_list | ::mlir::ArrayAttr | flat symbol ref array attribute |
Result | Description |
---|---|
exception_ptr | void* |
type_id | 32-bit unsigned integer |
cir.eh.typeid
(cir::EhTypeIdOp)Compute exception type id from it's global type symbol
Syntax:
operation ::= `cir.eh.typeid` $type_sym attr-dict
Returns the exception type id for a given global symbol representing a type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
, SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
type_sym | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Result | Description |
---|---|
type_id | 32-bit unsigned integer |
cir.exp2
(cir::Exp2Op)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.exp2` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.exp
(cir::ExpOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.exp` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.expect
(cir::ExpectOp)Compute whether expression is likely to evaluate to a specified value
Syntax:
operation ::= `cir.expect` `(` $val`,` $expected (`,` $prob^)? `)` `:` type($val) attr-dict
Provides __builtin_expect functionality in Clang IR.
If $prob is not specified, then behaviour is same as __builtin_expect. If specified, then behaviour is same as __builtin_expect_with_probability, where probability = $prob.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
prob | ::mlir::FloatAttr | 64-bit float attribute |
Operand | Description |
---|---|
val | primitive int |
expected | primitive int |
Result | Description |
---|---|
result | primitive int |
cir.fabs
(cir::FAbsOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.fabs` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.fmax
(cir::FMaxOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fmax` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
rhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.fmin
(cir::FMinOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fmin` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
rhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.fmod
(cir::FModOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fmod` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
rhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.floor
(cir::FloorOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.floor` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.for
(cir::ForOp)C/C++ for loop counterpart
Syntax:
operation ::= `cir.for` `:` `cond` $cond
`body` $body
`step` $step
attr-dict
Represents a C/C++ for loop. It consists of three regions:
cond
: single block region with the loop's condition. Should be terminated with a cir.condition
operation.body
: contains the loop body and an arbitrary number of blocks.step
: single block region with the loop's step.Example:
cir.for cond {
cir.condition(%val)
} body {
cir.break
^bb2:
cir.yield
} step {
cir.yield
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface
, LoopOpInterface
, RegionBranchOpInterface
cir.func
(cir::FuncOp)Declare or define a function
Similar to mlir::FuncOp
built-in:
Operations within the function cannot implicitly capture values defined outside of the function, i.e. Functions are
IsolatedFromAbove
. All external references must use function arguments or attributes that establish a symbolic connection (e.g. symbols referenced by name via a string attribute like SymbolRefAttr). An external function declaration (used when referring to a function declared in some other module) has no body. While the MLIR textual form provides a nice inline syntax for function arguments, they are internally represented as "block arguments" to the first block in the region.Only dialect attribute names may be specified in the attribute dictionaries for function arguments, results, or the function itself.
The function linkage information is specified by linkage
, as defined by GlobalLinkageKind
attribute.
The calling_conv
attribute specifies the calling convention of the function. The default calling convention is CallingConv::C
.
A compiler builtin function must be marked as builtin
for further processing when lowering from CIR.
The coroutine
keyword is used to mark coroutine function, which requires at least one cir.await
instruction to be used in its body.
The lambda
translates to a C++ operator()
that implements a lambda, this allow callsites to make certain assumptions about the real function nature when writing analysis. The verifier should, but do act on this keyword yet.
The no_proto
keyword is used to identify functions that were declared without a prototype and, consequently, may contain calls with invalid arguments and undefined behavior.
The extra_attrs
, which is an aggregate of function-specific attributes is required and mandatory to describle additional attributes that are not listed above. Though mandatory, the prining of the attribute can be omitted if it is empty.
The global_ctor
indicates whether a function should execute before main()
function, as specified by __attribute__((constructor))
. A execution priority can also be specified global_ctor(<prio>)
. Similarly, for global destructors both global_dtor
and global_dtor(<prio>)
are available.
Example:
// External function definitions.
cir.func @abort()
// A function with internal linkage.
cir.func internal @count(%x: i64) -> (i64)
return %x : i64
}
// Linkage information
cir.func linkonce_odr @some_method(...)
// Calling convention information
cir.func @another_func(...) cc(spir_kernel) extra(#fn_attr)
// Builtin function
cir.func builtin @__builtin_coro_end(!cir.ptr<i8>, !cir.bool) -> !cir.bool
// Coroutine
cir.func coroutine @_Z10silly_taskv() -> !CoroTask {
...
cir.await(...)
...
}
Traits: AutomaticAllocationScope
, IsolatedFromAbove
Interfaces: CIRGlobalValueInterface
, CallableOpInterface
, FunctionOpInterface
, Symbol
Attribute | MLIR Type | Description |
---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
global_visibility | ::mlir::cir::VisibilityAttr | Visibility attribute |
function_type | ::mlir::TypeAttr | type attribute of CIR function type |
builtin | ::mlir::UnitAttr | unit attribute |
coroutine | ::mlir::UnitAttr | unit attribute |
lambda | ::mlir::UnitAttr | unit attribute |
no_proto | ::mlir::UnitAttr | unit attribute |
dsolocal | ::mlir::UnitAttr | unit attribute |
linkage | ::mlir::cir::GlobalLinkageKindAttr | Linkage type/kind |
calling_conv | ::mlir::cir::CallingConvAttr | calling convention |
extra_attrs | ::mlir::cir::ExtraFuncAttributesAttr | Represents aggregated attributes for a function |
sym_visibility | ::mlir::StringAttr | string attribute |
comdat | ::mlir::UnitAttr | unit attribute |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
aliasee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
global_ctor | ::mlir::cir::GlobalCtorAttr | Marks a function as a global constructor |
global_dtor | ::mlir::cir::GlobalDtorAttr | Marks a function as a global destructor |
ast | ::mlir::Attribute | AST Function attribute |
cir.get_bitfield
(cir::GetBitfieldOp)Get a bitfield
Syntax:
operation ::= `cir.get_bitfield` `(`$bitfield_info `,` $addr attr-dict `:`
qualified(type($addr)) `)` `->` type($result)
The cir.get_bitfield
operation provides a load-like access to a bit field of a record.
It expects a name if a bit field, a pointer to a storage in the base record, a type of the storage, a name of the bitfield, a size the bit field, an offset of the bit field and a sign.
A unit attribute volatile
can be used to indicate a volatile load of the bitfield.
Example: Suppose we have a struct with multiple bitfields stored in different storages. The cir.get_bitfield
operation gets the value of the bitfield
typedef struct {
int a : 4;
int b : 27;
int c : 17;
int d : 2;
int e : 15;
} S;
int load_bitfield(S& s) {
return s.d;
}
// 'd' is in the storage with the index 1
!struct_type = !cir.struct<struct "S" {!cir.int<u, 32>, !cir.int<u, 32>, !cir.int<u, 16>} #cir.record.decl.ast>
#bfi_d = #cir.bitfield_info<name = "d", storage_type = !u32i, size = 2, offset = 17, is_signed = true>
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!struct_type>>, !cir.ptr<!struct_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!struct_type> -> !cir.ptr<!u32i>
%4 = cir.get_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>) -> !s32i
Attribute | MLIR Type | Description |
---|---|---|
bitfield_info | ::mlir::cir::BitfieldInfoAttr | Represents a bit field info |
is_volatile | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
addr | CIR pointer type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.get_global
(cir::GetGlobalOp)Get the address of a global variable
Syntax:
operation ::= `cir.get_global` (`thread_local` $tls^)?
$name `:` qualified(type($addr)) attr-dict
The cir.get_global
operation retrieves the address pointing to a named global variable. If the global variable is marked constant, writing to the resulting address (such as through a cir.store
operation) is undefined. Resulting type must always be a !cir.ptr<...>
type with the same address space as the global variable.
Addresses of thread local globals can only be retrieved if this operation is marked thread_local
, which indicates the address isn't constant.
Example:
%x = cir.get_global @foo : !cir.ptr<i32>
...
%y = cir.get_global thread_local @batata : !cir.ptr<i32>
...
cir.global external addrspace(offload_global) @gv = #cir.int<0> : !s32i
%z = cir.get_global @gv : !cir.ptr<!s32i, addrspace(offload_global)>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
, SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
tls | ::mlir::UnitAttr | unit attribute |
Result | Description |
---|---|
addr | CIR pointer type |
cir.get_member
(cir::GetMemberOp)Get the address of a member of a struct
Syntax:
operation ::= `cir.get_member` $addr `[` $index_attr `]` attr-dict
`:` qualified(type($addr)) `->` qualified(type($result))
The cir.get_member
operation gets the address of a particular named member from the input record.
It expects a pointer to the base record as well as the name of the member and its field index.
Example:
// Suppose we have a struct with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!struct_ty = !cir.struct<"struct.Bar" {!s32i, !s8i}>
// Get the address of the member at index 1.
%1 = cir.get_member %0[1] {name = "i"} : (!cir.ptr<!struct_ty>) -> !cir.ptr<!s8i>
Attribute | MLIR Type | Description |
---|---|---|
name | ::mlir::StringAttr | string attribute |
index_attr | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
addr | CIR pointer type |
Result | Description |
---|---|
result | CIR pointer type |
cir.get_method
(cir::GetMethodOp)Resolve a method to a function pointer as callee
Syntax:
operation ::= `cir.get_method` $method `,` $object
`:` `(` qualified(type($method)) `,` qualified(type($object)) `)`
`->` `(` qualified(type($callee)) `,` qualified(type($adjusted_this)) `)`
attr-dict
The cir.get_method
operation takes a method and an object as input, and yields a function pointer that points to the actual function corresponding to the input method. The operation also applies any necessary adjustments to the input object pointer for calling the method and yields the adjusted pointer.
This operation is generated when calling a method through a pointer-to- member-function in C++:
// Foo *object;
// int arg;
// void (Foo::*method)(int);
(object->*method)(arg);
The code above will generate CIR similar as:
// %object = ...
// %arg = ...
// %method = ...
%callee, %this = cir.get_method %method, %object
cir.call %callee(%this, %arg)
The method type must match the callee type. That is:
!cir.ptr<!cir.void>
.Operand | Description |
---|---|
method | CIR type that represents C++ pointer-to-member-function type |
object | !cir.struct* |
Result | Description |
---|---|
callee | !cir.ptr<!cir.func> |
adjusted_this | void* |
cir.get_runtime_member
(cir::GetRuntimeMemberOp)Get the address of a member of a struct
Syntax:
operation ::= `cir.get_runtime_member` $addr `[` $member `:` qualified(type($member)) `]` attr-dict
`:` qualified(type($addr)) `->` qualified(type($result))
The cir.get_runtime_member
operation gets the address of a member from the input record. The target member is given by a value of type !cir.data_member
(i.e. a pointer-to-data-member value).
This operation differs from cir.get_member
in when the target member can be determined. For the cir.get_member
operation, the target member is specified as a constant index so the member it returns access to is known when the operation is constructed. For the cir.get_runtime_member
operation, the target member is given through a pointer-to-data-member value which is unknown until the program being compiled is executed. In other words, cir.get_member
represents a normal member access through the .
operator in C/C++:
struct Foo { int x; };
Foo f;
(void)f.x; // cir.get_member
And cir.get_runtime_member
represents a member access through the .*
or the ->*
operator in C++:
struct Foo { int x; }
Foo f;
Foo *p;
int Foo::*member;
(void)f.*member; // cir.get_runtime_member
(void)f->*member; // cir.get_runtime_member
This operation expects a pointer to the base record as well as the pointer to the target member.
Operand | Description |
---|---|
addr | !cir.struct* |
member | CIR type that represents pointer-to-data-member type in C++ |
Result | Description |
---|---|
result | CIR pointer type |
cir.global
(cir::GlobalOp)Declares or defines a global variable
Syntax:
operation ::= `cir.global` ($sym_visibility^)?
custom<OmitDefaultVisibility>($global_visibility)
(`constant` $constant^)?
$linkage
(`comdat` $comdat^)?
($tls_model^)?
(`dsolocal` $dsolocal^)?
(`addrspace` `(` custom<GlobalOpAddrSpace>($addr_space)^ `)`)?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
attr-dict
The cir.global
operation declares or defines a named global variable.
The backing memory for the variable is allocated statically and is described by the type of the variable.
The operation is a declaration if no inital_value
is specified, else it is a definition.
The global variable can also be marked constant using the constant
unit attribute. Writing to such constant global variables is undefined.
The linkage
tracks C/C++ linkage types, currently very similar to LLVM's. Symbol visibility in sym_visibility
is defined in terms of MLIR's visibility and verified to be in accordance to linkage
.
visibility_attr
is defined in terms of CIR's visibility.
Example:
// Public and constant variable with initial value.
cir.global public constant @c : i32 = 4;
Traits: NoRegionArguments
Interfaces: CIRGlobalValueInterface
, RegionBranchOpInterface
, Symbol
Attribute | MLIR Type | Description |
---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
global_visibility | ::mlir::cir::VisibilityAttr | Visibility attribute |
sym_visibility | ::mlir::StringAttr | string attribute |
sym_type | ::mlir::TypeAttr | any type attribute |
linkage | ::mlir::cir::GlobalLinkageKindAttr | Linkage type/kind |
addr_space | ::mlir::cir::AddressSpaceAttr | Address space attribute for pointer types |
tls_model | ::mlir::cir::TLS_ModelAttr | TLS model |
initial_value | ::mlir::Attribute | any attribute |
comdat | ::mlir::UnitAttr | unit attribute |
constant | ::mlir::UnitAttr | unit attribute |
dsolocal | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
ast | ::mlir::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
section | ::mlir::StringAttr | string attribute |
cir.goto
(cir::GotoOp)Syntax:
operation ::= `cir.goto` $label attr-dict
Transfers control to the specified label.
Example:
void foo() {
goto exit;
exit:
return;
}
cir.func @foo() {
cir.goto "exit"
^bb1:
cir.label "exit"
cir.return
}
Traits: Terminator
Attribute | MLIR Type | Description |
---|---|---|
label | ::mlir::StringAttr | string attribute |
cir.if
(cir::IfOp)The if-then-else operation
The cir.if
operation represents an if-then-else construct for conditionally executing two regions of code. The operand is a cir.bool
type.
Examples:
cir.if %b {
...
} else {
...
}
cir.if %c {
...
}
cir.if %c {
...
cir.br ^a
^a:
cir.yield
}
cir.if
defines no values and the ‘else' can be omitted. cir.yield
must explicitly terminate the region if it has more than one block.
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Operand | Description |
---|---|
condition | CIR bool type |
cir.is_constant
(cir::IsConstantOp)Syntax:
operation ::= `cir.is_constant` `(` $val `:` type($val) `)` `:` type($result) attr-dict
Returns true
if the argument is known to be a compile-time constant otherwise returns ‘false'.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
val | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | CIR bool type |
cir.iterator_begin
(cir::IterBeginOp)Returns an iterator to the first element of a container
Syntax:
operation ::= `cir.iterator_begin` `(`
$original_fn `,` $container `:` type($container)
`)` `->` type($result) attr-dict
Attribute | MLIR Type | Description |
---|---|---|
original_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operand | Description |
---|---|
container | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.iterator_end
(cir::IterEndOp)Returns an iterator to the element following the last element of a container
Syntax:
operation ::= `cir.iterator_end` `(`
$original_fn `,` $container `:` type($container)
`)` `->` type($result) attr-dict
Attribute | MLIR Type | Description |
---|---|---|
original_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operand | Description |
---|---|
container | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.llrint
(cir::LLrintOp)Builtin function that takes a floating-point value as input and produces an integral value as output.
Syntax:
operation ::= `cir.llrint` $src `:` type($src) `->` type($result) attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.llround
(cir::LLroundOp)Builtin function that takes a floating-point value as input and produces an integral value as output.
Syntax:
operation ::= `cir.llround` $src `:` type($src) `->` type($result) attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.label
(cir::LabelOp)Syntax:
operation ::= `cir.label` $label attr-dict
An identifier which may be referred by cir.goto operation Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
Attribute | MLIR Type | Description |
---|---|---|
label | ::mlir::StringAttr | string attribute |
cir.load
(cir::LoadOp)Load value from memory adddress
Syntax:
operation ::= `cir.load` (`deref` $isDeref^)?
(`volatile` $is_volatile^)?
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
cir.load
reads a value (lvalue to rvalue conversion) given an address backed up by a cir.ptr
type. A unit attribute deref
can be used to mark the resulting value as used by another operation to dereference a pointer. A unit attribute volatile
can be used to indicate a volatile loading. Load can be marked atomic by using atomic(<mem_order>)
.
align
can be used to specify an alignment that's different from the default, which is computed from result
's type ABI data layout.
Example:
// Read from local variable, address in %0.
%1 = cir.load %0 : !cir.ptr<i32>, i32
// Load address from memory at address %0. %3 is used by at least one
// operation that dereferences a pointer.
%3 = cir.load deref %0 : !cir.ptr<!cir.ptr<i32>>
// Perform a volatile load from address in %0.
%4 = cir.load volatile %0 : !cir.ptr<i32>, i32
// Others
%x = cir.load align(16) atomic(seq_cst) %0 : !cir.ptr<i32>, i32
Interfaces: InferTypeOpInterface
, PromotableMemOpInterface
Attribute | MLIR Type | Description |
---|---|---|
isDeref | ::mlir::UnitAttr | unit attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
mem_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
Operand | Description |
---|---|
addr | CIR pointer type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.log10
(cir::Log10Op)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.log10` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.log2
(cir::Log2Op)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.log2` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.log
(cir::LogOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.log` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.lrint
(cir::LrintOp)Builtin function that takes a floating-point value as input and produces an integral value as output.
Syntax:
operation ::= `cir.lrint` $src `:` type($src) `->` type($result) attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.lround
(cir::LroundOp)Builtin function that takes a floating-point value as input and produces an integral value as output.
Syntax:
operation ::= `cir.lround` $src `:` type($src) `->` type($result) attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.libc.memchr
(cir::MemChrOp)Libc's memchr
Syntax:
operation ::= `cir.libc.memchr` `(`
$src `,` $pattern `,` $len `)` attr-dict
Search for pattern
in data range from src
to src
+ len
. provides a bound to the search in src
. result
is a pointer to found pattern
or a null pointer.
Examples:
%p = cir.libc.memchr(%src, %pattern, %len) -> !cir.ptr<!void>
Interfaces: InferTypeOpInterface
Operand | Description |
---|---|
src | void* |
pattern | 32-bit signed integer |
len | 64-bit unsigned integer |
Result | Description |
---|---|
result | void* |
cir.libc.memcpy
(cir::MemCpyOp)Equivalent to libc's memcpy
Syntax:
operation ::= `cir.libc.memcpy` $len `bytes` `from` $src `to` $dst attr-dict
`:` type($len) `` `,` qualified(type($src)) `->` qualified(type($dst))
Given two CIR pointers, src
and dst
, cir.libc.memcpy
will copy len
bytes from the memory pointed by src
to the memory pointed by dst
.
While cir.copy
is meant to be used for implicit copies in the code where the length of the copy is known, cir.memcpy
copies only from and to void pointers, requiring the copy length to be passed as an argument.
Examples:
// Copying 2 bytes from one array to a struct:
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memcpy %2 bytes from %arr to %struct : !cir.ptr<!arr> -> !cir.ptr<!struct>
Operand | Description |
---|---|
dst | CIR pointer type |
src | CIR pointer type |
len | primitive int |
cir.nearbyint
(cir::NearbyintOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.nearbyint` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.objsize
(cir::ObjSizeOp)Conversion between values of different types
Syntax:
operation ::= `cir.objsize` `(`
$ptr `:` type($ptr) `,`
$kind
(`,` `dynamic` $dynamic^)?
`)`
`->` type($result) attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::SizeInfoTypeAttr | size info type |
dynamic | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
ptr | CIR pointer type |
Result | Description |
---|---|
result | primitive int |
cir.pow
(cir::PowOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.pow` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
rhs | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.prefetch
(cir::PrefetchOp)Prefetch operation
Syntax:
operation ::= `cir.prefetch` `(` $addr `:` qualified(type($addr)) `)`
`locality``(` $locality `)`
(`write` $isWrite^) : (`read`)?
attr-dict
The cir.prefetch
op prefetches data from the memmory address.
cir.prefetch(%0 : !cir.ptr<!void>) locality(1) write
This opcode has the three attributes:
Attribute | MLIR Type | Description |
---|---|---|
locality | ::mlir::IntegerAttr | 32-bit signless integer attribute whose minimum value is 0 whose maximum value is 3 |
isWrite | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
addr | void* |
cir.ptr_diff
(cir::PtrDiffOp)Pointer subtraction arithmetic
Syntax:
operation ::= `cir.ptr_diff` `(` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `->` qualified(type($result)) attr-dict
cir.ptr_diff
performs a subtraction between two pointer types with the same element type and produces a mlir::cir::IntType
result.
Note that the result considers the pointer size according to the ABI for the pointee sizes, e.g. the subtraction between two !cir.ptr<!u64i>
might yield 1, meaning 8 bytes, whereas for void
or function type pointees, yielding 8 means 8 bytes.
%7 = "cir.ptr_diff"(%0, %1) : !cir.ptr<!u64i> -> !u64i
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | CIR pointer type |
rhs | CIR pointer type |
Result | Description |
---|---|
result | primitive int |
cir.ptr_stride
(cir::PtrStrideOp)Pointer access with stride
Syntax:
operation ::= `cir.ptr_stride` `(` $base `:` qualified(type($base)) `,` $stride `:` qualified(type($stride)) `)`
`,` qualified(type($result)) attr-dict
Given a base pointer as first operand, provides a new pointer after applying a stride (second operand).
%3 = cir.const 0 : i32
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32), !cir.ptr<i32>
Traits: AlwaysSpeculatableImplTrait
, SameFirstOperandAndResultType
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
base | CIR pointer type |
stride | primitive int |
Result | Description |
---|---|
result | CIR pointer type |
cir.resume
(cir::ResumeOp)Resumes execution after not catching exceptions
Syntax:
operation ::= `cir.resume` ($rethrow^)?
($exception_ptr^)?
(`,` $type_id^)?
attr-dict
The cir.resume
operation handles an uncaught exception scenario and behaves in two different modes:
CatchUnwind
region of cir.try
, where it does not receive any arguments (implied from the cir.try
scope), orcir.try
operation, where it requires an exception_ptr
and a type_id
.The rethrow
attribute is used to denote rethrowing behavior for the resume operation (versus default terminaton).
Traits: `AttrSizedOperandSegments`, `ReturnLike`, `Terminator`
Interfaces: `RegionBranchTerminatorOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>rethrow</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `exception_ptr` | void*
| `type_id` | 32-bit unsigned integer
### `cir.return` (cir::ReturnOp)
_Return from function_
Syntax:
operation ::= cir.return
($input^ :
type($input))? attr-dict
The "return" operation represents a return operation within a function.
The operation takes an optional operand and produces no results.
The operand type must match the signature of the function that contains
the operation.
```mlir
func @foo() -> i32 {
...
cir.return %0 : i32
}
Traits: HasParent<FuncOp, ScopeOp, IfOp, SwitchOp, DoWhileOp, WhileOp, ForOp>
, Terminator
Operand | Description |
---|---|
input | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.rint
(cir::RintOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.rint` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.rotate
(cir::RotateOp)Reverse the bytes that constitute the operand integer
Syntax:
operation ::= `cir.rotate` (`left` $left^) : (`right`)?
$src `,` $amt `->` type($result) attr-dict
The cir.rotate
rotates operand in src
by the given bit amount amt
. Its widths must be either 8, 16, 32, or 64 and both src
, amt
and result
be of the same type. The rotate direction is specified by a left
/right
keyword.
This operation covers different C/C++ builtins, some examples: __builtin_rotateleft8
, __builtin_rotateleft16
, __builtin_rotateleft32
, __builtin_rotateleft64
, _rotl8
, _rotl16
, _rotl
, _lrotl
, _rotl64
, etc and their "right" variants.
Example:
%r = cir.rotate left %0, %1 -> !u32i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
left | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
src | primitive int |
amt | primitive int |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.round
(cir::RoundOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.round` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.scope
(cir::ScopeOp)Represents a C/C++ scope
Syntax:
operation ::= `cir.scope` custom<OmittedTerminatorRegion>($scopeRegion) (`:` type($results)^)? attr-dict
cir.scope
contains one region and defines a strict "scope" for all new values produced within its blocks.
The region can contain an arbitrary number of blocks but usually defaults to one and can optionally return a value (useful for representing values coming out of C++ full-expressions) via cir.yield
:
%rvalue = cir.scope {
...
cir.yield %value
}
If cir.scope
yields no value, the cir.yield
can be left out, and will be inserted implicitly.
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Result | Description |
---|---|
results | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.select
(cir::SelectOp)Yield one of two values based on a boolean value
Syntax:
operation ::= `cir.select` `if` $condition `then` $true_value `else` $false_value
`:` `(`
qualified(type($condition)) `,`
qualified(type($true_value)) `,`
qualified(type($false_value))
`)` `->` qualified(type($result)) attr-dict
The cir.select
operation takes three operands. The first operand condition
is a boolean value of type !cir.bool
. The second and the third operand can be of any CIR types, but their types must be the same. If the first operand is true
, the operation yields its second operand. Otherwise, the operation yields its third operand.
Example:
%0 = cir.const #cir.bool<true> : !cir.bool
%1 = cir.const #cir.int<42> : !s32i
%2 = cir.const #cir.int<72> : !s32i
%3 = cir.select if %0 then %1 else %2 : (!cir.bool, !s32i, !s32i) -> !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
condition | CIR bool type |
true_value | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
false_value | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.set_bitfield
(cir::SetBitfieldOp)Set a bitfield
Syntax:
operation ::= `cir.set_bitfield` `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,`
$src`:`type($src) `)` attr-dict `->` type($result)
The cir.set_bitfield
operation provides a store-like access to a bit field of a record.
It expects an address of a storage where to store, a type of the storage, a value being stored, a name of a bit field, a pointer to the storage in the base record, a size of the storage, a size the bit field, an offset of the bit field and a sign. Returns a value being stored.
A unit attribute volatile
can be used to indicate a volatile load of the bitfield.
Example. Suppose we have a struct with multiple bitfields stored in different storages. The cir.set_bitfield
operation sets the value of the bitfield.
typedef struct {
int a : 4;
int b : 27;
int c : 17;
int d : 2;
int e : 15;
} S;
void store_bitfield(S& s) {
s.d = 3;
}
// 'd' is in the storage with the index 1
!struct_type = !cir.struct<struct "S" {!cir.int<u, 32>, !cir.int<u, 32>, !cir.int<u, 16>} #cir.record.decl.ast>
#bfi_d = #cir.bitfield_info<name = "d", storage_type = !u32i, size = 2, offset = 17, is_signed = true>
%1 = cir.const #cir.int<3> : !s32i
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!struct_type>>, !cir.ptr<!struct_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!struct_type> -> !cir.ptr<!u32i>
%4 = cir.set_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>, %1 : !s32i) -> !s32i
Attribute | MLIR Type | Description |
---|---|---|
bitfield_info | ::mlir::cir::BitfieldInfoAttr | Represents a bit field info |
is_volatile | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
addr | CIR pointer type |
src | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.shift
(cir::ShiftOp)Shift
Syntax:
operation ::= `cir.shift` `(`
(`left` $isShiftleft^) : (`right`)?
`,` $value `:` type($value)
`,` $amount `:` type($amount)
`)` `->` type($result) attr-dict
Shift left
or right
, according to the first operand. Second operand is the shift target and the third the amount.
%7 = cir.shift(left, %1 : !u64i, %4 : !s32i) -> !u64i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
isShiftleft | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
value | Integer type with arbitrary precision up to a fixed limit |
amount | Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.sin
(cir::SinOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.sin` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.sqrt
(cir::SqrtOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.sqrt` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.stack_restore
(cir::StackRestoreOp)Restores the state of the function stack
Syntax:
operation ::= `cir.stack_restore` $ptr attr-dict `:` qualified(type($ptr))
Restore the state of the function stack to the state it was in when the corresponding cir.stack_save executed. Useful for implementing language features like variable length arrays.
%0 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] {alignment = 8 : i64}
%1 = cir.stack_save : <!u8i>
cir.store %1, %0 : !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i>
cir.stack_restore %2 : !cir.ptr<!u8i>
Operand | Description |
---|---|
ptr | CIR pointer type |
cir.stack_save
(cir::StackSaveOp)Remembers the current state of the function stack
Syntax:
operation ::= `cir.stack_save` attr-dict `:` qualified(type($result))
Remembers the current state of the function stack. Returns a pointer that later can be passed into cir.stack_restore. Useful for implementing language features like variable length arrays.
%0 = cir.stack_save : <!u8i>
Result | Description |
---|---|
result | CIR pointer type |
cir.std.find
(cir::StdFindOp)Std:find()
Syntax:
operation ::= `cir.std.find` `(`
$original_fn
`,` $first `:` type($first)
`,` $last `:` type($last)
`,` $pattern `:` type($pattern)
`)` `->` type($result) attr-dict
Search for pattern
in data range from first
to last
. This currently maps to only one form of std::find
. The original_fn
operand tracks the mangled named that can be used when lowering to a cir.call
.
Example:
...
%result = cir.std.find(@original_fn,
%first : !T, %last : !T, %pattern : !P) -> !T
Traits: SameFirstSecondOperandAndResultType
Attribute | MLIR Type | Description |
---|---|---|
original_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operand | Description |
---|---|
first | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
last | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
pattern | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.store
(cir::StoreOp)Store value to memory address
Syntax:
operation ::= `cir.store` (`volatile` $is_volatile^)?
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
cir.store
stores a value (first operand) to the memory address specified in the second operand. A unit attribute volatile
can be used to indicate a volatile store. Store's can be marked atomic by using atomic(<mem_order>)
.
align
can be used to specify an alignment that's different from the default, which is computed from result
's type ABI data layout.
Example:
// Store a function argument to local storage, address in %0.
cir.store %arg0, %0 : i32, !cir.ptr<i32>
// Perform a volatile store into memory location at the address in %0.
cir.store volatile %arg0, %0 : i32, !cir.ptr<i32>
// Others
cir.store align(16) atomic(seq_cst) %x, %addr : i32, !cir.ptr<i32>
Interfaces: PromotableMemOpInterface
Attribute | MLIR Type | Description |
---|---|---|
is_volatile | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
mem_order | ::mlir::cir::MemOrderAttr | Memory order according to C++11 memory model |
Operand | Description |
---|---|
value | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
addr | CIR pointer type |
cir.switch.flat
(cir::SwitchFlatOp)Syntax:
operation ::= `cir.switch.flat` $condition `:` type($condition) `,`
$defaultDestination (`(` $defaultOperands^ `:` type($defaultOperands) `)`)?
custom<SwitchFlatOpCases>(ref(type($condition)), $case_values, $caseDestinations,
$caseOperands, type($caseOperands))
attr-dict
The cir.switch.flat
operation is a region-less and simplified version of the cir.switch
. It's representation is closer to LLVM IR dialect than the C/C++ language feature.
Traits: AttrSizedOperandSegments
, Terminator
Attribute | MLIR Type | Description |
---|---|---|
case_values | ::mlir::ArrayAttr | array attribute |
case_operand_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
Operand | Description |
---|---|
condition | Integer type with arbitrary precision up to a fixed limit |
defaultOperands | variadic of any type |
caseOperands | variadic of any type |
Successor | Description |
---|---|
defaultDestination | any successor |
caseDestinations | any successor |
cir.switch
(cir::SwitchOp)Switch operation
Syntax:
operation ::= `cir.switch` custom<SwitchOp>(
$regions, $cases, $condition, type($condition)
)
attr-dict
The cir.switch
operation represents C/C++ switch functionality for conditionally executing multiple regions of code. The operand to an switch is an integral condition value.
A variadic list of "case" attribute operands and regions track the possible control flow within cir.switch
. A case
must be in one of the following forms:
equal, <constant>
: equality of the second case operand against the condition.anyof, [constant-list]
: equals to any of the values in a subsequent following list.range, [lower-bound, upper-bound]
: the condition is within the closed interval.default
: any other value.Each case region must be explicitly terminated.
Examples:
cir.switch (%b : i32) [
case (equal, 20) {
...
cir.yield break
},
case (anyof, [1, 2, 3] : i32) {
...
cir.return ...
}
case (range, [10, 15]) {
...
cir.yield break
},
case (default) {
...
cir.yield fallthrough
}
]
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
, SameVariadicOperandSize
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Attribute | MLIR Type | Description |
---|---|---|
cases | ::mlir::ArrayAttr | cir.switch case array attribute |
Operand | Description |
---|---|
condition | Integer type with arbitrary precision up to a fixed limit |
cir.ternary
(cir::TernaryOp)The cond ? a : b
C/C++ ternary operation
Syntax:
operation ::= `cir.ternary` `(` $cond `,`
`true` $trueRegion `,`
`false` $falseRegion
`)` `:` functional-type(operands, results) attr-dict
The cir.ternary
operation represents C/C++ ternary, much like a select
operation. First argument is a cir.bool
condition to evaluate, followed by two regions to execute (true or false). This is different from cir.if
since each region is one block sized and the cir.yield
closing the block scope should have one argument.
Example:
// x = cond ? a : b;
%x = cir.ternary (%cond, true_region {
...
cir.yield %a : i32
}, false_region {
...
cir.yield %b : i32
}) -> i32
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Operand | Description |
---|---|
cond | CIR bool type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.throw
(cir::ThrowOp)(Re)Throws an exception
Syntax:
operation ::= `cir.throw` ($exception_ptr^ `:` type($exception_ptr))?
(`,` $type_info^)?
(`,` $dtor^)?
attr-dict
Very similar to __cxa_throw:
void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
void (*dest) (void *));
The absense of arguments for cir.throw
means it rethrows.
For the no-rethrow version, it must have at least two operands, the RTTI information, a pointer to the exception object (likely allocated via cir.cxa.allocate_exception
) and finally an optional dtor, which might run as part of this operation.
// if (b == 0)
// throw "Division by zero condition!";
cir.if %10 {
%11 = cir.alloc_exception 8 -> !cir.ptr<!void>
...
cir.store %13, %11 : // Store string addr for "Division by zero condition!"
cir.throw %11 : !cir.ptr<!cir.ptr<!u8i>>, @"typeinfo for char const*"
Attribute | MLIR Type | Description |
---|---|---|
type_info | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operand | Description |
---|---|
exception_ptr | CIR pointer type |
cir.trap
(cir::TrapOp)Exit the program abnormally
Syntax:
operation ::= `cir.trap` attr-dict
The cir.trap operation causes the program to exit abnormally. The implementations may implement this operation with different mechanisms. For example, an implementation may implement this operation by calling abort, while another implementation may implement this operation by executing an illegal instruction.
Traits: Terminator
cir.trunc
(cir::TruncOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.trunc` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
Result | Description |
---|---|
result | CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type |
cir.try_call
(cir::TryCallOp)Try_call operation
Mostly similar to cir.call but requires two destination branches, one for handling exceptions in case its thrown and the other one to follow on regular control-flow.
Example:
// Direct call
%2 = cir.try_call @my_add(%0, %1) ^continue, ^landing_pad : (f32, f32) -> f32
Traits: AttrSizedOperandSegments
, Terminator
Interfaces: BranchOpInterface
, CIRCallOpInterface
, CallOpInterface
, SymbolUserOpInterface
Attribute | MLIR Type | Description |
---|---|---|
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
extra_attrs | ::mlir::cir::ExtraFuncAttributesAttr | Represents aggregated attributes for a function |
ast | ::mlir::cir::ASTCallExprInterface | ASTCallExprInterface instance |
Operand | Description |
---|---|
contOperands | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
landingPadOperands | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
arg_ops | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Successor | Description |
---|---|
cont | any successor |
landing_pad | any successor |
cir.try
(cir::TryOp)C++ try block
Syntax:
operation ::= `cir.try` (`synthetic` $synthetic^)? $try_region
`cleanup` $cleanup_region
custom<CatchRegions>($catch_regions, $catch_types)
attr-dict
Holds the lexical scope of `try {}`. Note that resources used on catch
clauses are usually allocated in the same parent as `cir.try`.
`synthetic`: use `cir.try` to represent try/catches not originally
present in the source code (e.g. `g = new Class` under `-fexceptions`).
Example: TBD
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Attribute | MLIR Type | Description |
---|---|---|
synthetic | ::mlir::UnitAttr | unit attribute |
catch_types | ::mlir::ArrayAttr | array attribute |
cir.unary
(cir::UnaryOp)Unary operations
Syntax:
operation ::= `cir.unary` `(` $kind `,` $input `)` `:` type($input) `,` type($result) attr-dict
cir.unary
performs the unary operation according to the specified opcode kind: [inc, dec, plus, minus, not].
It requires one input operand and has one result, both types should be the same.
%7 = cir.unary(inc, %1) : i32 -> i32
%8 = cir.unary(dec, %2) : i32 -> i32
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::UnaryOpKindAttr | unary operation kind |
Operand | Description |
---|---|
input | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.undef
(cir::UndefOp)Creates an undefined value of CIR dialect type.
Syntax:
operation ::= `cir.undef` attr-dict `:` type($res)
cir.undef
is similar to the one in the LLVM IR dialect Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Result | Description |
---|---|
res | any type |
cir.unreachable
(cir::UnreachableOp)Invoke immediate undefined behavior
Syntax:
operation ::= `cir.unreachable` attr-dict
If the program control flow reaches a cir.unreachable
operation, the program exhibits undefined behavior immediately. This operation is useful in cases where the unreachability of a program point needs to be explicitly marked.
Traits: Terminator
cir.va.arg
(cir::VAArgOp)Fetches next variadic element as a given type
Syntax:
operation ::= `cir.va.arg` $arg_list attr-dict `:` functional-type(operands, $result)
Operand | Description |
---|---|
arg_list | CIR pointer type |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.va.copy
(cir::VACopyOp)Copies a variable argument list
Syntax:
operation ::= `cir.va.copy` $src_list `to` $dst_list attr-dict `:` type(operands)
Operand | Description |
---|---|
dst_list | CIR pointer type |
src_list | CIR pointer type |
cir.va.end
(cir::VAEndOp)Ends a variable argument list
Syntax:
operation ::= `cir.va.end` $arg_list attr-dict `:` type(operands)
Operand | Description |
---|---|
arg_list | CIR pointer type |
cir.va.start
(cir::VAStartOp)Starts a variable argument list
Syntax:
operation ::= `cir.va.start` $arg_list attr-dict `:` type(operands)
Operand | Description |
---|---|
arg_list | CIR pointer type |
cir.vtable.address_point
(cir::VTableAddrPointOp)Get the vtable (global variable) address point
Syntax:
operation ::= `cir.vtable.address_point` `(`
($name^)?
($sym_addr^ `:` type($sym_addr))?
`,`
`vtable_index` `=` $vtable_index `,`
`address_point_index` `=` $address_point_index
`)`
`:` qualified(type($addr)) attr-dict
The vtable.address_point
operation retrieves the "effective" address (address point) of a C++ virtual table. An object internal __vptr
gets initializated on top of the value returned by this operation.
vtable_index
provides the appropriate vtable within the vtable group (as specified by Itanium ABI), and addr_point_index
the actual address point within that vtable.
The return type is always a !cir.ptr<!cir.ptr<() -> i32>>
.
Example:
cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<() -> i32>>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
, SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
vtable_index | ::mlir::IntegerAttr | 32-bit signless integer attribute |
address_point_index | ::mlir::IntegerAttr | 32-bit signless integer attribute |
Operand | Description |
---|---|
sym_addr | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
addr | CIR pointer type |
cir.vec.cmp
(cir::VecCmpOp)Compare two vectors
Syntax:
operation ::= `cir.vec.cmp` `(` $kind `,` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `,`
qualified(type($result)) attr-dict
The cir.vec.cmp
operation does an element-wise comparison of two vectors of the same type. The result is a vector of the same size as the operands whose element type is the signed integral type that is the same size as the element type of the operands. The values in the result are 0 or -1.
Traits: AlwaysSpeculatableImplTrait
, SameTypeOperands
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::mlir::cir::CmpOpKindAttr | compare operation kind |
Operand | Description |
---|---|
lhs | CIR vector type |
rhs | CIR vector type |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.create
(cir::VecCreateOp)Create a vector value
Syntax:
operation ::= `cir.vec.create` `(` ($elements^ `:` type($elements))? `)` `:` qualified(type($result))
attr-dict
The cir.vec.create
operation creates a vector value with the given element values. The number of element arguments must match the number of elements in the vector type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
elements | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.extract
(cir::VecExtractOp)Extract one element from a vector object
Syntax:
operation ::= `cir.vec.extract` $vec `[` $index `:` type($index) `]` attr-dict `:` qualified(type($vec))
The cir.vec.extract
operation extracts the element at the given index from a vector object.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
vec | CIR vector type |
index | primitive int |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
cir.vec.insert
(cir::VecInsertOp)Insert one element into a vector object
Syntax:
operation ::= `cir.vec.insert` $value `,` $vec `[` $index `:` type($index) `]` attr-dict `:`
qualified(type($vec))
The cir.vec.insert
operation replaces the element of the given vector at the given index with the given value. The new vector with the inserted element is returned.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
vec | CIR vector type |
value | any type |
index | primitive int |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.shuffle.dynamic
(cir::VecShuffleDynamicOp)Shuffle a vector using indices in another vector
Syntax:
operation ::= `cir.vec.shuffle.dynamic` $vec `:` qualified(type($vec)) `,` $indices `:` qualified(type($indices))
attr-dict
The cir.vec.shuffle.dynamic
operation implements the undocumented form of Clang's __builtin_shufflevector, where the indices of the shuffled result can be runtime values.
There are two input vectors, which must have the same number of elements. The second input vector must have an integral element type. The elements of the second vector are interpreted as indices into the first vector. The result vector is constructed by taking the elements from the first input vector from the indices indicated by the elements of the second vector.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
vec | CIR vector type |
indices | !cir.vector of !cir.int |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.shuffle
(cir::VecShuffleOp)Combine two vectors using indices passed as constant integers
Syntax:
operation ::= `cir.vec.shuffle` `(` $vec1 `,` $vec2 `:` qualified(type($vec1)) `)` $indices `:`
qualified(type($result)) attr-dict
The cir.vec.shuffle
operation implements the documented form of Clang's __builtin_shufflevector, where the indices of the shuffled result are integer constants.
The two input vectors, which must have the same type, are concatenated. Each of the integer constant arguments is interpreted as an index into that concatenated vector, with a value of -1 meaning that the result value doesn't matter. The result vector, which must have the same element type as the input vectors and the same number of elements as the list of integer constant indices, is constructed by taking the elements at the given indices from the concatenated vector. The size of the result vector does not have to match the size of the individual input vectors or of the concatenated vector.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
indices | ::mlir::ArrayAttr | array attribute |
Operand | Description |
---|---|
vec1 | CIR vector type |
vec2 | CIR vector type |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.splat
(cir::VecSplatOp)Convert a scalar into a vector
Syntax:
operation ::= `cir.vec.splat` $value `:` type($value) `,` qualified(type($result)) attr-dict
The cir.vec.splat
operation creates a vector value from a scalar value. All elements of the vector have the same value, that of the given scalar.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
value | Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |
Result | Description |
---|---|
result | CIR vector type |
cir.vec.ternary
(cir::VecTernaryOp)The cond ? a : b
ternary operator for vector types
Syntax:
operation ::= `cir.vec.ternary` `(` $cond `,` $vec1 `,` $vec2 `)` `:` qualified(type($cond)) `,`
qualified(type($vec1)) attr-dict
The cir.vec.ternary
operation represents the C/C++ ternary operator, ?:
, for vector types, which does a select
on individual elements of the vectors. Unlike a regular ?:
operator, there is no short circuiting. All three arguments are always evaluated. Because there is no short circuiting, there are no regions in this operation, unlike cir.ternary.
The first argument is a vector of integral type. The second and third arguments are vectors of the same type and have the same number of elements as the first argument.
The result is a vector of the same type as the second and third arguments. Each element of the result is (bool)a[n] ? b[n] : c[n]
.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
cond | !cir.vector of !cir.int |
vec1 | CIR vector type |
vec2 | CIR vector type |
Result | Description |
---|---|
result | CIR vector type |
cir.while
(cir::WhileOp)C/C++ while loop
Syntax:
operation ::= `cir.while` $cond `do` $body attr-dict
Represents a C/C++ while loop. It consists of two regions:
cond
: single block region with the loop's condition. Should be terminated with a cir.condition
operation.body
: contains the loop body and an arbitrary number of blocks.Example:
cir.while {
cir.break
^bb2:
cir.yield
} do {
cir.condition %cond : cir.bool
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface
, LoopOpInterface
, RegionBranchOpInterface
cir.yield
(cir::YieldOp)Represents the default branching behaviour of a region
Syntax:
operation ::= `cir.yield` ($args^ `:` type($args))? attr-dict
The cir.yield
operation terminates regions on different CIR operations, and it is used to represent the default branching behaviour of a region. Said branching behaviour is determinted by the parent operation. For example, a yield in a switch-case
region implies a fallthrough, while a yield in a cir.if
region implies a branch to the exit block, and so on.
In some cases, it might yield an SSA value and the semantics of how the values are yielded is defined by the parent operation. For example, a cir.ternary
operation yields a value from one of its regions.
As a general rule, cir.yield
must be explicitly used whenever a region has more than one block and no terminator, or within cir.switch
regions not cir.return
terminated.
Examples:
cir.if %4 {
...
cir.yield
}
cir.switch (%5) [
case (equal, 3) {
...
cir.yield
}, ...
]
cir.scope {
...
cir.yield
}
%x = cir.scope {
...
cir.yield %val
}
%y = cir.ternary {
...
cir.yield %val : i32
} : i32
Traits: HasParent<IfOp, ScopeOp, SwitchOp, WhileOp, ForOp, AwaitOp, TernaryOp, GlobalOp, DoWhileOp, TryOp, ArrayCtor, ArrayDtor>
, ReturnLike
, Terminator
Interfaces: RegionBranchTerminatorOpInterface
Operand | Description |
---|---|
args | variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type |