Operations


cir.alloc_exception (cir::AllocException)

Defines a scope-local variable

Syntax:

operation ::= `cir.alloc_exception` `(` $allocType `)` `->` 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(!cir.ptr<!u8i>) -> <!cir.ptr<!u8i>>
    ... // store exception content into %11
    cir.throw(%11 : !cir.ptr<!cir.ptr<!u8i>>, ...

Attributes:

AttributeMLIR TypeDescription
allocType::mlir::TypeAttrany type 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^)?
              `]`
              (`ast` $ast^)? attr-dict

The cir.alloca operation defines a scope-local variable.

The presence init attribute indicates that the local variable represented by this alloca was originally initialized in C/C++ source code. In such cases, the first use contains the initialization (a cir.store, a cir.call to a ctor, etc).

The dynAllocSize specifies the size to dynamically allocate on the stack and ignores the allocation size based on the original type. This is useful when handling VLAs and is omitted when declaring regular local variables.

The result type is a pointer to the input's type.

Example:

// int count = 3;
%0 = cir.alloca i32, !cir.ptr<i32>, ["count", init] {alignment = 4 : i64}

// int *ptr;
%1 = cir.alloca !cir.ptr<i32>, !cir.ptr<!cir.ptr<i32>>, ["ptr"] {alignment = 8 : i64}
...

Attributes:

AttributeMLIR TypeDescription
allocaType::mlir::TypeAttrany type attribute
name::mlir::StringAttrstring attribute
init::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute whose minimum value is 0
ast::mlir::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.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::mlir::cir::MemOrderAttrMemory order according to C++11 memory model
fail_order::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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::mlir::cir::AtomicFetchKindAttrBinary opcode for atomic fetch operations
mem_order::mlir::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 extended-precision float type 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 extended-precision float type or Integer type with arbitrary precision up to a fixed limit

cir.atomic.xchg (cir::AtomicXchg)

Atomic exchange

Syntax:

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

Atomic exchange operations. Implements C/C++ builtins such as __atomic_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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 3 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.
  • 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::mlir::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))
              `)` `->` qualified(type($base_addr)) attr-dict

The cir.base_class_addr operaration gets the address of a particular base class given a derived class pointer.

Example:

TBD

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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::mlir::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, SameVariadicOperandSize, 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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.

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.call (cir::CallOp)

Call operation

Direct and indirect calls.

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

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

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

Example:

// Direct call
%2 = cir.call @my_add(%0, %1) : (f32, f32) -> f32
 ...
// Indirect call
%20 = cir.call %18(%17)

Interfaces: CIRCallOpInterface, CallOpInterface, SymbolUserOpInterface

Attributes:

AttributeMLIR TypeDescription
callee::mlir::FlatSymbolRefAttrflat symbol reference attribute
ast::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
«unnamed» 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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

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)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.catch (cir::CatchOp)

Catch operation

Syntax:

operation ::= `cir.catch` `(`
              $exception_info `:` type($exception_info) `,`
              custom<CatchOp>($regions, $catchers)
              `)` attr-dict

Traits: NoRegionArguments, RecursivelySpeculatableImplTrait, SameVariadicOperandSize

Interfaces: ConditionallySpeculatable, RegionBranchOpInterface

Attributes:

AttributeMLIR TypeDescription
catchers::mlir::ArrayAttrarray attribute

Operands:

Operand Description
exception_info 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.catch_param (cir::CatchParamOp)

Materialize the catch clause formal parameter

Syntax:

operation ::= `cir.catch_param` `(` $exception_info `)` `->` qualified(type($param)) attr-dict

The cir.catch_param binds to a the C/C++ catch clause param and allow it to be materialized. This operantion grabs the param by looking into a exception info !cir.eh_info argument.

Example:

// TBD

Operands:

Operand Description
exception_info !cir.eh_info*

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 extended-precision float 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 extended-precision float type

cir.cmp (cir::CmpOp)

Compare values two values and produce a boolean result

Syntax:

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

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

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

Traits: AlwaysSpeculatableImplTrait, SameTypeOperands

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

AttributeMLIR TypeDescription
kind::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
result primitive signed int

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 attr-dict `:` qualified(type($dst))

Given two CIR pointers, src and dst, cir.copy will copy the memory pointed by src to the memory pointed by dst.

The amount of bytes copied is inferred from the pointee type. Naturally, the pointee type of both src and dst must match and must implement the DataLayoutTypeInterface.

Examples:

  // Copying contents from one struct to another:
  cir.copy %0 to %1 : !cir.ptr<!struct_ty>

