Operations


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{}

Attributes:

AttributeMLIR TypeDescription
poison::mlir::UnitAttrunit attribute

Operands:

Operand Description
src primitive signed int or !cir.vector of !cir.int

Results:

Result Description
result primitive signed int 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>>, ...

Attributes:

AttributeMLIR TypeDescription
size::mlir::IntegerAttr64-bit signless integer attribute

Results:

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

Attributes:

AttributeMLIR TypeDescription
allocaType::mlir::TypeAttrany type attribute
name::mlir::StringAttrstring attribute
init::mlir::UnitAttrunit attribute
constant::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute whose minimum value is 0
annotations::mlir::ArrayAttrarray attribute
ast::cir::ASTVarDeclInterfaceASTVarDeclInterface instance

Operands:

Operand Description
dynAllocSize primitive int

Results:

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.

Operands:

Operand Description
addr !cir.ptr<!cir.eh_info>

cir.array.dtor (::cir::ArrayDtor)

Destroy array elements with C++ dtors

Syntax:

operation ::= `cir.array.dtor` `(` $addr `:` qualified(type($addr)) `)` $body attr-dict

Destroy each array element using the same C++ destructor. This operation has one region, with one single block. The block has an incoming argument for the current array index to initialize.

Operands:

Operand Description
addr !cir.ptr<!cir.eh_info>

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{}

Attributes:

AttributeMLIR TypeDescription
alignment::mlir::IntegerAttr64-bit signless integer attribute

Operands:

Operand Description
pointer CIR pointer type
offset Integer type with arbitrary precision up to a fixed limit

Results:

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.

Operands:

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

Operands:

Operand Description
ptr1 void*
ptr2 void*

cir.atomic.cmp_xchg (::cir::AtomicCmpXchg)

Atomic compare exchange

Syntax:

operation ::= `cir.atomic.cmp_xchg` `(`
              $ptr `:` qualified(type($ptr)) `,`
              $expected `:` type($expected) `,`
              $desired `:` type($desired) `,`
              `success` `=`  $succ_order `,`
              `failure` `=`  $fail_order
              `)`
              (`weak` $weak^)?
              (`volatile` $is_volatile^)?
              `:` `(` type($old) `,` type($cmp) `)` attr-dict

C/C++ Atomic compare and exchange operation. Implements builtins like __atomic_compare_exchange_n and __atomic_compare_exchange.

Example: %old, %cmp = cir.atomic.cmp_xchg(%ptr : !cir.ptr<!some_struct>, %expected : !u64i, %desired : !u64i, success = seq_cst, failure = seq_cst) weak : (!u64i, !cir.bool)

Interfaces: InferTypeOpInterface

Attributes:

AttributeMLIR TypeDescription
succ_order::cir::MemOrderAttrMemory order according to C++11 memory model
fail_order::cir::MemOrderAttrMemory order according to C++11 memory model
weak::mlir::UnitAttrunit attribute
is_volatile::mlir::UnitAttrunit attribute

Operands:

Operand Description
ptr CIR pointer type
expected Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
desired Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
old Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
cmp CIR bool type

cir.atomic.fetch (::cir::AtomicFetch)

Atomic fetch with unary and binary operations

Syntax:

operation ::= `cir.atomic.fetch` `(`
              $binop `,`
              $ptr `:` type($ptr) `,`
              $val `:` type($val) `,`
              $mem_order `)`
              (`volatile` $is_volatile^)?
              (`fetch_first` $fetch_first^)?
              `:` type($result) attr-dict

Represents __atomic_<binop>_fetch and __atomic_fetch_<binop> builtins, where binop is on of the binary opcodes : add, sub, and, xor, or, nand, max and min.

ptr is an integer or fp pointer, followed by val, which must be an integer or fp (only supported for add and sub). The operation can also be marked volatile.

If fetch_first is present, the operation works like __atomic_fetch_binop and returns the value that had previously been in *ptr, otherwise it returns the final result of the computation (__atomic_binop_fetch).

Example: %res = cir.atomic.fetch(add, %ptr : !cir.ptr<!s32i>, %val : !s32i, seq_cst) : !s32i

Interfaces: InferTypeOpInterface

Attributes:

AttributeMLIR TypeDescription
binop::cir::AtomicFetchKindAttrBinary opcode for atomic fetch operations
mem_order::cir::MemOrderAttrMemory order according to C++11 memory model
is_volatile::mlir::UnitAttrunit attribute
fetch_first::mlir::UnitAttrunit attribute

Operands:

Operand Description
ptr {int,void}*
val CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit

cir.atomic.xchg (::cir::AtomicXchg)

Atomic exchange

Syntax:

operation ::= `cir.atomic.xchg` `(`
              $ptr `:` qualified(type($ptr)) `,`
              $val `:` type($val) `,`
              $mem_order `)`
              (`volatile` $is_volatile^)?
              `:` type($result) attr-dict

Atomic exchange operations. Implements C/C++ builtins such as __atomic_exchangeand __atomic_exchange_n.

Example: %res = cir.atomic.xchg(%ptr : !cir.ptr<!some_struct>, %val : !u64i, seq_cst) : !u64i

Interfaces: InferTypeOpInterface

Attributes:

AttributeMLIR TypeDescription
mem_order::cir::MemOrderAttrMemory order according to C++11 memory model
is_volatile::mlir::UnitAttrunit attribute

Operands:

Operand Description
ptr CIR pointer type
val Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.await (::cir::AwaitOp)

Wraps C++ co_await implicit logic

Syntax:

operation ::= `cir.await` `(` $kind `,`
              `ready` `:` $ready `,`
              `suspend` `:` $suspend `,`
              `resume` `:` $resume `,`
              `)`
              attr-dict

The under the hood effect of using C++ co_await expr roughly translates to:

// co_await expr;

auto &&x = CommonExpr();
if (!x.await_ready()) {
   ...
   x.await_suspend(...);
   ...
}
x.await_resume();

cir.await represents this logic by using 3 regions:

  • ready: covers veto power from x.await_ready()
  • suspend: wraps actual x.await_suspend() logic
  • resume: handles x.await_resume()

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

Attributes:

AttributeMLIR TypeDescription
kind::cir::AwaitKindAttrawait 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<!ty_Derived> nonnull) [0] -> !cir.ptr<!ty_Base>

Attributes:

AttributeMLIR TypeDescription
offset::mlir::IntegerAttrindex attribute
assume_not_null::mlir::UnitAttrunit attribute

Operands:

Operand Description
derived_addr CIR pointer type

Results:

Result Description
base_addr CIR pointer type

cir.binop (::cir::BinOp)

Binary operations (arith and logic)

Syntax:

operation ::= `cir.binop` `(` $kind `,` $lhs `,` $rhs  `)`
              (`nsw` $no_signed_wrap^)?
              (`nuw` $no_unsigned_wrap^)?
              `:` type($lhs) attr-dict

