cir.acos
(::cir::ACosOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.acos` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.asin
(::cir::ASinOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.asin` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.atan
(::cir::ATanOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.atan` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.abs
(::cir::AbsOp)_Libc builtin equivalent abs, labs, llabs
The `poison` argument indicate whether the result value
is a poison value if the first argument is statically or
dynamically an INT_MIN value.
Example:
```mlir
%0 = cir.const #cir.int<-42> : s32i
%1 = cir.abs %0 poison : s32i
%2 = cir.abs %3 : !cir.vector<!s32i x 4>
```_
Syntax:
operation ::= `cir.abs` $src ( `poison` $poison^ )? `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
poison | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
src | fundamental signed integer type or !cir.vector of !cir.int |
Result | Description |
---|---|
result | fundamental signed integer type or !cir.vector of !cir.int |
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^)?
(`,` `const` $constant^)?
`]`
($annotations^)?
(`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 presence of the const
attribute indicates that the local variable is declared with C/C++ const
keyword.
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 |
constant | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute whose minimum value is 0 |
annotations | ::mlir::ArrayAttr | array attribute |
ast | ::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
Operand | Description |
---|---|
dynAllocSize | fundamental integer type |
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.array> |
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.array> |
cir.assume.aligned
(::cir::AssumeAlignedOp)Tell the optimizer that a pointer is aligned
Syntax:
operation ::= `cir.assume.aligned` $pointer `:` qualified(type($pointer))
`[` `alignment` $alignment (`,` `offset` $offset^ `:` type($offset))? `]`
attr-dict
The cir.assume.aligned
operation takes two or three arguments.
When the 3rd argument offset
is absent, this operation tells the optimizer that the pointer given by the pointer
argument is aligned to the alignment given by the align
argument.
When the offset
argument is given, it represents an offset from the alignment. This operation then tells the optimizer that the pointer given by the pointer
argument is always misaligned by the alignment given by the align
argument by offset
bytes, a.k.a. the pointer yielded by (char *)pointer - offset
is aligned to the specified alignment.
The align
argument is a constant integer represented as an integer attribute instead of an SSA value. It must be a positive integer.
The result of this operation has the same value as the pointer
argument, but the optimizer has additional knowledge about its alignment.
This operation corresponds to the __builtin_assume_aligned
builtin function.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operand | Description |
---|---|
pointer | CIR pointer type |
offset | Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | CIR pointer type |
cir.assume
(::cir::AssumeOp)Tell the optimizer that a boolean value is true
Syntax:
operation ::= `cir.assume` $predicate `:` type($predicate) attr-dict
The cir.assume
operation takes a single boolean prediate as its only argument and does not have any results. The operation tells the optimizer that the predicate's value is true.
This operation corresponds to the __assume
and the __builtin_assume
builtin function.
Operand | Description |
---|---|
predicate | CIR bool type |
cir.assume.separate_storage
(::cir::AssumeSepStorageOp)Tell the optimizer that two pointers point to different allocations
Syntax:
operation ::= `cir.assume.separate_storage` $ptr1 `,` $ptr2 `:` qualified(type($ptr1)) attr-dict
The cir.assume.separate_storage
operation takes two pointers as arguments, and the operation tells the optimizer that these two pointers point to different allocations.
This operation corresponds to the __builtin_assume_separate_storage
builtin function.
Traits: SameTypeOperands
Operand | Description |
---|---|
ptr1 | pointer to void type |
ptr2 | pointer to void type |
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
`)`
(`syncscope` `(` $syncscope^ `)`)?
(`align` `(` $alignment^ `)`)?
(`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_record>, %expected : !u64i, %desired : !u64i, success = seq_cst, failure = seq_cst) weak : (!u64i, !cir.bool)
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
succ_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
fail_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
syncscope | ::cir::MemScopeKindAttr | Memory Scope Enumeration |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
cmp | CIR bool type |
cir.atomic.fence
(::cir::AtomicFence)Atomic thread fence
Syntax:
operation ::= `cir.atomic.fence` (`syncscope` `(` $syncscope^ `)`)? $ordering attr-dict
C/C++ Atomic thread fence synchronization primitive. Implements the builtin __atomic_thread_fence
which enforces memory ordering constraints across threads within the specified synchronization scope.
This handles all variations including:
__atomic_thread_fence
__atomic_signal_fence
__c11_atomic_thread_fence
__c11_atomic_signal_fence
Example:
cir.atomic.fence syncscope(system) seq_cst
cir.atomic.fence syncscope(single_thread) seq_cst
Attribute | MLIR Type | Description |
---|---|---|
ordering | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
syncscope | ::cir::MemScopeKindAttr | Memory Scope Enumeration |
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 | ::cir::AtomicFetchKindAttr | Binary opcode for atomic fetch operations |
mem_order | ::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 | integer or floating point type |
Result | Description |
---|---|
result | integer or floating point type |
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_record>, %val : !u64i, seq_cst) : !u64i
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
mem_order | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | ::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))
(`nonnull` $assume_not_null^)?
`)` `[` $offset `]` `->` qualified(type($base_addr)) attr-dict
The cir.base_class_addr
operaration gets the address of a particular non-virtual base class given a derived class pointer. The offset in bytes of the base class must be passed in, since it is easier for the front end to calculate that than the MLIR passes. The operation contains a flag for whether or not the operand may be nullptr. That depends on the context and cannot be known by the operation, and that information affects how the operation is lowered.
Example:
struct Base { };
struct Derived : Base { };
Derived d;
Base& b = d;
will generate
%3 = cir.base_class_addr (%1 : !cir.ptr<!rec_Derived> nonnull) [0] -> !cir.ptr<!rec_Base>
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
derived_addr | CIR pointer type |
Result | Description |
---|---|
base_addr | CIR pointer type |
cir.base_data_member
(::cir::BaseDataMemberOp)Cast a derived class data member pointer to a base class data member pointer
Syntax:
operation ::= `cir.base_data_member` `(` $src `:` qualified(type($src)) `)`
`[` $offset `]` `->` qualified(type($result)) attr-dict
The cir.base_data_member
operation casts a data member pointer of type T Derived::*
to a data member pointer of type T Base::*
, where Base
is an accessible non-ambiguous non-virtual base class of Derived
.
The offset
parameter gives the offset in bytes of the Base
base class subobject within a Derived
object.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
src | CIR type that represents pointer-to-data-member type in C++ |
Result | Description |
---|---|
result | CIR type that represents pointer-to-data-member type in C++ |
cir.base_method
(::cir::BaseMethodOp)Cast a derived class pointer-to-member-function to a base class pointer-to-member-function
Syntax:
operation ::= `cir.base_method` `(` $src `:` qualified(type($src)) `)`
`[` $offset `]` `->` qualified(type($result)) attr-dict
The cir.base_method
operation casts a pointer-to-member-function of type Ret (Derived::*)(Args)
to a pointer-to-member-function of type Ret (Base::*)(Args)
, where Base
is a non-virtual base class of Derived
.
The offset
parameter gives the offset in bytes of the Base
base class subobject within a Derived
object.
Example:
%1 = cir.base_method(%0 : !cir.method<!cir.func<(!s32i)> in !rec_Derived>) [16] -> !cir.method<!cir.func<(!s32i)> in !rec_Base>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
src | CIR type that represents C++ pointer-to-member-function type |
Result | Description |
---|---|
result | CIR type that represents C++ pointer-to-member-function 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^)?
(`sat` $saturated^)?
`:` 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 | ::cir::BinOpKindAttr | binary operation (arith and logic) kind |
no_unsigned_wrap | ::mlir::UnitAttr | unit attribute |
no_signed_wrap | ::mlir::UnitAttr | unit attribute |
saturated | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | ::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
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | signed integer type of widths 32/64 |
Result | Description |
---|---|
result | signed integer type of widths 32/64 |
cir.bit.clz
(::cir::BitClzOp)Get the number of leading 0-bits in the input
Syntax:
operation ::= `cir.bit.clz` `(` $input `:` type($input) `)` (`zero_poison` $is_zero_poison^)?
`:` 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.
Zero_poison attribute means this operation invokes undefined behavior if the input value is 0.
Example:
!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) zero_poison : !u32i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
is_zero_poison | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
input | unsigned integer type of widths 16/32/64 |
Result | Description |
---|---|
result | unsigned integer type of widths 16/32/64 |
cir.bit.ctz
(::cir::BitCtzOp)Get the number of trailing 0-bits in the input
Syntax:
operation ::= `cir.bit.ctz` `(` $input `:` type($input) `)` (`zero_poison` $is_zero_poison^)?
`:` 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.
Zero_poison attribute means 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) : !u32i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
is_zero_poison | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
input | unsigned integer type of widths 16/32/64 |
Result | Description |
---|---|
result | unsigned integer type of widths 16/32/64 |
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
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | signed integer type of widths 32/64 |
Result | Description |
---|---|
result | signed integer type of widths 32/64 |
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
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | unsigned integer type of widths 32/64 |
Result | Description |
---|---|
result | unsigned integer type of widths 32/64 |
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
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | unsigned integer type of widths 16/32/64 |
Result | Description |
---|---|
result | unsigned integer type of widths 16/32/64 |
cir.bit_reverse
(::cir::BitReverseOp)Reverse the bit pattern of the operand integer
Syntax:
operation ::= `cir.bit_reverse` $src `:` type($result) attr-dict
The cir.bit_reverse
operation reverses the bit pattern of the operand integer. Its only argument must be of unsigned integer types of width 8, 16, 32, or 64.
This operation covers the C/C++ builtin function __builtin_bitreverse
.
Example:
%1 = cir.bit_reverse %0 : !u32i
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | unsigned integer type of widths 8/16/32/64 |
Result | Description |
---|---|
result | unsigned integer type of widths 8/16/32/64 |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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.
Note that for source level goto
's crossing scope boundaries, those are usually represented with the "symbolic" cir.goto
operation.
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | unsigned integer type of widths 16/32/64 |
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 record type.
Example:
__asm__("foo" : : : );
__asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
__asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
!rec_22anon2E022 = !cir.record<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
!rec_22anon2E122 = !cir.record<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}"}) -> !rec_22anon2E022
cir.asm(x86_att,
out = [],
in = [%3 : !s32i],
in_out = [%2 : !s32i],
{"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_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 | ::cir::AsmFlavorAttr | ATT or Intel |
operand_attrs | ::mlir::ArrayAttr | array attribute |
operands_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
Operand | Description |
---|---|
asm_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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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
.
If the cir.call
has the exception
keyword, the call can throw. In this case, cleanups can be added in the cleanup
region.
Example:
// Direct call
%2 = cir.call @my_add(%0, %1) : (f32, f32) -> f32
...
// Indirect call
%20 = cir.call %18(%17)
...
// Call that might throw
cir.call exception @my_div() -> () cleanup {
// call dtor...
}
Traits: NoRegionArguments
Interfaces: CIRCallOpInterface
, CallOpInterface
, SymbolUserOpInterface
Attribute | MLIR Type | Description |
---|---|---|
exception | ::mlir::UnitAttr | unit attribute |
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
calling_conv | ::cir::CallingConvAttr | calling convention |
side_effect | ::cir::SideEffectAttr | allowed side effects of a function |
extra_attrs | ::cir::ExtraFuncAttributesAttr | Represents aggregated attributes for a function |
ast | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
cir.case
(::cir::CaseOp)Case operation
Syntax:
operation ::= `cir.case` `(` $kind `,` $value `)` $caseRegion attr-dict
The cir.case
operation represents a case within a C/C++ switch. The cir.case
operation must be in a cir.switch
operation directly or indirectly.
The cir.case
have 4 kinds:
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.
Traits: AutomaticAllocationScope
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Attribute | MLIR Type | Description |
---|---|---|
value | ::mlir::ArrayAttr | array attribute |
kind | ::cir::CaseOpKindAttr | case kind |
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 | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | ::cir::CatchParamKindAttr | Designate limits for begin/end of catch param handling |
Operand | Description |
---|---|
exception_ptr | pointer to void type |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | pointer to void type |
end | pointer to void type |
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
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
kind | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
Result | Description |
---|---|
result | CIR bool 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 | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
Result | Description |
---|---|
result | signed integer type |
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 | ::cir::ComplexBinOpKindAttr | complex number binary operation kind |
range | ::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 | integer or floating point type |
imag | integer or floating point type |
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 | integer or floating point type |
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 | integer or floating point type |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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))
(`tbaa` `(` $tbaa^ `)`)?
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 record to another:
cir.copy %0 to %1 : !cir.ptr<!record_ty>
Traits: SameTypeOperands
Interfaces: PromotableMemOpInterface
Attribute | MLIR Type | Description |
---|---|---|
is_volatile | ::mlir::UnitAttr | unit attribute |
tbaa | ::cir::TBAAAttr | CIR dialect TBAA base 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.delete.array
(::cir::DeleteArrayOp)Delete address representing an array
Syntax:
operation ::= `cir.delete.array` $address `:` type($address) attr-dict
cir.delete.array
operation deletes an array. For example, delete[] ptr;
will be translated to cir.delete.array %ptr
.
Operand | Description |
---|---|
address | CIR pointer type |
cir.derived_class_addr
(::cir::DerivedClassAddrOp)Get the derived class address for a class/struct
Syntax:
operation ::= `cir.derived_class_addr` `(`
$base_addr `:` qualified(type($base_addr))
(`nonnull` $assume_not_null^)?
`)` `[` $offset `]` `->` qualified(type($derived_addr)) attr-dict
The cir.derived_class_addr
operaration gets the address of a particular derived class given a non-virtual base class pointer. The offset in bytes of the base class must be passed in, similar to cir.base_class_addr
, but going into the other direction (In the itanium ABI this means lowering to a negative offset).
The operation contains a flag for whether or not the operand may be nullptr. That depends on the context and cannot be known by the operation, and that information affects how the operation is lowered.
Example:
class A { int a; };
class B { int b;
public:
A *getAsA();
};
class X : public A, public B { int x; };
A *B::getAsA() {
return static_cast<X*>(this);
leads to
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_B>>, !cir.ptr<!rec_B>
%3 = cir.derived_class_addr(%2 : !cir.ptr<!rec_B> nonnull) [4] -> !cir.ptr<!rec_X>
%4 = cir.base_class_addr(%3 : !cir.ptr<!rec_X>) [0] -> !cir.ptr<!rec_A>
cir.return %4
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
base_addr | CIR pointer type |
Result | Description |
---|---|
derived_addr | CIR pointer type |
cir.derived_data_member
(::cir::DerivedDataMemberOp)Cast a base class data member pointer to a derived class data member pointer
Syntax:
operation ::= `cir.derived_data_member` `(` $src `:` qualified(type($src)) `)`
`[` $offset `]` `->` qualified(type($result)) attr-dict
The cir.derived_data_member
operation casts a data member pointer of type T Base::*
to a data member pointer of type T Derived::*
, where Base
is an accessible non-ambiguous non-virtual base class of Derived
.
The offset
parameter gives the offset in bytes of the Base
base class subobject within a Derived
object.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
src | CIR type that represents pointer-to-data-member type in C++ |
Result | Description |
---|---|
result | CIR type that represents pointer-to-data-member type in C++ |
cir.derived_method
(::cir::DerivedMethodOp)Cast a base class pointer-to-member-function to a derived class pointer-to-member-function
Syntax:
operation ::= `cir.derived_method` `(` $src `:` qualified(type($src)) `)`
`[` $offset `]` `->` qualified(type($result)) attr-dict
The cir.derived_method
operation casts a pointer-to-member-function of type Ret (Base::*)(Args)
to a pointer-to-member-function of type Ret (Derived::*)(Args)
, where Base
is a non-virtual base class of Derived
.
The offset
parameter gives the offset in bytes of the Base
base class subobject within a Derived
object.
Example:
%1 = cir.derived_method(%0 : !cir.method<!cir.func<(!s32i)> in !rec_Base>) [16] -> !cir.method<!cir.func<(!s32i)> in !rec_Derived>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
src | CIR type that represents C++ pointer-to-member-function type |
Result | Description |
---|---|
result | CIR type that represents C++ pointer-to-member-function 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 record 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 record pointers:
The input of the operation must be a record pointer. The result of the operation is either a record 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 | ::cir::DynamicCastKindAttr | dynamic cast kind |
info | ::cir::DynamicCastInfoAttr | ABI specific information about a dynamic cast |
relative_layout | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
src | !cir.record* |
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 | pointer to void type |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | fundamental integer type |
expected | fundamental integer type |
Result | Description |
---|---|
result | fundamental integer type |
cir.extract_member
(::cir::ExtractMemberOp)Extract the value of a member of a record value
Syntax:
operation ::= `cir.extract_member` $record `[` $index_attr `]` attr-dict
`:` qualified(type($record)) `->` qualified(type($result))
The cir.extract_member
operation extracts the value of a particular member from the input record. Unlike cir.get_member
which derives pointers, this operation operates on values. It takes a value of record type, and extract the value of the specified record member from the input record value.
Currently cir.extract_member
does not work on unions.
Example:
// Suppose we have a record with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!record_ty = !cir.record<"struct.Bar" {!s32i, !s8i}>
// And suppose we have a value of the record type.
%0 = cir.const #cir.const_record<{#cir.int<1> : !s32i, #cir.int<2> : !s8i}> : !record_ty
// Extract the value of the second member of the record.
%1 = cir.extract_member %0[1] : !record_ty -> !s8i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
index_attr | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
record | CIR record 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.fmaxnum
(::cir::FMaxNumOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fmaxnum` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.fmaximum
(::cir::FMaximumOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fmaximum` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.fminnum
(::cir::FMinNumOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fminnum` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.fminimum
(::cir::FMinimumOp)Libc builtin equivalent ignoring floating-point exceptions and errno.
Syntax:
operation ::= `cir.fminimum` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
lhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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.frame_address
(::cir::FrameAddrOp)The frame address of the current function, or of one of its callers
Syntax:
operation ::= `cir.frame_address` `(` $level `)` attr-dict
Represents call to builtin function ` __builtin_frame_address` in CIR. This builtin function returns the frame address of the current function, or of one of its callers. The frame is the area on the stack that holds local variables and saved registers. The frame address is normally the address of the first word pushed on to the stack by the function. However, the exact definition depends upon the processor and the calling convention. If the processor has a dedicated frame pointer register, and the function has a frame, then __builtin_frame_address returns the value of the frame pointer register.
The level
argument is number of frames to scan up the call stack. For instance, value of 0 yields the frame address of the current function, value of 1 yields the frame address of the caller of the current function, and so forth.
Examples:
%p = frame_address(%level) -> !cir.ptr<!void>
Interfaces: InferTypeOpInterface
Operand | Description |
---|---|
level | 32-bit unsigned integer |
Result | Description |
---|---|
result | pointer to void type |
cir.free.exception
(::cir::FreeExceptionOp)Frees an exception according to Itanium ABI
Syntax:
operation ::= `cir.free.exception` $ptr attr-dict
Implements a slightly higher level version of: void __cxa_free_exception(void *thrown_exception);
Example:
%0 = cir.alloc.exception 16 -> !cir.ptr<!some_record>
%1 = cir.get_global @d2 : !cir.ptr<!some_record>
cir.try synthetic cleanup {
cir.call exception @_ZN7test2_DC1ERKS_(%0, %1) : (!cir.ptr<!some_record>, !cir.ptr<!some_record>) -> () cleanup {
%2 = cir.cast(bitcast, %0 : !cir.ptr<!some_record>), !cir.ptr<!void>
cir.free.exception %2
cir.yield
}
...
}
Operand | Description |
---|---|
ptr | pointer to void type |
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 | ::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 | ::cir::GlobalLinkageKindAttr | Linkage type/kind |
calling_conv | ::cir::CallingConvAttr | calling convention |
extra_attrs | ::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 | ::cir::GlobalCtorAttr | Marks a function as a global constructor |
global_dtor | ::cir::GlobalDtorAttr | Marks a function as a global destructor |
annotations | ::mlir::ArrayAttr | array attribute |
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
!record_type = !cir.record<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<!record_type>>, !cir.ptr<!record_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!record_type> -> !cir.ptr<!u32i>
%4 = cir.get_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>) -> !s32i
Attribute | MLIR Type | Description |
---|---|---|
bitfield_info | ::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 record
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 record with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!record_ty = !cir.record<"struct.Bar" {!s32i, !s8i}>
// Get the address of the member at index 1.
%1 = cir.get_member %0[1] {name = "i"} : (!cir.ptr<!record_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.record* |
Result | Description |
---|---|
callee | !cir.ptr<!cir.func> |
adjusted_this | pointer to void type |
cir.get_runtime_member
(::cir::GetRuntimeMemberOp)Get the address of a member of a record
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.record* |
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^)?
(`` $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)
($annotations^)?
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 | ::cir::VisibilityAttr | Visibility attribute |
sym_visibility | ::mlir::StringAttr | string attribute |
sym_type | ::mlir::TypeAttr | any type attribute |
linkage | ::cir::GlobalLinkageKindAttr | Linkage type/kind |
addr_space | ::cir::AddressSpaceAttr | Address space attribute for pointer types |
tls_model | ::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 | ::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
section | ::mlir::StringAttr | string attribute |
annotations | ::mlir::ArrayAttr | array attribute |
cir.goto
(::cir::GotoOp)Syntax:
operation ::= `cir.goto` $label attr-dict
Transfers control to the specified label
. This requires a corresponding cir.label
to exist and is used by to represent source level goto
s that jump across region boundaries. Alternatively, cir.br
is used to construct goto's that don't violate such boundaries.
cir.goto
is completely symbolic (i.e. it "jumps" on a label that isn't yet materialized) and should be taken into account by passes and analysis when deciding if it's safe to make some assumptions about a given region or basic block.
Example:
int test(int x) {
if (x)
goto label;
{
x = 10;
label:
return x;
}
}
cir.scope { // REGION #1
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.cast(int_to_bool, %2 : !s32i), !cir.bool
cir.if %3 {
cir.goto "label"
}
}
cir.scope { // REGION #2
%2 = cir.const #cir.int<10> : !s32i
cir.store %2, %0 : !s32i, !cir.ptr<!s32i>
cir.br ^bb1
^bb1: // pred: ^bb0
cir.label "label"
%3 = cir.load %0 : !cir.ptr<!s32i>, !s32i
cir.store %3, %1 : !s32i, !cir.ptr<!s32i>
%4 = cir.load %1 : !cir.ptr<!s32i>, !s32i
cir.return %4 : !s32i
}
cir.unreachable
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. The if/else regions must be terminated. If the region has only one block, the terminator can be left out, and cir.yield
terminator will be inserted implictly. Otherwise, the region must be explicitly terminated.
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Operand | Description |
---|---|
condition | CIR bool type |
cir.insert_member
(::cir::InsertMemberOp)Overwrite the value of a member of a record value
Syntax:
operation ::= `cir.insert_member` $record `[` $index_attr `]` `,` $value attr-dict
`:` qualified(type($record)) `,` qualified(type($value))
The cir.insert_member
operation overwrites the value of a particular member in the input record value, and returns the modified record value. The result of this operation is equal to the input record value, except for the member specified by index_attr
whose value is equal to the given value.
This operation is named after the LLVM instruction insertvalue
.
Currently cir.insert_member
does not work on unions.
Example:
// Suppose we have a record with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!record_ty = !cir.record<"struct.Bar" {!s32i, !s8i}>
// And suppose we have a value of the record type.
%0 = cir.const #cir.const_record<{#cir.int<1> : !s32i, #cir.int<2> : !s8i}> : !record_ty
// %0 is {1, 2}
// Overwrite the second member of the record value.
%1 = cir.const #cir.int<3> : !s8i
%2 = cir.insert_member %0[1], %1 : !record_ty, !s8i
// %2 is {1, 3}
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
index_attr | ::mlir::IntegerAttr | index attribute |
Operand | Description |
---|---|
record | CIR record type |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
Result | Description |
---|---|
result | CIR record type |
cir.invariant_group
(::cir::InvariantGroupOp)Start an invariant group
Syntax:
operation ::= `cir.invariant_group` $ptr `:` type($result) attr-dict
The cir.invariant_group
operation takes a single pointer value as argument and returns the same pointer value with fresh invariant group information. All loads and stores that access the returned pointer value are presumed by the optimizer to load or store the same value.
This operation is not emitted during CIRGen. Instead, it is created when hoisting constant alloca operations to the entry block of a function. This operation effectively marks the syntactic scope of the constant local variable represented by the hosited alloca operation, and it allows for better LLVMIR generation with potentially more optimizations.
For example, if we have the following CIR before alloca hoisting:
cir.func @foo() {
cir.scope {
%0 = cir.alloca !s32i : !cir.ptr<!s32i>
use(%0)
}
}
After alloca hoisting:
cir.func @foo() {
%0 = cir.alloca !s32i : !cir.ptr<!s32i>
cir.scope {
%1 = cir.invariant_group %0 : !cir.ptr<!s32i>
use(%1)
}
}
During LLVMIR lowering, load and store operations whose pointer operand comes from cir.invariant_group
are lowered to corresponding LLVM instructions with invariant group metadata attached.
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
ptr | CIR pointer type |
Result | Description |
---|---|
result | CIR pointer 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
Result | Description |
---|---|
result | CIR bool type |
cir.is_fp_class
(::cir::IsFPClassOp)Corresponding to the __builtin_fpclassify
builtin function in clang
Syntax:
operation ::= `cir.is_fp_class` $src `,` $flags `:` functional-type($src, $result) attr-dict
The cir.is_fp_class
operation takes a floating-point value as its first argument and a bitfield of flags as its second argument. The operation returns a boolean value indicating whether the floating-point value satisfies the given flags.
The flags must be a compile time constant and the values are:
Bit # | floating-point class |
---|---|
0 | Signaling NaN |
1 | Quiet NaN |
2 | Negative infinity |
3 | Negative normal |
4 | Negative subnormal |
5 | Negative zero |
6 | Positive zero |
7 | Positive subnormal |
8 | Positive normal |
9 | Positive infinity |
Interfaces: InferTypeOpInterface
Attribute | MLIR Type | Description |
---|---|---|
flags | ::mlir::IntegerAttr | 32-bit signless integer attribute |
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
Result | Description |
---|---|
result | CIR bool type |
cir.std.begin
(::cir::IterBeginOp)Std::begin()
Syntax:
operation ::= `cir.std.begin` `(` $container `:` type($container) `,` $original_fn `)` `->` 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
cir.std.end
(::cir::IterEndOp)Std::end()
Syntax:
operation ::= `cir.std.end` `(` $container `:` type($container) `,` $original_fn `)` `->` 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
cir.llvm.intrinsic
(::cir::LLVMIntrinsicCallOp)Call to llvm intrinsic functions that is not defined in CIR
Syntax:
operation ::= `cir.llvm.intrinsic` $intrinsic_name $arg_ops `:` functional-type($arg_ops, $result) attr-dict
cir.llvm.intrinsic
operation represents a call-like expression which has return type and arguments that maps directly to a llvm intrinsic. It only records intrinsic intrinsic_name
.
Attribute | MLIR Type | Description |
---|---|---|
intrinsic_name | ::mlir::StringAttr | string attribute |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double 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.linker_options
(::cir::LinkerOptionsOp)Options to pass to the linker when the object file is linked
Syntax:
operation ::= `cir.linker_options` $options attr-dict
Pass the given options to the linker when the resulting object file is linked. This is used extensively on Windows to determine the C runtime that the object files should link against.
Examples:
// Link against the MSVC static threaded CRT.
cir.linker_options ["/DEFAULTLIB:", "libcmt"]
// Link against aarch64 compiler-rt builtins
cir.linker_options ["-l", "clang_rt.builtins-aarch64"]
Traits: `HasParent<mlir::ModuleOp>`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>options</code></td><td>::mlir::ArrayAttr</td><td>string array attribute</td></tr>
</table>
### `cir.load` (::cir::LoadOp)
_Load value from memory adddress_
Syntax:
operation ::= cir.load
(deref
$isDeref^)? (volatile
$is_volatile^)? (nontemporal
$is_nontemporal^)? (align
(
$alignment^ )
)? (atomic
(
$mem_order^ )
)? $addr :
qualified(type($addr)) ,
type($result) attr-dict (tbaa
(
$tbaa^ )
)?
`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:
```mlir
// 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 |
is_nontemporal | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
tbaa | ::mlir::Attribute | CIR dialect TBAA base attribute or Describes a special scalar type, the omnipotent char type. or Describes a special scalar type, the vtable pointer type. or Describes a scalar type in TBAA with an identifier. or Describes a struct type in TBAA or |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double 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 | pointer to void type |
pattern | 32-bit signed integer |
len | 64-bit unsigned integer |
Result | Description |
---|---|
result | pointer to void type |
cir.memcpy_inline
(::cir::MemCpyInlineOp)Memory copy with constant length without callingany external function
Syntax:
operation ::= `cir.memcpy_inline` $len `bytes` `from` $src `to` $dst attr-dict
`:` qualified(type($src)) `->` qualified(type($dst))
Given two CIR pointers, src
and dst
, memcpy_inline
will copy len
bytes from the memory pointed by src
to the memory pointed by dst
.
Unlike cir.libc.memcpy
, this Op guarantees that no external functions are called, and length of copied bytes is a constant.
Examples:
// Copying 2 bytes from one array to a record:
cir.memcpy_inline 2 bytes from %arr to %record : !cir.ptr<!arr> -> !cir.ptr<!record>
Attribute | MLIR Type | Description |
---|---|---|
len | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operand | Description |
---|---|
dst | pointer to void type |
src | pointer to void type |
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 record:
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memcpy %2 bytes from %arr to %record : !cir.ptr<!arr> -> !cir.ptr<!record>
Operand | Description |
---|---|
dst | pointer to void type |
src | pointer to void type |
len | fundamental unsigned integer type |
cir.libc.memmove
(::cir::MemMoveOp)Equivalent to libc's memmove
Syntax:
operation ::= `cir.libc.memmove` $len `bytes` `from` $src `to` $dst attr-dict
`:` qualified(type($dst)) `,` type($len)
Given two CIR pointers, src
and dst
, cir.libc.memmove
will copy len
bytes from the memory pointed by src
to the memory pointed by dst
.
similiar to cir.libc.memcpy
but accounts for overlapping memory.
Examples:
// Copying 2 bytes from one array to a record:
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memmove %2 bytes from %arr to %record : !cir.ptr<!void>, !u64i
Operand | Description |
---|---|
dst | pointer to void type |
src | pointer to void type |
len | fundamental unsigned integer type |
cir.memset_inline
(::cir::MemSetInlineOp)Fill a block of memory with constant length without callingany external function
Syntax:
operation ::= `cir.memset_inline` $len `bytes` `from` $dst `set` `to` $val attr-dict
`:` qualified(type($dst)) `,` type($val)
Given the CIR pointer, dst
, cir.memset_inline
will set the first len
bytes of the memory pointed by dst
to the specified val
.
The len
argument must be a constant integer argument specifying the number of bytes to fill.
Examples:
// Set 2 bytes from a record to 0
cir.memset_inline 2 bytes from %record set to %zero : !cir.ptr<!void>, !s32i
Attribute | MLIR Type | Description |
---|---|---|
len | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operand | Description |
---|---|
dst | pointer to void type |
val | 32-bit signed integer |
cir.libc.memset
(::cir::MemSetOp)Equivalent to libc's memset
Syntax:
operation ::= `cir.libc.memset` $len `bytes` `from` $dst `set` `to` $val attr-dict
`:` qualified(type($dst)) `,` type($val) `,` type($len)
Given the CIR pointer, dst
, cir.libc.memset
will set the first len
bytes of the memory pointed by dst
to the specified val
.
Examples:
// Set 2 bytes from a record to 0:
%2 = cir.const #cir.int<2> : !u32i
%3 = cir.const #cir.int<0> : !u32i
%zero = cir.cast(integral, %3 : !s32i), !u8i
cir.libc.memset %2 bytes from %record set to %zero : !cir.ptr<!void>, !s32i, !u64i
Operand | Description |
---|---|
dst | pointer to void type |
val | 32-bit signed integer |
len | fundamental unsigned integer type |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | ::cir::SizeInfoTypeAttr | size info type |
dynamic | ::mlir::UnitAttr | unit attribute |
Operand | Description |
---|---|
ptr | CIR pointer type |
Result | Description |
---|---|
result | fundamental integer type |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
rhs | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | pointer to void type |
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 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 | fundamental integer type |
cir.ptr_mask
(::cir::PtrMaskOp)Masks out bits of the pointer according to a mask
Syntax:
operation ::= `cir.ptr_mask` `(` $ptr `,` $mask `:` type($mask) `)` `:` qualified(type($result)) attr-dict
The cir.ptr_mask
operation takes a pointer and an interger mask
as its argument and return the masked pointer type according to the mask
.
Interfaces: InferTypeOpInterface
Operand | Description |
---|---|
ptr | CIR pointer type |
mask | Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | CIR pointer type |
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 | fundamental integer type |
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` | pointer to void type |
| `type_id` | 32-bit unsigned integer |
### `cir.return_address` (::cir::ReturnAddrOp)
_The return address of the current function, or of one of its callers_
Syntax:
operation ::= cir.return_address
(
$level )
attr-dict
Represents call to builtin function ` __builtin_return_address` in CIR.
This builtin function returns the return address of the current function,
or of one of its callers.
The `level` argument is number of frames to scan up the call stack.
For instance, value of 0 yields the return address of the current function,
value of 1 yields the return address of the caller of the current function,
and so forth.
Examples:
```mlir
%p = return_address(%level) -> !cir.ptr<!void>
Interfaces: InferTypeOpInterface
Operand | Description |
---|---|
level | 32-bit unsigned integer |
Result | Description |
---|---|
result | pointer to void type |
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.
func @foo() -> i32 {
...
cir.return %0 : i32
}
Traits: HasParent<FuncOp, ScopeOp, IfOp, SwitchOp, DoWhileOp, WhileOp, ForOp, CaseOp, TryOp>
, 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | Integer type with arbitrary precision up to a fixed limit |
amt | Integer type with arbitrary precision up to a fixed limit |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit |
cir.roundeven
(::cir::RoundEvenOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.roundeven` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
cir.scope
(::cir::ScopeOp)Represents a C/C++ scope
Syntax:
operation ::= `cir.scope` custom<OmittedTerminatorRegion>($scopeRegion, $cleanupRegion) (`:` 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
}
The blocks can be terminated by cir.yield
, cir.return
or cir.throw
. If cir.scope
yields no value, the cir.yield
can be left out, and will be inserted implicitly.
The scope might also have an associated cleanup
region, providing code that run destruction of automatic variables. Note that in order to lower the cleanup region while keeping C++ semantics, all immediate control-flow breaking operations not under a children scope should jump to this cleanup code.
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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
!record_type = !cir.record<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<!record_type>>, !cir.ptr<!record_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!record_type> -> !cir.ptr<!u32i>
%4 = cir.set_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>, %1 : !s32i) -> !s32i
Attribute | MLIR Type | Description |
---|---|---|
bitfield_info | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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. Second and the thrid operand can be either integer type or vector of integer type. However, they must be either all vector of integer type, or all integer type. If they are vectors, each vector element of the shift target is shifted by the corresponding shift amount in the shift amount vector.
%7 = cir.shift(left, %1 : !u64i, %4 : !s32i) -> !u64i
%8 = cir.shift(left, %2 : !cir.vector<!s32i x 2>, %3 : !cir.vector<!s32i x 2>) -> !cir.vector<!s32i x 2>
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 or !cir.vector of !cir.int |
amount | Integer type with arbitrary precision up to a fixed limit or !cir.vector of !cir.int |
Result | Description |
---|---|
result | Integer type with arbitrary precision up to a fixed limit or !cir.vector of !cir.int |
cir.signbit
(::cir::SignBitOp)Checks the sign of a floating-point number
Syntax:
operation ::= `cir.signbit` $input attr-dict `:` type($input) `->` qualified(type($res))
It returns whether the sign bit (i.e. the highest bit) of the input operand is set.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
input | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
Result | Description |
---|---|
res | CIR bool type |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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` `(` $first `:` type($first) `,` $last `:` type($last) `,` $pattern `:` type($pattern) `,` $original_fn `)` `->` type($result) attr-dict
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
cir.store
(::cir::StoreOp)Store value to memory address
Syntax:
operation ::= `cir.store` (`volatile` $is_volatile^)?
(`nontemporal` $is_nontemporal^)?
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
(`tbaa` `(` $tbaa^ `)`)?
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 |
is_nontemporal | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
tbaa | ::mlir::Attribute | CIR dialect TBAA base attribute or Describes a special scalar type, the omnipotent char type. or Describes a special scalar type, the vtable pointer type. or Describes a scalar type in TBAA with an identifier. or Describes a struct type in TBAA or |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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>(
$body, $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.
The set of cir.case
operations and their enclosing cir.switch
represents the semantics of a C/C++ switch statement. Users can use collectCases(llvm::SmallVector<CaseOp> &cases)
to collect the cir.case
operation in the cir.switch
operation easily.
The cir.case
operations doesn't have to be in the region of cir.switch
directly. However, when all the cir.case
operations lives in the region of cir.switch
directly and there is no other operations except the ending cir.yield
operation in the region of cir.switch
directly, we call the cir.switch
operation is in a simple form. Users can use bool isSimpleForm(llvm::SmallVector<CaseOp> &cases)
member function to detect if the cir.switch
operation is in a simple form. The simple form makes analysis easier to handle the cir.switch
operation and makes the boundary to give up pretty clear.
To make the simple form as common as possible, CIR code generation attaches operations corresponding to the statements that lives between top level cases into the closest cir.case
operation.
For example,
switch(int cond) {
case 4:
a++;
b++;
case 5;
c++;
...
}
The statement b++
is not a sub-statement of the case statement case 4
. But to make the generated cir.switch
a simple form, we will attach the statement b++
into the closest cir.case
operation. So that the generated code will be like:
cir.switch(int cond) {
cir.case(equal, 4) {
a++;
b++;
cir.yield
}
cir.case(equal, 5) {
c++;
cir.yield
}
...
}
For the same reason, we will hoist the case statement as the substatement of another case statement so that they will be in the same level. For example,
switch(int cond) {
case 4:
default;
case 5;
a++;
...
}
will be generated as
cir.switch(int cond) {
cir.case(equal, 4) {
cir.yield
}
cir.case(default) {
cir.yield
}
cir.case(equal, 5) {
a++;
cir.yield
}
...
}
The cir.switch might not be considered "simple" if any of the following is true:
switch(int cond) {
l:
b++;
case 4:
a++;
break;
case 5:
goto l;
...
}
the generated CIR for this non-simple switch would be:
cir.switch(int cond) {
cir.label "l"
b++;
cir.case(4) {
a++;
cir.break
}
cir.case(5) {
goto "l"
}
cir.yield
}
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
, SameVariadicOperandSize
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Operand | Description |
---|---|
condition | Integer type with arbitrary precision up to a fixed limit |
cir.tan
(::cir::TanOp)Libc builtin equivalent ignoring floating point exceptions and errno
Syntax:
operation ::= `cir.tan` $src `:` type($src) attr-dict
Traits: AlwaysSpeculatableImplTrait
, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable
, InferTypeOpInterface
, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operand | Description |
---|---|
src | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
Result | Description |
---|---|
result | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or !cir.vector of !cir.fp |
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 |
calling_conv | ::cir::CallingConvAttr | calling convention |
side_effect | ::cir::SideEffectAttr | allowed side effects of a function |
extra_attrs | ::cir::ExtraFuncAttributesAttr | Represents aggregated attributes for a function |
ast | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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^)?
(`cleanup` $cleanup^)?
$try_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`).
`cleanup`: signal to targets (LLVM for now) that this try/catch, needs
to specially tag their landing pads as needing "cleanup".
Example: TBD
Traits: AutomaticAllocationScope
, NoRegionArguments
, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, RegionBranchOpInterface
Attribute | MLIR Type | Description |
---|---|---|
synthetic | ::mlir::UnitAttr | unit attribute |
cleanup | ::mlir::UnitAttr | unit attribute |
catch_types | ::mlir::ArrayAttr | array attribute |
cir.unary
(::cir::UnaryOp)Unary operations
Syntax:
operation ::= `cir.unary` `(` $kind `,` $input `)`
(`nsw` $no_signed_wrap^)?
`:` 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 | ::cir::UnaryOpKindAttr | unary operation kind |
no_signed_wrap | ::mlir::UnitAttr | unit attribute |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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.vtt.address_point
(::cir::VTTAddrPointOp)Get the VTT address point
Syntax:
operation ::= `cir.vtt.address_point` ($name^)?
($sym_addr^ `:` type($sym_addr))?
`,`
`offset` `=` $offset
`->` qualified(type($addr)) attr-dict
The vtt.address_point
operation retrieves an element from the VTT, which is the address point of a C++ vtable. In virtual inheritance, A set of internal __vptr
for an object are initialized by this operation, which assigns an element from the VTT. The initialization order is as follows:
The complete object constructors and destructors find the VTT, via the mangled name of VTT global variable. They pass the address of the subobject's sub-VTT entry in the VTT as a second parameter when calling the base object constructors and destructors. The base object constructors and destructors use the addresses passed to initialize the primary virtual pointer and virtual pointers that point to the classes which either have virtual bases or override virtual functions with a virtual step.
The first parameter is either the mangled name of VTT global variable or the address of the subobject's sub-VTT entry in the VTT. The second parameter offset
provides a virtual step to adjust to the actual address point of the vtable.
The return type is always a !cir.ptr<!cir.ptr<void>>
.
Example:
cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.base_class_addr(%1 : !cir.ptr<!rec_D> nonnull) [0] -> !cir.ptr<!rec_B>
%4 = cir.vtt.address_point @_ZTT1D, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
cir.call @_ZN1BC2Ev(%3, %4)
Or:
%7 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 1 -> !cir.ptr<!cir.ptr<!void>>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
, NoMemoryEffect (MemoryEffectOpInterface)
, SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
Attribute | MLIR Type | Description |
---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
offset | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |
Result | Description |
---|---|
addr | 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))?
`,`
`address_point` `=` $address_point
`)`
`:` 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.
address_point.index
(vtable index) provides the appropriate vtable within the vtable group (as specified by Itanium ABI), and address_point.offset
(address 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, address_point = <index = 0, offset = 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 |
address_point | ::cir::AddressPointAttr | Address point 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | ::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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | fundamental integer 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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 | fundamental integer type |
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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type 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<ArrayCtor, ArrayDtor, AwaitOp, CallOp, CaseOp, DoWhileOp, ForOp, GlobalOp, IfOp, ScopeOp, SwitchOp, TernaryOp, TryOp, WhileOp>
, 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 record type or CIR exception info or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR complex type |