Traits: SameTypeOperands

Operands:

Operand Description
dst CIR pointer type
src CIR pointer type

cir.cos (cir::CosOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.do (cir::DoWhileOp)

C/C++ do-while loop

Syntax:

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

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

Example:

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

Traits: NoRegionArguments

Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface

cir.dyn_cast (cir::DynamicCastOp)

Perform dynamic cast on struct pointers

Syntax:

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

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

  • 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::mlir::cir::DynamicCastKindAttrdynamic cast kind
info::mlir::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.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 extended-precision float 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 extended-precision float type

cir.exp (cir::ExpOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.expect (cir::ExpectOp)

Compute whether expression is likely to evaluate to a specified value

Syntax:

operation ::= `cir.expect` `(` $val`,` $expected (`,` $prob^)? `)` `:` type($val) attr-dict

Provides __builtin_expect functionality in Clang IR.

If $prob is not specified, then behaviour is same as __builtin_expect. If specified, then behaviour is same as __builtin_expect_with_probability, where probability = $prob.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.floor (cir::FloorOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.for (cir::ForOp)

C/C++ for loop counterpart

Syntax:

operation ::= `cir.for` `:` `cond` $cond
              `body` $body
              `step` $step
              attr-dict

Represents a C/C++ for loop. It consists of three regions:

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

Example:

cir.for cond {
  cir.condition(%val)
} body {
  cir.break
^bb2:
  cir.yield
} step {
  cir.yield
}

Traits: NoRegionArguments

Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface

cir.func (cir::FuncOp)

Declare or define a function

Similar to mlir::FuncOp built-in:

Operations within the function cannot implicitly capture values defined outside of the function, i.e. Functions are IsolatedFromAbove. All external references must use function arguments or attributes that establish a symbolic connection (e.g. symbols referenced by name via a string attribute like SymbolRefAttr). An external function declaration (used when referring to a function declared in some other module) has no body. While the MLIR textual form provides a nice inline syntax for function arguments, they are internally represented as "block arguments" to the first block in the region.

Only dialect attribute names may be specified in the attribute dictionaries for function arguments, results, or the function itself.

The function linkage information is specified by linkage, as defined by GlobalLinkageKind attribute.

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(...)

// 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: CallableOpInterface, FunctionOpInterface, Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring 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
linkage::mlir::cir::GlobalLinkageKindAttrLinkage type/kind
extra_attrs::mlir::cir::ExtraFuncAttributesAttrRepresents aggregated attributes for a function
sym_visibility::mlir::StringAttrstring attribute
arg_attrs::mlir::ArrayAttrArray of dictionary attributes
res_attrs::mlir::ArrayAttrArray of dictionary attributes
aliasee::mlir::FlatSymbolRefAttrflat symbol reference attribute
global_ctor::mlir::cir::GlobalCtorAttrMarks a function as a global constructor
global_dtor::mlir::cir::GlobalDtorAttrMarks a function as a global destructor
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::mlir::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.

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>

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_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^)?
              (`constant` $constant^)?
              $linkage
              ($tls_model^)?
              $sym_name
              custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
              attr-dict

The cir.global operation declares or defines a named global variable.

The backing memory for the variable is allocated statically and is described by the type of the variable.

The operation is a declaration if no inital_value is specified, else it is a definition.

The global variable can also be marked constant using the constant unit attribute. Writing to such constant global variables is undefined.

The linkage tracks C/C++ linkage types, currently very similar to LLVM's. Symbol visibility in sym_visibility is defined in terms of MLIR's visibility and verified to be in accordance to linkage.

Example:

// Public and constant variable with initial value.
cir.global public constant @c : i32 = 4;

Traits: NoRegionArguments

Interfaces: RegionBranchOpInterface, Symbol

Attributes:

AttributeMLIR TypeDescription
sym_name::mlir::StringAttrstring attribute
sym_visibility::mlir::StringAttrstring attribute
sym_type::mlir::TypeAttrany type attribute
linkage::mlir::cir::GlobalLinkageKindAttrLinkage type/kind
tls_model::mlir::cir::TLS_ModelAttrTLS model
initial_value::mlir::Attributeany attribute
constant::mlir::UnitAttrunit attribute
alignment::mlir::IntegerAttr64-bit signless integer attribute
ast::mlir::cir::ASTVarDeclInterfaceASTVarDeclInterface instance
section::mlir::StringAttrstring attribute

cir.goto (cir::GotoOp)

Syntax:

operation ::= `cir.goto` $label attr-dict

Transfers control to the specified label.

Example:

   void foo() {
     goto exit;

   exit:
     return;
   }
   cir.func @foo() {
     cir.goto "exit"
   ^bb1:
     cir.label "exit"
     cir.return
   }

Traits: Terminator

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. cir.yield must explicitly terminate the region if it has more than one block.

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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^)?
              (`atomic` `(` $mem_order^ `)`)?
              $addr `:` qualified(type($addr)) `,` type($result) attr-dict

cir.load reads a value (lvalue to rvalue conversion) given an address backed up by a cir.ptr type. A unit attribute deref can be used to mark the resulting value as used by another operation to dereference a pointer. A unit attribute volatile can be used to indicate a volatile loading. Load can be marked atomic by using atomic(<mem_order>).

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

Interfaces: InferTypeOpInterface

Attributes:

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

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 extended-precision float 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 extended-precision float type

cir.log2 (cir::Log2Op)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.log (cir::LogOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

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.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 CIR pointer type
src CIR pointer type
len primitive int

cir.nearbyint (cir::NearbyintOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.objsize (cir::ObjSizeOp)

Conversion between values of different types

Syntax:

operation ::= `cir.objsize` `(`
              $ptr `:` type($ptr) `,`
              $kind
              (`,` `dynamic` $dynamic^)?
              `)`
              `->` type($result) attr-dict

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Attributes:

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

Operands:

Operand Description
ptr CIR pointer type

Results:

Result Description
result primitive int

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 mlir::cir::IntType result.

Note that the result considers the pointer size according to the ABI for the pointee sizes, e.g. the subtraction between two !cir.ptr<!u64i> might yield 1, meaning 8 bytes, whereas for void or function type pointees, yielding 8 means 8 bytes.

%7 = "cir.ptr_diff"(%0, %1) : !cir.ptr<!u64i> -> !u64i

Traits: AlwaysSpeculatableImplTrait, SameTypeOperands

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Operands:

Operand Description
lhs CIR pointer type
rhs CIR pointer type

Results:

Result Description
result primitive int

cir.ptr_stride (cir::PtrStrideOp)

Pointer access with stride

Syntax:

operation ::= `cir.ptr_stride` `(` $base `:` qualified(type($base)) `,` $stride `:` qualified(type($stride)) `)`
              `,` qualified(type($result)) attr-dict

Given a base pointer as first operand, provides a new pointer after applying a stride (second operand).

%3 = cir.const 0 : i32
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32), !cir.ptr<i32>

Traits: AlwaysSpeculatableImplTrait, SameFirstOperandAndResultType

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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` attr-dict

The cir.resume operation terminates a region on cir.catch, "resuming" or continuing the unwind process.

Examples:

cir.catch ... {
  ...
  fallback { cir.resume };
}

Traits: HasParent<CatchOp>, ReturnLike, Terminator

Interfaces: RegionBranchTerminatorOpInterface

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>, 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 extended-precision float 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 extended-precision float type

cir.rotate (cir::RotateOp)

Reverse the bytes that constitute the operand integer

Syntax:

operation ::= `cir.rotate` (`left` $left^) : (`right`)?
              $src `,` $amt `->` type($result) attr-dict

The cir.rotate rotates operand in src by the given bit amount amt. Its widths must be either 8, 16, 32, or 64 and both src, amt and result be of the same type. The rotate direction is specified by a left/right keyword.

This operation covers different C/C++ builtins, some examples: __builtin_rotateleft8, __builtin_rotateleft16, __builtin_rotateleft32, __builtin_rotateleft64, _rotl8, _rotl16, _rotl, _lrotl, _rotl64, etc and their "right" variants.

Example:

%r = cir.rotate left %0, %1 -> !u32i

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.scope (cir::ScopeOp)

Represents a C/C++ scope

Syntax:

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

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

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

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

If cir.scope yields no value, the cir.yield can be left out, and will be inserted implicitly.

Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait

Interfaces: ConditionallySpeculatable, RegionBranchOpInterface

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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.

%7 = cir.shift(left, %1 : !u64i, %4 : !s32i) -> !u64i

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
amount Integer type with arbitrary precision up to a fixed limit

Results:

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

cir.sin (cir::SinOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.sqrt (cir::SqrtOp)

Libc builtin equivalent ignoring floating point exceptions and errno

Syntax:

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

Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

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 extended-precision float 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 extended-precision float type

cir.stack_restore (cir::StackRestoreOp)

Restores the state of the function stack

Syntax:

operation ::= `cir.stack_restore` $ptr attr-dict `:` qualified(type($ptr))

Restore the state of the function stack to the state it was in when the corresponding cir.stack_save executed. Useful for implementing language features like variable length arrays.

%0 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] {alignment = 8 : i64}
%1 = cir.stack_save : <!u8i>
cir.store %1, %0 : !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i>
cir.stack_restore %2 : !cir.ptr<!u8i>

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.store (cir::StoreOp)

Store value to memory address

Syntax:

operation ::= `cir.store` (`volatile` $is_volatile^)?
              (`atomic` `(` $mem_order^ `)`)?
              $value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))

cir.store stores a value (first operand) to the memory address specified in the second operand. A unit attribute volatile can be used to indicate a volatile store. Store's can be marked atomic by using atomic(<mem_order>).

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>

Attributes:

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

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents
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>(
              $regions, $cases, $condition, type($condition)
              )
              attr-dict

The cir.switch operation represents C/C++ switch functionality for conditionally executing multiple regions of code. The operand to an switch is an integral condition value.

A variadic list of "case" attribute operands and regions track the possible control flow within cir.switch. A case must be in one of the following forms:

  • equal, <constant>: equality of the second case operand against the condition.
  • anyof, [constant-list]: equals to any of the values in a subsequent following list.
  • default: any other value.

Each case region must be explicitly terminated.

Examples:

cir.switch (%b : i32) [
  case (equal, 20) {
    ...
    cir.yield break
  },
  case (anyof, [1, 2, 3] : i32) {
    ...
    cir.return ...
  }
  case (default) {
    ...
    cir.yield fallthrough
  }
]

Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait, SameVariadicOperandSize

Interfaces: ConditionallySpeculatable, RegionBranchOpInterface

Attributes:

AttributeMLIR TypeDescription
cases::mlir::ArrayAttrcir.switch case array attribute

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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(!cir.ptr<!u8i>) -> <!cir.ptr<!u8i>>
    ...
    cir.store %13, %11 : // Store string addr for "Division by zero condition!"
    cir.throw(%11 : !cir.ptr<!cir.ptr<!u8i>>, @"typeinfo for char const*")

Traits: HasParent<FuncOp, ScopeOp, IfOp, SwitchOp, DoWhileOp, WhileOp, ForOp>, Terminator

Attributes:

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

Operands:

Operand Description
exception_ptr 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 extended-precision float 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 extended-precision float type

cir.try_call (cir::TryCallOp)

Try call operation

Similar to cir.call, direct and indirect properties are the same. The difference relies in an exception object address operand. It's encoded as the first operands or second (for indirect calls).

Similarly to cir.call, avoid using mlir::Operation methods to walk the operands for this operation, instead use the methods provided by CIRCallOpInterface.

Example:

cir.try {
  %0 = cir.alloca !cir.ptr<!cir.eh.info>, !cir.ptr<!cir.ptr<!cir.eh.info>>
  ...
  %r = cir.try_call %exception(%0) @division(%1, %2)
} ...

Interfaces: CIRCallOpInterface, CallOpInterface, SymbolUserOpInterface

Attributes:

AttributeMLIR TypeDescription
callee::mlir::FlatSymbolRefAttrflat symbol reference attribute
ast::mlir::cir::ASTCallExprInterfaceASTCallExprInterface instance

Operands:

Operand Description
exceptionInfo !cir.eh_info**
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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

Results:

Result Description
«unnamed» 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.try (cir::TryOp)

Syntax:

operation ::= `cir.try` $body `:` functional-type(operands, results) attr-dict
TBD

Note that variables declared inside a try {} in C++ will have their allocas places in the surrounding (parent) scope.

Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait

Interfaces: ConditionallySpeculatable, InferTypeOpInterface, RegionBranchOpInterface

Results:

Result Description
result !cir.eh_info*

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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.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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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::mlir::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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

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, CatchOp, TryOp, ArrayCtor, ArrayDtor>, 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 bool type or CIR array type or CIR vector type or CIR function type or CIR void type or CIR struct type or CIR exception info or CIR single-precision float type or CIR double-precision float type or CIR type that represents x87 80-bit floating-point format or CIR extended-precision float type or CIR type that represents IEEE-754 binary16 format or CIR type that represents

cir.llvmir.zeroinit (cir::ZeroInitConstOp)

Zero initializes a constant value of a given type

Syntax:

operation ::= `cir.llvmir.zeroinit` attr-dict `:` type($result)

This operation circumvents the lack of a zeroinitializer operation in LLVM Dialect. It can zeroinitialize any LLVM type.

Traits: AlwaysSpeculatableImplTrait

Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)

Effects: MemoryEffects::Effect{}

Results:

Result Description
result any type