cir.binop performs the binary operation according to the specified opcode kind: [mul, div, rem, add, sub, and, xor, or].

It requires two input operands and has one result, all types should be the same.

%7 = cir.binop(add, %1, %2) : !s32i
%7 = cir.binop(mul, %1, %2) : !u8i

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType, SameTypeOperands

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::BinOpKindAttrbinary operation (arith and logic) kind
no_unsigned_wrap::mlir::UnitAttrunit attribute
no_signed_wrap::mlir::UnitAttrunit attribute

Operands:

Operand Description
lhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
rhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.binop.overflow (::cir::BinOpOverflowOp)

Perform binary integral arithmetic with overflow checking

Syntax:

operation ::= `cir.binop.overflow` `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,`
              `(` type($result) `,` type($overflow) `)`
              attr-dict

cir.binop.overflow performs binary arithmetic operations with overflow checking on integral operands.

The kind argument specifies the kind of arithmetic operation to perform. It can be either add, sub, or mul. The lhs and rhs arguments specify the input operands of the arithmetic operation. The types of lhs and rhs must be the same.

cir.binop.overflow produces two SSA values. result is the result of the arithmetic operation truncated to its specified type. overflow is a boolean value indicating whether overflow happens during the operation.

The exact semantic of this operation is as follows:

  • lhs and rhs are promoted to an imaginary integral type that has infinite precision.
  • The arithmetic operation is performed on the promoted operands.
  • The infinite-precision result is truncated to the type of result. The truncated result is assigned to result.
  • If the truncated result is equal to the un-truncated result, overflow is assigned to false. Otherwise, overflow is assigned to true.

Traits: AlwaysSpeculatableImplTrait, SameTypeOperands

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::BinOpOverflowKindAttrchecked binary arithmetic operation kind

Operands:

Operand Description
lhs Integer type with arbitrary precision up to a fixed limit
rhs Integer type with arbitrary precision up to a fixed limit

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit
overflow CIR bool type

cir.bit.clrsb (::cir::BitClrsbOp)

Get the number of leading redundant sign bits in the input

Syntax:

operation ::= `cir.bit.clrsb` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the number of leading redundant sign bits in the input integer.

The input integer must be a signed integer. The most significant bit of the input integer is the sign bit. The cir.bit.clrsb operation returns the number of redundant sign bits in the input, that is, the number of bits following the most significant bit that are identical to it.

The bit width of the input integer must be either 32 or 64.

Examples:

!s32i = !cir.int<s, 32>

// %0 = 0xDEADBEEF, 0b1101_1110_1010_1101_1011_1110_1110_1111
%0 = cir.const #cir.int<3735928559> : !s32i
// %1 will be 1 because there is 1 bit following the most significant bit
// that is identical to it.
%1 = cir.bit.clrsb(%0 : !s32i) : !s32i

// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
%2 = cir.const #cir.int<1> : !s32i
// %3 will be 30
%3 = cir.bit.clrsb(%2 : !s32i) : !s32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 32-bit signed integer or 64-bit signed integer

Results:

Result Description
result 32-bit signed integer

cir.bit.clz (::cir::BitClzOp)

Get the number of leading 0-bits in the input

Syntax:

operation ::= `cir.bit.clz` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the number of leading 0-bits in the input.

The input integer must be an unsigned integer. The cir.bit.clz operation returns the number of consecutive 0-bits at the most significant bit position in the input.

This operation invokes undefined behavior if the input value is 0.

Example:

!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>

// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 28
%1 = cir.bit.clz(%0 : !u32i) : !s32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer

Results:

Result Description
result 32-bit signed integer

cir.bit.ctz (::cir::BitCtzOp)

Get the number of trailing 0-bits in the input

Syntax:

operation ::= `cir.bit.ctz` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the number of trailing 0-bits in the input.

The input integer must be an unsigned integer. The cir.bit.ctz operation returns the number of consecutive 0-bits at the least significant bit position in the input.

This operation invokes undefined behavior if the input value is 0.

Example:

!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>

// %0 = 0b1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 3
%1 = cir.bit.ctz(%0 : !u32i) : !s32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer

Results:

Result Description
result 32-bit signed integer

cir.bit.ffs (::cir::BitFfsOp)

Get the position of the least significant 1-bit of input

Syntax:

operation ::= `cir.bit.ffs` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the position of the least significant 1-bit of the input.

The input integer must be a signed integer. The cir.bit.ffs operation returns one plus the index of the least significant 1-bit of the input signed integer. As a special case, if the input integer is 0, cir.bit.ffs returns 0.

Example:

!s32i = !cir.int<s, 32>

// %0 = 0x0010_1000
%0 = cir.const #cir.int<40> : !s32i
// #1 will be 4 since the 4th least significant bit is 1.
%1 = cir.bit.ffs(%0 : !s32i) : !s32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 32-bit signed integer or 64-bit signed integer

Results:

Result Description
result 32-bit signed integer

cir.bit.parity (::cir::BitParityOp)

Get the parity of input

Syntax:

operation ::= `cir.bit.parity` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the parity of the input. The parity of an integer is the number of 1-bits in it modulo 2.

The input must be an unsigned integer.

Example:

!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>

// %0 = 0x0110_1000
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 1 since there are 3 1-bits in %0
%1 = cir.bit.parity(%0 : !u32i) : !u32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 32-bit unsigned integer or 64-bit unsigned integer

Results:

Result Description
result 32-bit signed integer

cir.bit.popcount (::cir::BitPopcountOp)

Get the number of 1-bits in input

Syntax:

operation ::= `cir.bit.popcount` `(` $input `:` type($input) `)` `:` type($result) attr-dict

Compute the number of 1-bits in the input.

The input must be an unsigned integer.

Example:

!u32i = !cir.int<u, 32>

// %0 = 0x0110_1000
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 3 since there are 3 1-bits in %0
%1 = cir.bit.popcount(%0 : !u32i) : !u32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer

Results:

Result Description
result 32-bit signed integer

cir.brcond (::cir::BrCondOp)

Conditional branch

Syntax:

operation ::= `cir.brcond` $cond
              $destTrue (`(` $destOperandsTrue^ `:` type($destOperandsTrue) `)`)?
              `,`
              $destFalse (`(` $destOperandsFalse^ `:` type($destOperandsFalse) `)`)?
              attr-dict

The cir.brcond %cond, ^bb0, ^bb1 branches to ‘bb0' block in case %cond (which must be a !cir.bool type) evaluates to true, otherwise it branches to ‘bb1'.

Example:

  ...
    cir.brcond %a, ^bb3, ^bb4
  ^bb3:
    cir.return
  ^bb4:
    cir.yield

Traits: AlwaysSpeculatableImplTrait, AttrSizedOperandSegments, Terminator

Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
cond CIR bool type
destOperandsTrue variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
destOperandsFalse variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Successors:

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{}

Operands:

Operand Description
destOperands variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Successors:

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{}

Operands:

Operand Description
input 16-bit unsigned integer or 32-bit unsigned integer or 64-bit unsigned integer

Results:

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:

  • the output variable index referenced by the input operands.
  • the index of early-clobber operand

Operand attributes is a storage, where each element corresponds to the operand with the same index. The first index relates to the operation result (if any). Note, the operands themselves are stored as VariadicOfVariadic in the next order: output, input and then in/out operands.

Note, when several output operands are present, the result type may be represented as an anon struct type.

Example:

__asm__("foo" : : : );
__asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
__asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
!ty_22anon2E022 = !cir.struct<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
!ty_22anon2E122 = !cir.struct<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>}>
...
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
%1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["y", init]
...
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.load %1 : !cir.ptr<!s32i>, !s32i

cir.asm(x86_att,
  out = [],
  in = [],
  in_out = [],
  {"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects

cir.asm(x86_att,
  out = [],
  in = [],
  in_out = [%2 : !s32i],
  {"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) -> !ty_22anon2E022

cir.asm(x86_att,
  out = [],
  in = [%3 : !s32i],
  in_out = [%2 : !s32i],
  {"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !ty_22anon2E122

Traits: RecursiveMemoryEffects

Attributes:

AttributeMLIR TypeDescription
asm_string::mlir::StringAttrstring attribute
constraints::mlir::StringAttrstring attribute
side_effects::mlir::UnitAttrunit attribute
asm_flavor::cir::AsmFlavorAttrATT or Intel
operand_attrs::mlir::ArrayAttrarray attribute
operands_segments::mlir::DenseI32ArrayAttri32 dense array attribute

Operands:

Operand Description
operands variadic of any type

Results:

Result Description
res Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.call (::cir::CallOp)

Call operation

Direct and indirect calls.

For direct calls, the call operation represents a direct call to a function that is within the same symbol scope as the call. The operands and result types of the call must match the specified function type. The callee is encoded as a aymbol reference attribute named "callee".

For indirect calls, the first mlir::Operation operand is the call target.

Given the way indirect calls are encoded, avoid using mlir::Operation methods to walk the operands for this operation, instead use the methods provided by CIRCallOpInterface.

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

Attributes:

AttributeMLIR TypeDescription
exception::mlir::UnitAttrunit attribute
callee::mlir::FlatSymbolRefAttrflat symbol reference attribute
calling_conv::cir::CallingConvAttrcalling convention
extra_attrs::cir::ExtraFuncAttributesAttrRepresents aggregated attributes for a function
ast::cir::ASTCallExprInterfaceASTCallExprInterface instance

Operands:

Operand Description
arg_ops variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents 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

Attributes:

AttributeMLIR TypeDescription
value::mlir::ArrayAttrarray attribute
kind::cir::CaseOpKindAttrcase 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{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::CastKindAttrcast kind

Operands:

Operand Description
src Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.catch_param (::cir::CatchParamOp)

Represents catch clause formal parameter

Syntax:

operation ::= `cir.catch_param` ($kind^)?
              ($exception_ptr^)?
              (`->` qualified(type($param))^)?
              attr-dict

The cir.catch_param can operate in two modes: within catch regions of cir.try or anywhere else with the begin or end markers. The begin version requires an exception pointer of cir.ptr<!void>.

Example:

// TBD

Attributes:

AttributeMLIR TypeDescription
kind::cir::CatchParamKindAttrDesignate limits for begin/end of catch param handling

Operands:

Operand Description
exception_ptr void*

Results:

Result Description
param Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.ceil (::cir::CeilOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.ceil` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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.

Operands:

Operand Description
begin void*
end void*

cir.cmp (::cir::CmpOp)

Compare values two values and produce a boolean result

Syntax:

operation ::= `cir.cmp` `(` $kind `,` $lhs `,` $rhs  `)` `:` type($lhs) `,` type($result) attr-dict

cir.cmp compares two input operands of the same type and produces a cir.bool result. The kinds of comparison available are: [lt,gt,ge,eq,ne]

%7 = cir.cmp(gt, %1, %2) : i32, !cir.bool

Traits: AlwaysSpeculatableImplTrait, SameTypeOperands

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::CmpOpKindAttrcompare operation kind

Operands:

Operand Description
lhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
rhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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{}

Attributes:

AttributeMLIR TypeDescription
info::cir::CmpThreeWayInfoAttrHolds information about a three-way comparison operation

Operands:

Operand Description
lhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
rhs Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result primitive signed int

cir.complex.binop (::cir::ComplexBinOp)

Binary operations on operands of complex type

Syntax:

operation ::= `cir.complex.binop` $kind $lhs `,` $rhs `range` `(` $range `)` (`promoted` $promoted^)?
              `:` qualified(type($lhs)) attr-dict

The cir.complex.binop operation represents a binary operation on operands of C complex type (e.g. float _Complex). The operation can only represent binary multiplication or division on complex numbers; other binary operations, such as addition and subtraction, are represented by the cir.binop operation.

The operation requires two input operands and has one result. The types of all the operands and the result should be of the same !cir.complex type.

The operation also takes a range attribute that specifies the complex range of the binary operation.

Examples:

%2 = cir.complex.binop add %0, %1 : !cir.complex<!cir.float>
%2 = cir.complex.binop mul %0, %1 : !cir.complex<!cir.float>

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType, SameTypeOperands

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::ComplexBinOpKindAttrcomplex number binary operation kind
range::cir::ComplexRangeKindAttrcomplex multiplication and division implementation
promoted::mlir::UnitAttrunit attribute

Operands:

Operand Description
lhs CIR complex type
rhs CIR complex type

Results:

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{}

Operands:

Operand Description
real CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit
imag CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit

Results:

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{}

Operands:

Operand Description
operand CIR complex type

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit

cir.complex.imag_ptr (::cir::ComplexImagPtrOp)

Derive a pointer to the imaginary part of a complex value

Syntax:

operation ::= `cir.complex.imag_ptr` $operand `:`
              qualified(type($operand)) `->` qualified(type($result)) attr-dict

cir.complex.imag_ptr operation takes a pointer operand that points to a complex value of type !cir.complex and yields a pointer to the imaginary part of the operand.

Example:

%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
operand !cir.complex*

Results:

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{}

Operands:

Operand Description
operand CIR complex type

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or Integer type with arbitrary precision up to a fixed limit

cir.complex.real_ptr (::cir::ComplexRealPtrOp)

Derive a pointer to the real part of a complex value

Syntax:

operation ::= `cir.complex.real_ptr` $operand `:`
              qualified(type($operand)) `->` qualified(type($result)) attr-dict

cir.complex.real_ptr operation takes a pointer operand that points to a complex value of type !cir.complex and yields a pointer to the real part of the operand.

Example:

%1 = cir.complex.real_ptr %0 : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
operand !cir.complex*

Results:

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:

  • When in the cond region of a cir.loop, it continues the loop if true, or exits it if false.
  • When in the 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

Operands:

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{}

Attributes:

AttributeMLIR TypeDescription
value::mlir::TypedAttrTypedAttr instance

Results:

Result Description
res Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.continue (::cir::ContinueOp)

C/C++ continue statement equivalent

Syntax:

operation ::= `cir.continue` attr-dict

The cir.continue operation is used to continue execution to the next iteration of a loop. It is only allowed within cir.loop regions.

Traits: Terminator

cir.copy (::cir::CopyOp)

Copies contents from a CIR pointer to another

Syntax:

operation ::= `cir.copy` $src `to` $dst (`volatile` $is_volatile^)?
              attr-dict `:` qualified(type($dst))
              (`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 struct to another:
  cir.copy %0 to %1 : !cir.ptr<!struct_ty>

Traits: SameTypeOperands

Interfaces: PromotableMemOpInterface

Attributes:

AttributeMLIR TypeDescription
is_volatile::mlir::UnitAttrunit attribute
tbaa::mlir::ArrayAttrarray attribute

Operands:

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{}

Operands:

Operand Description
lhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
rhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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<!ty_B>>, !cir.ptr<!ty_B>
  %3 = cir.derived_class_addr(%2 : !cir.ptr<!ty_B> nonnull) [4] -> !cir.ptr<!ty_X>
  %4 = cir.base_class_addr(%3 : !cir.ptr<!ty_X>) [0] -> !cir.ptr<!ty_A>
  cir.return %4

Attributes:

AttributeMLIR TypeDescription
offset::mlir::IntegerAttrindex attribute
assume_not_null::mlir::UnitAttrunit attribute

Operands:

Operand Description
base_addr CIR pointer type

Results:

Result Description
derived_addr CIR pointer type

cir.do (::cir::DoWhileOp)

C/C++ do-while loop

Syntax:

operation ::= `cir.do` $body `while` $cond attr-dict

Represents a C/C++ do-while loop. Identical to cir.while but the condition is evaluated after the body.

Example:

cir.do {
  cir.break
^bb2:
  cir.yield
} while {
  cir.condition %cond : cir.bool
}

Traits: NoRegionArguments

Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface

cir.dyn_cast (::cir::DynamicCastOp)

Perform dynamic cast on struct pointers

Syntax:

operation ::= `cir.dyn_cast` `(`
              $kind `,` $src `:` type($src)
              (`,` qualified($info)^)?
              (`relative_layout` $relative_layout^)?
              `)`
              `->` qualified(type($result)) attr-dict

The cir.dyn_cast operation models part of the semantics of the dynamic_cast operator in C++. It can be used to perform 3 kinds of casts on struct pointers:

  • Down-cast, which casts a base class pointer to a derived class pointer;
  • Side-cast, which casts a class pointer to a sibling class pointer;
  • Cast-to-complete, which casts a class pointer to a void pointer.

The input of the operation must be a struct pointer. The result of the operation is either a struct pointer or a void pointer.

The parameter kind specifies the semantics of this operation. If its value is ptr, then the operation models dynamic casts on pointers. Otherwise, if its value is ref, the operation models dynamic casts on references. Specifically:

  • When the input pointer is a null pointer value:
    • If kind is ref, the operation will invoke undefined behavior. A sanitizer check will be emitted if sanitizer is on.
    • Otherwise, the operation will return a null pointer value as its result.
  • When the runtime type check fails:
    • If kind is ref, the operation will throw a bad_cast exception.
    • Otherwise, the operation will return a null pointer value as its result.

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.

Attributes:

AttributeMLIR TypeDescription
kind::cir::DynamicCastKindAttrdynamic cast kind
info::cir::DynamicCastInfoAttrABI specific information about a dynamic cast
relative_layout::mlir::UnitAttrunit attribute

Operands:

Operand Description
src !cir.struct*

Results:

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 exception
  • type_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

Attributes:

AttributeMLIR TypeDescription
cleanup::mlir::UnitAttrunit attribute
sym_type_list::mlir::ArrayAttrflat symbol ref array attribute

Results:

Result Description
exception_ptr void*
type_id 32-bit unsigned integer

cir.eh.typeid (::cir::EhTypeIdOp)

Compute exception type id from it's global type symbol

Syntax:

operation ::= `cir.eh.typeid` $type_sym attr-dict

Returns the exception type id for a given global symbol representing a type.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
type_sym::mlir::FlatSymbolRefAttrflat symbol reference attribute

Results:

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Attributes:

AttributeMLIR TypeDescription
prob::mlir::FloatAttr64-bit float attribute

Operands:

Operand Description
val primitive int
expected primitive int

Results:

Result Description
result primitive int

cir.fabs (::cir::FAbsOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.fabs` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.fmax (::cir::FMaxOp)

Libc builtin equivalent ignoring floating-point exceptions and errno.

Syntax:

operation ::= `cir.fmax` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
rhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.fmin (::cir::FMinOp)

Libc builtin equivalent ignoring floating-point exceptions and errno.

Syntax:

operation ::= `cir.fmin` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
rhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
lhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
rhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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.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_struct>
%1 = cir.get_global @d2 : !cir.ptr<!some_struct>
cir.try synthetic cleanup {
  cir.call exception @_ZN7test2_DC1ERKS_(%0, %1) : (!cir.ptr<!some_struct>, !cir.ptr<!some_struct>) -> () cleanup {
    %2 = cir.cast(bitcast, %0 : !cir.ptr<!some_struct>), !cir.ptr<!void>
    cir.free.exception %2
    cir.yield
  }
  ...
}

Operands:

Operand Description
ptr void*

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

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
global_visibility::cir::VisibilityAttrVisibility attribute
function_type::mlir::TypeAttrtype attribute of CIR function type
builtin::mlir::UnitAttrunit attribute
coroutine::mlir::UnitAttrunit attribute
lambda::mlir::UnitAttrunit attribute
no_proto::mlir::UnitAttrunit attribute
dsolocal::mlir::UnitAttrunit attribute
linkage::cir::GlobalLinkageKindAttrLinkage type/kind
calling_conv::cir::CallingConvAttrcalling convention
extra_attrs::cir::ExtraFuncAttributesAttrRepresents aggregated attributes for a function
sym_visibility::mlir::StringAttrstring attribute
comdat::mlir::UnitAttrunit attribute
arg_attrs::mlir::ArrayAttrArray of dictionary attributes
res_attrs::mlir::ArrayAttrArray of dictionary attributes
aliasee::mlir::FlatSymbolRefAttrflat symbol reference attribute
global_ctor::cir::GlobalCtorAttrMarks a function as a global constructor
global_dtor::cir::GlobalDtorAttrMarks a function as a global destructor
annotations::mlir::ArrayAttrarray attribute
ast::mlir::AttributeAST Function attribute

cir.get_bitfield (::cir::GetBitfieldOp)

Get a bitfield

Syntax:

operation ::= `cir.get_bitfield` `(`$bitfield_info `,` $addr attr-dict `:`
              qualified(type($addr)) `)` `->` type($result)

The cir.get_bitfield operation provides a load-like access to a bit field of a record.

It expects a name if a bit field, a pointer to a storage in the base record, a type of the storage, a name of the bitfield, a size the bit field, an offset of the bit field and a sign.

A unit attribute volatile can be used to indicate a volatile load of the bitfield.

Example: Suppose we have a struct with multiple bitfields stored in different storages. The cir.get_bitfield operation gets the value of the bitfield

typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
} S;

int load_bitfield(S& s) {
  return s.d;
}
// 'd' is in the storage with the index 1
!struct_type = !cir.struct<struct "S" {!cir.int<u, 32>, !cir.int<u, 32>, !cir.int<u, 16>} #cir.record.decl.ast>
#bfi_d = #cir.bitfield_info<name = "d", storage_type = !u32i, size = 2, offset = 17, is_signed = true>

%2 = cir.load %0 : !cir.ptr<!cir.ptr<!struct_type>>, !cir.ptr<!struct_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!struct_type> -> !cir.ptr<!u32i>
%4 = cir.get_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>) -> !s32i

Attributes:

AttributeMLIR TypeDescription
bitfield_info::cir::BitfieldInfoAttrRepresents a bit field info
is_volatile::mlir::UnitAttrunit attribute

Operands:

Operand Description
addr CIR pointer type

Results:

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{}

Attributes:

AttributeMLIR TypeDescription
name::mlir::FlatSymbolRefAttrflat symbol reference attribute
tls::mlir::UnitAttrunit attribute

Results:

Result Description
addr CIR pointer type

cir.get_member (::cir::GetMemberOp)

Get the address of a member of a struct

Syntax:

operation ::= `cir.get_member` $addr `[` $index_attr `]` attr-dict
              `:` qualified(type($addr)) `->` qualified(type($result))

The cir.get_member operation gets the address of a particular named member from the input record.

It expects a pointer to the base record as well as the name of the member and its field index.

Example:

// Suppose we have a struct with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!struct_ty = !cir.struct<"struct.Bar" {!s32i, !s8i}>

// Get the address of the member at index 1.
%1 = cir.get_member %0[1] {name = "i"} : (!cir.ptr<!struct_ty>) -> !cir.ptr<!s8i>

Attributes:

AttributeMLIR TypeDescription
name::mlir::StringAttrstring attribute
index_attr::mlir::IntegerAttrindex attribute

Operands:

Operand Description
addr CIR pointer type

Results:

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:

  • The return type of the method must match the return type of the callee.
  • The first parameter of the callee must have type !cir.ptr<!cir.void>.
  • Types of other parameters of the callee must match the parameters of the method.

Operands:

Operand Description
method CIR type that represents C++ pointer-to-member-function type
object !cir.struct*

Results:

Result Description
callee !cir.ptr<!cir.func>
adjusted_this void*

cir.get_runtime_member (::cir::GetRuntimeMemberOp)

Get the address of a member of a struct

Syntax:

operation ::= `cir.get_runtime_member` $addr `[` $member `:` qualified(type($member)) `]` attr-dict
              `:` qualified(type($addr)) `->` qualified(type($result))

The cir.get_runtime_member operation gets the address of a member from the input record. The target member is given by a value of type !cir.data_member (i.e. a pointer-to-data-member value).

This operation differs from cir.get_member in when the target member can be determined. For the cir.get_member operation, the target member is specified as a constant index so the member it returns access to is known when the operation is constructed. For the cir.get_runtime_member operation, the target member is given through a pointer-to-data-member value which is unknown until the program being compiled is executed. In other words, cir.get_member represents a normal member access through the . operator in C/C++:

struct Foo { int x; };
Foo f;
(void)f.x;  // cir.get_member

And cir.get_runtime_member represents a member access through the .* or the ->* operator in C++:

struct Foo { int x; }
Foo f;
Foo *p;
int Foo::*member;

(void)f.*member;   // cir.get_runtime_member
(void)f->*member;  // cir.get_runtime_member

This operation expects a pointer to the base record as well as the pointer to the target member.

Operands:

Operand Description
addr !cir.struct*
member CIR type that represents pointer-to-data-member type in C++

Results:

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

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
global_visibility::cir::VisibilityAttrVisibility attribute
sym_visibility::mlir::StringAttrstring attribute
sym_type::mlir::TypeAttrany type attribute
linkage::cir::GlobalLinkageKindAttrLinkage type/kind
addr_space::cir::AddressSpaceAttrAddress space attribute for pointer types
tls_model::cir::TLS_ModelAttrTLS model
initial_value::mlir::Attributeany attribute
comdat::mlir::UnitAttrunit attribute
constant::mlir::UnitAttrunit attribute
dsolocal::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute
ast::cir::ASTVarDeclInterfaceASTVarDeclInterface instance
section::mlir::StringAttrstring attribute
annotations::mlir::ArrayAttrarray 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 gotos 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

Attributes:

AttributeMLIR TypeDescription
label::mlir::StringAttrstring 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

Operands:

Operand Description
condition CIR bool type

cir.is_constant (::cir::IsConstantOp)

Syntax:

operation ::= `cir.is_constant` `(` $val `:` type($val) `)` `:` type($result) attr-dict

Returns true if the argument is known to be a compile-time constant otherwise returns ‘false'.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
val Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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

Attributes:

AttributeMLIR TypeDescription
flags::mlir::IntegerAttr32-bit signless integer attribute

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR bool type

cir.iterator_begin (::cir::IterBeginOp)

Returns an iterator to the first element of a container

Syntax:

operation ::= `cir.iterator_begin` `(`
              $original_fn `,` $container `:` type($container)
              `)` `->` type($result) attr-dict

Attributes:

AttributeMLIR TypeDescription
original_fn::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

Operand Description
container Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.iterator_end (::cir::IterEndOp)

Returns an iterator to the element following the last element of a container

Syntax:

operation ::= `cir.iterator_end` `(`
              $original_fn `,` $container `:` type($container)
              `)` `->` type($result) attr-dict

Attributes:

AttributeMLIR TypeDescription
original_fn::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

Operand Description
container Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents 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.

Attributes:

AttributeMLIR TypeDescription
intrinsic_name::mlir::StringAttrstring attribute

Operands:

Operand Description
arg_ops variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.llrint (::cir::LLrintOp)

Builtin function that takes a floating-point value as input and produces an integral value as output.

Syntax:

operation ::= `cir.llrint` $src `:` type($src) `->` type($result) attr-dict

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

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

Attributes:

AttributeMLIR TypeDescription
label::mlir::StringAttrstring attribute

cir.load (::cir::LoadOp)

Load value from memory adddress

Syntax:

operation ::= `cir.load` (`deref` $isDeref^)?
              (`volatile` $is_volatile^)?
              (`align` `(` $alignment^ `)`)?
              (`atomic` `(` $mem_order^ `)`)?
              $addr `:` qualified(type($addr)) `,` type($result) attr-dict
              (`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:


// 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

Attributes:

AttributeMLIR TypeDescription
isDeref::mlir::UnitAttrunit attribute
is_volatile::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute
mem_order::cir::MemOrderAttrMemory order according to C++11 memory model
tbaa::mlir::ArrayAttrarray attribute

Operands:

Operand Description
addr CIR pointer type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.log10 (::cir::Log10Op)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.log10` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

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

Operands:

Operand Description
src void*
pattern 32-bit signed integer
len 64-bit unsigned integer

Results:

Result Description
result void*

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 struct:
  cir.memcpy_inline 2 bytes from %arr to %struct : !cir.ptr<!arr> -> !cir.ptr<!struct>

Attributes:

AttributeMLIR TypeDescription
len::mlir::IntegerAttr64-bit signless integer attribute

Operands:

Operand Description
dst void*
src void*

cir.libc.memcpy (::cir::MemCpyOp)

Equivalent to libc's memcpy

Syntax:

operation ::= `cir.libc.memcpy` $len `bytes` `from` $src `to` $dst attr-dict
              `:` type($len) `` `,` qualified(type($src)) `->` qualified(type($dst))

Given two CIR pointers, src and dst, cir.libc.memcpy will copy len bytes from the memory pointed by src to the memory pointed by dst.

While cir.copy is meant to be used for implicit copies in the code where the length of the copy is known, cir.memcpy copies only from and to void pointers, requiring the copy length to be passed as an argument.

Examples:

  // Copying 2 bytes from one array to a struct:
  %2 = cir.const #cir.int<2> : !u32i
  cir.libc.memcpy %2 bytes from %arr to %struct : !cir.ptr<!arr> -> !cir.ptr<!struct>

Operands:

Operand Description
dst void*
src void*
len primitive unsigned int

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 struct:
  %2 = cir.const #cir.int<2> : !u32i
  cir.libc.memmove %2 bytes from %arr to %struct : !cir.ptr<!void>, !u64i

Operands:

Operand Description
dst void*
src void*
len primitive unsigned int

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 struct to 0
  cir.memset_inline 2 bytes from %struct set to %zero : !cir.ptr<!void>, !s32i

Attributes:

AttributeMLIR TypeDescription
len::mlir::IntegerAttr64-bit signless integer attribute

Operands:

Operand Description
dst void*
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 struct 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 %struct set to %zero : !cir.ptr<!void>, !s32i, !u64i

Operands:

Operand Description
dst void*
val 32-bit signed integer
len primitive unsigned int

cir.nearbyint (::cir::NearbyintOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.nearbyint` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::SizeInfoTypeAttrsize info type
dynamic::mlir::UnitAttrunit attribute

Operands:

Operand Description
ptr CIR pointer type

Results:

Result Description
result primitive int

cir.pow (::cir::PowOp)

Libc builtin equivalent ignoring floating-point exceptions and errno.

Syntax:

operation ::= `cir.pow` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
rhs CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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:

  1. The $locality is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local keep in cache.
  2. The $isWrite is the specifier determining if the prefetch is prepaired for a ‘read' or ‘write'. If $isWrite doesn't specified it means that prefetch is prepared for ‘read'.

Attributes:

AttributeMLIR TypeDescription
locality::mlir::IntegerAttr32-bit signless integer attribute whose minimum value is 0 whose maximum value is 3
isWrite::mlir::UnitAttrunit attribute

Operands:

Operand Description
addr void*

cir.ptr_diff (::cir::PtrDiffOp)

Pointer subtraction arithmetic

Syntax:

operation ::= `cir.ptr_diff` `(` $lhs `,` $rhs  `)` `:` qualified(type($lhs)) `->` qualified(type($result)) attr-dict

cir.ptr_diff performs a subtraction between two pointer types with the same element type and produces a 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{}

Operands:

Operand Description
lhs CIR pointer type
rhs CIR pointer type

Results:

Result Description
result primitive int

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

Operands:

Operand Description
ptr CIR pointer type
mask Integer type with arbitrary precision up to a fixed limit

Results:

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{}

Operands:

Operand Description
base CIR pointer type
stride primitive int

Results:

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:

  • As the terminator of a CatchUnwind region of cir.try, where it does not receive any arguments (implied from the cir.try scope), or
  • The terminator of a regular basic block without an enclosing cir.try operation, where it requires an exception_ptr and a type_id.

The rethrow attribute is used to denote rethrowing behavior for the resume operation (versus default terminaton).


Traits: `AttrSizedOperandSegments`, `ReturnLike`, `Terminator`

Interfaces: `RegionBranchTerminatorOpInterface`

#### Attributes:

<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>rethrow</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>

#### Operands:

| Operand | Description |
| :-----: | ----------- |
| `exception_ptr` | void*
| `type_id` | 32-bit unsigned integer

### `cir.return_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

Operands:

Operand Description
level 32-bit unsigned integer

Results:

Result Description
result void*

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>, Terminator

Operands:

Operand Description
input variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.rint (::cir::RintOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.rint` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Attributes:

AttributeMLIR TypeDescription
left::mlir::UnitAttrunit attribute

Operands:

Operand Description
src primitive int
amt primitive int

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit

cir.round (::cir::RoundOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

operation ::= `cir.round` $src `:` type($src) attr-dict

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.scope (::cir::ScopeOp)

Represents a C/C++ scope

Syntax:

operation ::= `cir.scope` custom<OmittedTerminatorRegion>($scopeRegion) (`:` type($results)^)? attr-dict

cir.scope contains one region and defines a strict "scope" for all new values produced within its blocks.

The region can contain an arbitrary number of blocks but usually defaults to one and can optionally return a value (useful for representing values coming out of C++ full-expressions) via cir.yield:

%rvalue = cir.scope {
  ...
  cir.yield %value
}

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.

Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait

Interfaces: ConditionallySpeculatable, RegionBranchOpInterface

Results:

Result Description
results Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.select (::cir::SelectOp)

Yield one of two values based on a boolean value

Syntax:

operation ::= `cir.select` `if` $condition `then` $true_value `else` $false_value
              `:` `(`
              qualified(type($condition)) `,`
              qualified(type($true_value)) `,`
              qualified(type($false_value))
              `)` `->` qualified(type($result)) attr-dict

The cir.select operation takes three operands. The first operand condition is a boolean value of type !cir.bool. The second and the third operand can be of any CIR types, but their types must be the same. If the first operand is true, the operation yields its second operand. Otherwise, the operation yields its third operand.

Example:

%0 = cir.const #cir.bool<true> : !cir.bool
%1 = cir.const #cir.int<42> : !s32i
%2 = cir.const #cir.int<72> : !s32i
%3 = cir.select if %0 then %1 else %2 : (!cir.bool, !s32i, !s32i) -> !s32i

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
condition CIR bool type
true_value Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
false_value Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.set_bitfield (::cir::SetBitfieldOp)

Set a bitfield

Syntax:

operation ::= `cir.set_bitfield` `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,`
              $src`:`type($src) `)`  attr-dict `->` type($result)

The cir.set_bitfield operation provides a store-like access to a bit field of a record.

It expects an address of a storage where to store, a type of the storage, a value being stored, a name of a bit field, a pointer to the storage in the base record, a size of the storage, a size the bit field, an offset of the bit field and a sign. Returns a value being stored.

A unit attribute volatile can be used to indicate a volatile load of the bitfield.

Example. Suppose we have a struct with multiple bitfields stored in different storages. The cir.set_bitfield operation sets the value of the bitfield.

typedef struct {
  int a : 4;
  int b : 27;
  int c : 17;
  int d : 2;
  int e : 15;
} S;

void store_bitfield(S& s) {
  s.d = 3;
}
// 'd' is in the storage with the index 1
!struct_type = !cir.struct<struct "S" {!cir.int<u, 32>, !cir.int<u, 32>, !cir.int<u, 16>} #cir.record.decl.ast>
#bfi_d = #cir.bitfield_info<name = "d", storage_type = !u32i, size = 2, offset = 17, is_signed = true>

%1 = cir.const #cir.int<3> : !s32i
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!struct_type>>, !cir.ptr<!struct_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!struct_type> -> !cir.ptr<!u32i>
%4 = cir.set_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>, %1 : !s32i) -> !s32i

Attributes:

AttributeMLIR TypeDescription
bitfield_info::cir::BitfieldInfoAttrRepresents a bit field info
is_volatile::mlir::UnitAttrunit attribute

Operands:

Operand Description
addr CIR pointer type
src Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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{}

Attributes:

AttributeMLIR TypeDescription
isShiftleft::mlir::UnitAttrunit attribute

Operands:

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

Results:

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 a non-zero value (true) if the number is negative and zero (false) if the number is positive or zero.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
input CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
res 32-bit signed integer

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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>

Operands:

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>

Results:

Result Description
result CIR pointer type

cir.std.find (::cir::StdFindOp)

Std:find()

Syntax:

operation ::= `cir.std.find` `(`
              $original_fn
              `,` $first `:` type($first)
              `,` $last `:` type($last)
              `,` $pattern `:` type($pattern)
              `)` `->` type($result) attr-dict

Search for pattern in data range from first to last. This currently maps to only one form of std::find. The original_fn operand tracks the mangled named that can be used when lowering to a cir.call.

Example:

...
%result = cir.std.find(@original_fn,
                       %first : !T, %last : !T, %pattern : !P) -> !T

Traits: SameFirstSecondOperandAndResultType

Attributes:

AttributeMLIR TypeDescription
original_fn::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

Operand Description
first Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
last Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
pattern Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.store (::cir::StoreOp)

Store value to memory address

Syntax:

operation ::= `cir.store` (`volatile` $is_volatile^)?
              (`align` `(` $alignment^ `)`)?
              (`atomic` `(` $mem_order^ `)`)?
              $value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
              (`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

Attributes:

AttributeMLIR TypeDescription
is_volatile::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute
mem_order::cir::MemOrderAttrMemory order according to C++11 memory model
tbaa::mlir::ArrayAttrarray attribute

Operands:

Operand Description
value Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
addr CIR pointer type

cir.switch.flat (::cir::SwitchFlatOp)

Syntax:

operation ::= `cir.switch.flat` $condition `:` type($condition) `,`
              $defaultDestination (`(` $defaultOperands^ `:` type($defaultOperands) `)`)?
              custom<SwitchFlatOpCases>(ref(type($condition)), $case_values, $caseDestinations,
              $caseOperands, type($caseOperands))
              attr-dict

The cir.switch.flat operation is a region-less and simplified version of the cir.switch. It's representation is closer to LLVM IR dialect than the C/C++ language feature.

Traits: AttrSizedOperandSegments, Terminator

Attributes:

AttributeMLIR TypeDescription
case_values::mlir::ArrayAttrarray attribute
case_operand_segments::mlir::DenseI32ArrayAttri32 dense array attribute

Operands:

Operand Description
condition Integer type with arbitrary precision up to a fixed limit
defaultOperands variadic of any type
caseOperands variadic of any type

Successors:

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:

  • There are case statements of the switch statement lives in other scopes other than the top level compound statement scope. Note that a case statement itself doesn't form a scope.
  • The sub-statement of the switch statement is not a compound statement.
  • There are codes before the first case statement. For example,
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

Operands:

Operand Description
condition Integer type with arbitrary precision up to a fixed limit

cir.ternary (::cir::TernaryOp)

The cond ? a : b C/C++ ternary operation

Syntax:

operation ::= `cir.ternary` `(` $cond `,`
              `true` $trueRegion `,`
              `false` $falseRegion
              `)` `:` functional-type(operands, results) attr-dict

The cir.ternary operation represents C/C++ ternary, much like a select operation. First argument is a cir.bool condition to evaluate, followed by two regions to execute (true or false). This is different from cir.if since each region is one block sized and the cir.yield closing the block scope should have one argument.

Example:

// x = cond ? a : b;

%x = cir.ternary (%cond, true_region {
  ...
  cir.yield %a : i32
}, false_region {
  ...
  cir.yield %b : i32
}) -> i32

Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait

Interfaces: ConditionallySpeculatable, RegionBranchOpInterface

Operands:

Operand Description
cond CIR bool type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.throw (::cir::ThrowOp)

(Re)Throws an exception

Syntax:

operation ::= `cir.throw` ($exception_ptr^ `:` type($exception_ptr))?
              (`,` $type_info^)?
              (`,` $dtor^)?
              attr-dict

Very similar to __cxa_throw:

void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
                 void (*dest) (void *));

The absense of arguments for cir.throw means it rethrows.

For the no-rethrow version, it must have at least two operands, the RTTI information, a pointer to the exception object (likely allocated via cir.cxa.allocate_exception) and finally an optional dtor, which might run as part of this operation.

  // if (b == 0)
  //   throw "Division by zero condition!";
  cir.if %10 {
    %11 = cir.alloc_exception 8 -> !cir.ptr<!void>
    ...
    cir.store %13, %11 : // Store string addr for "Division by zero condition!"
    cir.throw %11 : !cir.ptr<!cir.ptr<!u8i>>, @"typeinfo for char const*"

Attributes:

AttributeMLIR TypeDescription
type_info::mlir::FlatSymbolRefAttrflat symbol reference attribute
dtor::mlir::FlatSymbolRefAttrflat symbol reference attribute

Operands:

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{}

Operands:

Operand Description
src CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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

Attributes:

AttributeMLIR TypeDescription
callee::mlir::FlatSymbolRefAttrflat symbol reference attribute
calling_conv::cir::CallingConvAttrcalling convention
extra_attrs::cir::ExtraFuncAttributesAttrRepresents aggregated attributes for a function
ast::cir::ASTCallExprInterfaceASTCallExprInterface instance

Operands:

Operand Description
contOperands variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
landingPadOperands variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type
arg_ops variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Successors:

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

Attributes:

AttributeMLIR TypeDescription
synthetic::mlir::UnitAttrunit attribute
cleanup::mlir::UnitAttrunit attribute
catch_types::mlir::ArrayAttrarray attribute

cir.unary (::cir::UnaryOp)

Unary operations

Syntax:

operation ::= `cir.unary` `(` $kind `,` $input `)` `:` type($input) `,` type($result) attr-dict

cir.unary performs the unary operation according to the specified opcode kind: [inc, dec, plus, minus, not].

It requires one input operand and has one result, both types should be the same.

%7 = cir.unary(inc, %1) : i32 -> i32
%8 = cir.unary(dec, %2) : i32 -> i32

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::UnaryOpKindAttrunary operation kind

Operands:

Operand Description
input Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents 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)

Operands:

Operand Description
arg_list CIR pointer type

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.va.copy (::cir::VACopyOp)

Copies a variable argument list

Syntax:

operation ::= `cir.va.copy` $src_list `to` $dst_list attr-dict `:` type(operands)

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)

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)

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<!ty_D> nonnull) [0] -> !cir.ptr<!ty_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{}

Attributes:

AttributeMLIR TypeDescription
name::mlir::FlatSymbolRefAttrflat symbol reference attribute
offset::mlir::IntegerAttr32-bit signless integer attribute

Operands:

Operand Description
sym_addr Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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))?
              `,`
              `vtable_index` `=` $vtable_index `,`
              `address_point_index` `=` $address_point_index
              `)`
              `:` qualified(type($addr)) attr-dict

The vtable.address_point operation retrieves the "effective" address (address point) of a C++ virtual table. An object internal __vptr gets initializated on top of the value returned by this operation.

vtable_index provides the appropriate vtable within the vtable group (as specified by Itanium ABI), and addr_point_index the actual address point within that vtable.

The return type is always a !cir.ptr<!cir.ptr<() -> i32>>.

Example:

cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<() -> i32>>

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
name::mlir::FlatSymbolRefAttrflat symbol reference attribute
vtable_index::mlir::IntegerAttr32-bit signless integer attribute
address_point_index::mlir::IntegerAttr32-bit signless integer attribute

Operands:

Operand Description
sym_addr Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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{}

Attributes:

AttributeMLIR TypeDescription
kind::cir::CmpOpKindAttrcompare operation kind

Operands:

Operand Description
lhs CIR vector type
rhs CIR vector type

Results:

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{}

Operands:

Operand Description
elements variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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{}

Operands:

Operand Description
vec CIR vector type
index primitive int

Results:

Result Description
result Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

cir.vec.insert (::cir::VecInsertOp)

Insert one element into a vector object

Syntax:

operation ::= `cir.vec.insert` $value `,` $vec `[` $index `:` type($index) `]` attr-dict `:`
              qualified(type($vec))

The cir.vec.insert operation replaces the element of the given vector at the given index with the given value. The new vector with the inserted element is returned.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
vec CIR vector type
value any type
index primitive int

Results:

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{}

Operands:

Operand Description
vec CIR vector type
indices !cir.vector of !cir.int

Results:

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{}

Attributes:

AttributeMLIR TypeDescription
indices::mlir::ArrayAttrarray attribute

Operands:

Operand Description
vec1 CIR vector type
vec2 CIR vector type

Results:

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{}

Operands:

Operand Description
value Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type

Results:

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{}

Operands:

Operand Description
cond !cir.vector of !cir.int
vec1 CIR vector type
vec2 CIR vector type

Results:

Result Description
result CIR vector type

cir.while (::cir::WhileOp)

C/C++ while loop

Syntax:

operation ::= `cir.while` $cond `do` $body attr-dict

Represents a C/C++ while loop. It consists of two regions:

  • cond: single block region with the loop's condition. Should be terminated with a cir.condition operation.
  • body: contains the loop body and an arbitrary number of blocks.

Example:

cir.while {
  cir.break
^bb2:
  cir.yield
} do {
  cir.condition %cond : cir.bool
}

Traits: NoRegionArguments

Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface

cir.yield (::cir::YieldOp)

Represents the default branching behaviour of a region

Syntax:

operation ::= `cir.yield` ($args^ `:` type($args))? attr-dict

The cir.yield operation terminates regions on different CIR operations, and it is used to represent the default branching behaviour of a region. Said branching behaviour is determinted by the parent operation. For example, a yield in a switch-case region implies a fallthrough, while a yield in a cir.if region implies a branch to the exit block, and so on.

In some cases, it might yield an SSA value and the semantics of how the values are yielded is defined by the parent operation. For example, a cir.ternary operation yields a value from one of its regions.

As a general rule, cir.yield must be explicitly used whenever a region has more than one block and no terminator, or within cir.switch regions not cir.return terminated.

Examples:

cir.if %4 {
  ...
  cir.yield
}

cir.switch (%5) [
  case (equal, 3) {
    ...
    cir.yield
  }, ...
]

cir.scope {
  ...
  cir.yield
}

%x = cir.scope {
  ...
  cir.yield %val
}

%y = cir.ternary {
  ...
  cir.yield %val : i32
} : i32

Traits: HasParent<IfOp, ScopeOp, SwitchOp, WhileOp, ForOp, AwaitOp, TernaryOp, GlobalOp, DoWhileOp, TryOp, ArrayCtor, ArrayDtor, CallOp, CaseOp>, ReturnLike, Terminator

Interfaces: RegionBranchTerminatorOpInterface

Operands:

Operand Description
args variadic of Integer type with arbitrary precision up to a fixed limit or CIR pointer type or CIR type that represents pointer-to-data-member type in C++ or CIR type that represents C++ pointer-to-member-function type or CIR bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR type that represents IEEEquad 128-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR type that represents IEEE-754 binary16 format or CIR type that represents or CIR complex type