1. ‘cir’ Dialect¶
A high-level dialect for analyzing and optimizing Clang supported languages
1.1. Operations¶
1.1.1. cir.abs (::cir::AbsOp)¶
Computes the absolute value of a signed integer
Syntax:
operation ::= `cir.abs` $src ( `min_is_poison` $min_is_poison^ )? `:` type($src) attr-dict
cir.abs computes the absolute value of a signed integer or vector
of signed integers.
The min_is_poison attribute indicates whether the result value is a
poison value if the argument is statically or dynamically the minimum
value for the type.
Example:
%0 = cir.const #cir.int<-42> : s32i
%1 = cir.abs %0 min_is_poison : s32i
%2 = cir.abs %3 : !cir.vector<!s32i x 4>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.1.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
min_is_poison | ::mlir::UnitAttr | unit attribute |
1.1.1.2. Operands:¶
Operand |
Description |
|---|---|
|
signed integer or vector of signed integer type |
1.1.1.3. Results:¶
Result |
Description |
|---|---|
|
signed integer or vector of signed integer type |
1.1.2. cir.acos (::cir::ACosOp)¶
Computes the arcus cosine of the specified value
Syntax:
operation ::= `cir.acos` $src `:` type($src) attr-dict
cir.acoscomputes the arcus cosine of a given value and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.2.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.2.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.3. cir.add (::cir::AddOp)¶
Integer addition
Syntax:
operation ::= `cir.add` (`nsw` $no_signed_wrap^)?
(`nuw` $no_unsigned_wrap^)?
(`sat` $saturated^)?
$lhs `,` $rhs `:` type($lhs) attr-dict
The cir.add operation performs addition on integer operands. Both
operands and the result must have the same integer or vector-of-integer
type.
The optional nsw (no signed wrap) and nuw (no unsigned wrap) unit
attributes indicate that the result is poison if signed or unsigned
overflow occurs, respectively. The optional sat (saturated) attribute
clamps the result to the type’s representable range instead of wrapping.
The nsw/nuw flags and sat are mutually exclusive.
Example:
%0 = cir.add %a, %b : !s32i
%1 = cir.add nsw %a, %b : !s32i
%2 = cir.add nuw %a, %b : !u32i
%3 = cir.add sat %a, %b : !s32i
%4 = cir.add %va, %vb : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.3.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
1.1.3.2. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.4. cir.add.overflow (::cir::AddOverflowOp)¶
Integer addition with overflow checking
Syntax:
operation ::= `cir.add.overflow` $lhs `,` $rhs `:` qualified(type($lhs)) `->` qualified(type($result))
attr-dict
cir.add.overflow performs addition with overflow checking on integral
operands. See CIR_BinOpOverflow for semantics.
Example:
%result, %overflow = cir.add.overflow %a, %b : !u32i -> !u32i
%result, %overflow = cir.add.overflow %a, %b : !cir.int<s, 33> -> !s32i
%result, %overflow = cir.add.overflow %a, %b : !s32i -> !cir.bool
Traits: AlwaysSpeculatableImplTrait, Commutative, SameTypeOperands
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.4.1. Operands:¶
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
|
Integer type with arbitrary precision up to a fixed limit |
1.1.4.2. Results:¶
Result |
Description |
|---|---|
|
integer or boolean type |
|
CIR bool type |
1.1.5. cir.address_of_return_address (::cir::AddrOfReturnAddrOp)¶
The place stores the return address of the current function
Syntax:
operation ::= `cir.address_of_return_address` attr-dict `:` qualified(type($result))
Represents a call to builtin function _AddressOfReturnAddress in CIR.
This builtin function returns a pointer to the place in the stack frame
where the return address of the current function is stored.
Examples:
%addr = address_of_return_address() : !cir.ptr<!u8i>
1.1.5.1. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.6. cir.alloc.exception (::cir::AllocExceptionOp)¶
Allocates an exception according to Itanium ABI
Syntax:
operation ::= `cir.alloc.exception` $size `->` qualified(type($addr)) attr-dict
Implements a slightly higher level __cxa_allocate_exception:
void *__cxa_allocate_exception(size_t thrown_size);
If the operation fails, the program terminates rather than throw.
Example:
// if (b == 0) {
// ...
// throw "...";
cir.if %10 {
%11 = cir.alloc_exception 8 -> !cir.ptr<!void>
... // store exception content into %11
cir.throw %11 : !cir.ptr<!cir.ptr<!u8i>>, ...
1.1.6.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
size | ::mlir::IntegerAttr | 64-bit signless integer attribute |
1.1.6.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.7. cir.alloca (::cir::AllocaOp)¶
Defines a scope-local variable
Syntax:
operation ::= `cir.alloca` $name
`align` `(` $alignment `)`
oilist( `init` $init
| `const` $constant
| `cleanup_dest_slot` $cleanup_dest_slot)
(`size` `(` $dynAllocSize^ `)`)? `:` qualified(type($addr))
($annotations^)? attr-dict
The cir.alloca operation defines a scope-local variable.
The presence of the const attribute indicates that the local variable is
declared with C/C++ const keyword.
The dynAllocSize specifies the size to dynamically allocate on the stack
and ignores the allocation size based on the original type. This is useful
when handling VLAs or the alloca builtin and is omitted when declaring
regular local variables.
The cleanup_dest_slot attribute indicates that this was a temporary
alloca generated by the compiler to handle cleanup exit dispatching.
The result type is a pointer to the input’s type.
Example:
// int count;
%0 = cir.alloca "count" align(4) : !cir.ptr<i32>
// int *ptr;
%1 = cir.alloca "ptr" align(8) : !cir.ptr<!cir.ptr<i32>>
...
Interfaces: PromotableAllocationOpInterface
1.1.7.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::StringAttr | string attribute |
init | ::mlir::UnitAttr | unit attribute |
constant | ::mlir::UnitAttr | unit attribute |
cleanup_dest_slot | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute whose minimum value is 1 |
annotations | ::mlir::ArrayAttr | array of cir.annotation attributes |
1.1.7.2. Operands:¶
Operand |
Description |
|---|---|
|
64-bit unsigned integer |
1.1.7.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.8. cir.and (::cir::AndOp)¶
Bitwise AND
Syntax:
operation ::= `cir.and` $lhs `,` $rhs `:` type($lhs) attr-dict
The cir.and operation performs a bitwise AND on integer operands.
Both operands and the result must have the same integer type.
Example:
%0 = cir.and %a, %b : !s32i
%1 = cir.and %a, %b : !cir.bool
Traits: Commutative, Idempotent, SameOperandsAndResultType
Interfaces: BinaryOpInterface, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.8.1. Operands:¶
Operand |
Description |
|---|---|
|
integer, boolean, or vector of integer |
|
integer, boolean, or vector of integer |
1.1.8.2. Results:¶
Result |
Description |
|---|---|
|
integer, boolean, or vector of integer |
1.1.9. cir.array.ctor (::cir::ArrayCtor)¶
Initialize array elements with C++ constructors
Syntax:
operation ::= `cir.array.ctor` $addr (`,` $num_elements^)? `:` qualified(type($addr))
(`,` type($num_elements)^)? $body
(`partial_dtor` $partial_dtor^)?
attr-dict
Initialize each array element using the same C++ constructor. This
operation has a body region and an optional partial_dtor region.
Both regions have a single block whose argument is a pointer to the
current array element.
The body region contains the constructor call for one element.
The partial_dtor region, when non-empty, contains the destructor call
for one element. During lowering, it is used to build a cleanup that
destroys already-constructed elements if a constructor throws. When the
element type has a trivial destructor or exceptions are disabled, the
partial_dtor region is left empty.
When num_elements is absent, addr must be a pointer to a fixed-size
CIR array type and the element count is derived from that array type.
When num_elements is present, addr is a pointer to the first element
and num_elements provides the runtime element count (for example new T[n]).
Examples:
// Fixed size without partial destructor:
cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @some_ctor(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
// Variable size without partial destructor:
cir.array.ctor(%ptr, %n : !cir.ptr<!rec_S>, !u64i) {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @some_ctor(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
// Fixed size with partial destructor:
cir.array.ctor(%0 : !cir.ptr<!cir.array<!rec_S x 42>>) {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @some_ctor(%arg0) : (!cir.ptr<!rec_S>) -> ()
} partial_dtor {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @some_dtor(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
Traits: SingleBlockImplicitTerminator<cir::YieldOp>, SingleBlock
1.1.9.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer type |
|
integer type |
1.1.10. cir.array.dtor (::cir::ArrayDtor)¶
Destroy array elements with C++ destructors
Syntax:
operation ::= `cir.array.dtor` $addr (`,` $num_elements^)? `:` qualified(type($addr))
(`,` type($num_elements)^)? (`dtor_may_throw` $dtor_may_throw^)? $body
attr-dict
Destroy each array element using the same C++ destructor. This operation has one region with one block whose argument is a pointer to the current array element.
When num_elements is absent, addr must be a pointer to a fixed-size
CIR array type and the element count is derived from that array type.
When num_elements is present, addr is a pointer to the first element
and num_elements provides the runtime element count (e.g. from an array
cookie for delete[]).
When dtor_may_throw is present, the element destructor call may throw
an exception.
Elements are destroyed in reverse order.
Examples:
// Fixed-size (stack array, global):
cir.array.dtor %0 : !cir.ptr<!cir.array<!rec_S x 42>> {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @_ZN1SD1Ev(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
// Dynamic count (delete[] with destructor):
cir.array.dtor %ptr, %n : !cir.ptr<!rec_S>, !u64i {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @_ZN1SD1Ev(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
// Dynamic count (delete[] with throwing destructor):
cir.array.dtor %ptr, %n : !cir.ptr<!rec_S>, !u64i dtor_may_throw {
^bb0(%arg0: !cir.ptr<!rec_S>):
cir.call @_ZN1SD1Ev(%arg0) : (!cir.ptr<!rec_S>) -> ()
}
Traits: SingleBlockImplicitTerminator<cir::YieldOp>, SingleBlock
1.1.10.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer type |
|
integer type |
1.1.11. cir.asin (::cir::ASinOp)¶
Computes the arcus sine of the specified value
Syntax:
operation ::= `cir.asin` $src `:` type($src) attr-dict
cir.asincomputes the arcus sine of a given value and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.11.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.11.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.12. cir.asm (::cir::InlineAsmOp)¶
The cir.asm operation represents C/C++ asm inline.
CIR constraints strings follow 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 are a storage, where each element corresponds to the operand with the same index. The first index relates to the operation result (if any). The operands themselves are stored as VariadicOfVariadic in the following order: output, input and then in/out operands. When several output operands are present, the result type may be represented as an anonymous record type.
Example:
__asm__("foo" : : : );
__asm__("bar $42 %[val]" : [val] "=r" (x), "+&r"(x));
__asm__("baz $42 %[val]" : [val] "=r" (x), "+&r"(x) : "[val]"(y));
!rec_22anon2E022 = !cir.record<struct "anon.0" {!cir.int<s, 32>, !cir.int<s, 32>}>
!rec_22anon2E122 = !cir.record<struct "anon.1" {!cir.int<s, 32>, !cir.int<s, 32>}>
...
%0 = cir.alloca "x" align(4) init : !cir.ptr<!s32i>
%1 = cir.alloca "y" align(4) init : !cir.ptr<!s32i>
...
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.load %1 : !cir.ptr<!s32i>, !s32i
cir.asm(x86_att,
out = [],
in = [],
in_out = [],
{"foo" "~{dirflag},~{fpsr},~{flags}"}) side_effects
cir.asm(x86_att,
out = [],
in = [],
in_out = [%2 : !s32i],
{"bar $$42 $0" "=r,=&r,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E022
cir.asm(x86_att,
out = [],
in = [%3 : !s32i],
in_out = [%2 : !s32i],
{"baz $$42 $0" "=r,=&r,0,1,~{dirflag},~{fpsr},~{flags}"}) -> !rec_22anon2E122
Traits: RecursiveMemoryEffects
1.1.12.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
asm_string | ::mlir::StringAttr | string attribute |
constraints | ::mlir::StringAttr | string attribute |
side_effects | ::mlir::UnitAttr | unit attribute |
asm_flavor | ::cir::AsmFlavorAttr | ATT or Intel |
operand_attrs | ::mlir::ArrayAttr | array attribute |
operands_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
1.1.12.2. Operands:¶
Operand |
Description |
|---|---|
|
variadic of any non-token type |
1.1.12.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.13. cir.assume (::cir::AssumeOp)¶
Tell the optimizer that a boolean value is true
Syntax:
operation ::= `cir.assume` $predicate custom<AssumeBundle>($bundle_kind, $bundle_args,
type($bundle_args))
`:` type($predicate) attr-dict
The cir.assume operation takes a single boolean predicate as its first
argument and does not have any results. The operation tells the optimizer
that the predicate is always true.
An optional operand bundle carries additional assumption metadata,
mirroring MLIR LLVM dialect’s llvm.assume operand bundles
(mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td). The bundle
kind is a AssumeBundleKind enum; bundle operands follow the kind
keyword in the assembly form. For example,
__builtin_assume_dereferenceable(p, n) lowers to
cir.assume %true dereferenceable(%p, %n : !cir.ptr<!void>, !u64i) : !cir.bool, which in turn lowers to
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr, i64) ].
This operation corresponds to the __assume / __builtin_assume
builtins (no bundle), as well as __builtin_assume_aligned
(align bundle), __builtin_assume_separate_storage
(separate_storage bundle), and __builtin_assume_dereferenceable
(dereferenceable bundle).
1.1.13.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
bundle_kind | ::cir::AssumeBundleKindAttr | kind of cir.assume operand bundle |
1.1.13.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR bool type |
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.14. cir.atan (::cir::ATanOp)¶
Computes the floating-point arcus tangent value
Syntax:
operation ::= `cir.atan` $src `:` type($src) attr-dict
cir.atan computes the arcus tangent of a floating-point operand
and returns a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.14.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.14.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.15. cir.atan2 (::cir::ATan2Op)¶
Computes the arc tangent of y/x
Syntax:
operation ::= `cir.atan2` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
cir.atan2 computes the arc tangent of the first operand divided by the
second operand, using the signs of both to determine the quadrant.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.15.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
1.1.15.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.16. cir.atomic.clear (::cir::AtomicClearOp)¶
Atomic clear
Syntax:
operation ::= `cir.atomic.clear` $mem_order $ptr
(`volatile` $is_volatile^)?
`:` qualified(type($ptr)) attr-dict
C/C++ atomic clear operation. Implements the builtin function
__atomic_clear.
The operation takes as its only operand a pointer to an 8-bit signed integer. The operation atomically sets the integer to zero.
Example:
cir.atomic.clear seq_cst %ptr : !cir.ptr<!s8i>
1.1.16.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.16.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to 8-bit signed integer |
1.1.17. cir.atomic.cmpxchg (::cir::AtomicCmpXchgOp)¶
Atomic compare and exchange
Syntax:
operation ::= `cir.atomic.cmpxchg` (`weak` $weak^)?
`success` `(` $succ_order `)` `failure` `(` $fail_order `)`
`syncscope` `(` $sync_scope `)`
$ptr `,` $expected `,` $desired
(`align` `(` $alignment^ `)`)?
(`volatile` $is_volatile^)?
`:` functional-type(operands, results) attr-dict
C/C++ atomic compare and exchange operation. Implements builtins like
__atomic_compare_exchange_n and __atomic_compare_exchange.
This operation takes three arguments: a pointer ptr and two values
expected and desired. This operation compares the value of the object
pointed-to by ptr with expected, and if they are equal, it sets the
value of the object to desired.
The succ_order attribute gives the memory order of this atomic operation
when the exchange takes place. The fail_order attribute gives the memory
order of this atomic operation when the exchange does not take place.
The sync_scope attribute specifies the synchronization scope for this
atomic operation.
The weak attribute is a boolean flag that indicates whether this is a
“weak” compare-and-exchange operation. A weak compare-and-exchange operation
allows “spurious failures”, meaning that be treated as if the comparison
failed and not exchange values even if *ptr and expected indeed compare
equal.
The type of expected and desired must be the same. The pointee type of
ptr must be the same as the type of expected and desired.
This operation has two results. The first result old gives the old value
of the object pointed-to by ptr, regardless of whether the exchange
actually took place. The second result success is a boolean flag
indicating whether the exchange actually took place.
Example:
%old, %success = cir.atomic.cmpxchg weak success(seq_cst) failure(acquire)
syncscope(system) %ptr, %expected, %desired
: (!cir.ptr<!u64i>, !u64i, !u64i) -> (!u64i, !cir.bool)
Interfaces: InferTypeOpInterface
1.1.17.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
succ_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
fail_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
sync_scope | ::cir::SyncScopeKindAttr | sync scope kind |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
weak | ::mlir::UnitAttr | unit attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.17.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.17.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
|
CIR bool type |
1.1.18. cir.atomic.fence (::cir::AtomicFenceOp)¶
Atomic thread fence
Syntax:
operation ::= `cir.atomic.fence` (`syncscope` `(` $syncscope^ `)`)? $ordering attr-dict
C/C++ Atomic thread fence synchronization primitive. Implements the builtin
__atomic_thread_fence which enforces memory ordering constraints across
threads within the specified synchronization scope.
This handles all variations including:
__atomic_thread_fence__atomic_signal_fence__c11_atomic_thread_fence__c11_atomic_signal_fence
Example:
cir.atomic.fence syncscope(system) seq_cst
cir.atomic.fence syncscope(single_thread) seq_cst
1.1.18.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
ordering | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
syncscope | ::cir::SyncScopeKindAttr | sync scope kind |
1.1.19. cir.atomic.fetch (::cir::AtomicFetchOp)¶
Atomic fetch-and-update operation
Syntax:
operation ::= `cir.atomic.fetch` $binop $mem_order
`syncscope` `(` $sync_scope `)`
(`fetch_first` $fetch_first^)?
$ptr `,` $val
(`volatile` $is_volatile^)?
`:` `(` qualified(type($ptr)) `,` qualified(type($val)) `)`
`->` type($result) attr-dict
C/C++ atomic fetch-and-update operation. This operation implements the C/C++
builtin functions __atomic_<binop>_fetch, __atomic_fetch_<binop>, and
__c11_atomic_fetch_<binop>, where <binop> is one of the following binary
opcodes: add, sub, and, xor, or, nand, max, min,
uinc_wrap, and udec_wrap.
This operation takes 2 arguments: a pointer ptr and a value val. The
type of val must match the pointee type of ptr. If the binary operation
is add, sub, max, or min, the type of val may either be an integer
type or a floating-point type. Otherwise, val must be an integer.
This operation atomically loads the value from ptr, performs the binary
operation as indicated by binop on the loaded value and val, and stores
the result back to ptr. If the fetch_first flag is present, the result
of this operation is the old value loaded from ptr before the binary
operation. Otherwise, the result of this operation is the result of the
binary operation.
Example:
: (!cir.ptr<!s32i>, !s32i) -> !s32i
Interfaces: InferTypeOpInterface
1.1.19.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
binop | ::cir::AtomicFetchKindAttr | Binary opcode for atomic fetch-and-update operations |
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
sync_scope | ::cir::SyncScopeKindAttr | sync scope kind |
is_volatile | ::mlir::UnitAttr | unit attribute |
fetch_first | ::mlir::UnitAttr | unit attribute |
1.1.19.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to integer or floating point type |
|
integer or floating point type |
1.1.19.3. Results:¶
Result |
Description |
|---|---|
|
integer or floating point type |
1.1.20. cir.atomic.test_and_set (::cir::AtomicTestAndSetOp)¶
Atomic test and set
Syntax:
operation ::= `cir.atomic.test_and_set` $mem_order $ptr
(`volatile` $is_volatile^)?
`:` qualified(type($ptr)) `->` qualified(type($result)) attr-dict
C/C++ atomic test and set operation. Implements the builtin function
__atomic_test_and_set.
The operation takes as its only operand a pointer to an 8-bit signed integer. The operation atomically set the integer to an implementation- defined non-zero “set” value. The result of the operation is a boolean value indicating whether the previous value of the integer was the “set” value.
Example:
%res = cir.atomic.test_and_set seq_cst %ptr : !cir.ptr<!s8i> -> !cir.bool
Interfaces: InferTypeOpInterface
1.1.20.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.20.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to 8-bit signed integer |
1.1.20.3. Results:¶
Result |
Description |
|---|---|
|
CIR bool type |
1.1.21. cir.atomic.xchg (::cir::AtomicXchgOp)¶
Atomic exchange
Syntax:
operation ::= `cir.atomic.xchg` $mem_order
`syncscope` `(` $sync_scope `)`
(`volatile` $is_volatile^)?
$ptr `,` $val
`:` functional-type(operands, results) attr-dict
C/C++ atomic exchange operation. This operation implements the C/C++
builtin function __atomic_exchange, __atomic_exchange_n, and
__c11_atomic_exchange.
This operation takes two arguments: a pointer ptr and a value val. The
operation atomically replaces the value of the object pointed-to by ptr
with val, and returns the original value of the object.
Example:
%res = cir.atomic.xchg seq_cst %ptr, %val : !cir.ptr<!u64i> -> !u64i
Interfaces: InferTypeOpInterface
1.1.21.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
sync_scope | ::cir::SyncScopeKindAttr | sync scope kind |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.21.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.21.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.22. 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 allows individual scrutiny of conditions
which might lead to folding some of them out. Lowerings coming out
of CIR, e.g. LLVM, should use the suspend region to track more
lower level codegen (e.g. intrinsic emission for coro.save/coro.suspend).
There are also 4 flavors of cir.await available:
init: compiler generated initial suspend via implicitco_await.user: also known as normal, representing a user writtenco_await.yield: user writtenco_yieldexpressions.final: compiler generated final suspend via implicitco_await.
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
1.1.22.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::AwaitKindAttr | await kind |
1.1.23. cir.base_class_addr (::cir::BaseClassAddrOp)¶
Get the base class address for a class/struct
Syntax:
operation ::= `cir.base_class_addr` $derived_addr `:` qualified(type($derived_addr))
(`nonnull` $assume_not_null^)?
` ` `[` $offset `]` `->` qualified(type($base_addr)) attr-dict
The cir.base_class_addr operaration gets the address of a particular
non-virtual base class given a derived class pointer. The offset in bytes
of the base class must be passed in, since it is easier for the front end
to calculate that than the MLIR passes. The operation contains a flag for
whether or not the operand may be nullptr. That depends on the context and
cannot be known by the operation, and that information affects how the
operation is lowered.
The validity of the relationship of derived and base cannot yet be verified. If the target class is not a valid base class for the object, the behavior is undefined.
Example:
struct Base { };
struct Derived : Base { };
Derived d;
Base& b = d;
will generate
%3 = cir.base_class_addr %1 : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.23.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
1.1.23.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.23.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.24. cir.base_data_member (::cir::BaseDataMemberOp)¶
Cast a derived class data member pointer to a base class data member pointer
Syntax:
operation ::= `cir.base_data_member` $src `[` $offset `]` `:` qualified(type($src)) `->` qualified(type($result)) attr-dict
The cir.base_data_member operation casts a data member pointer of type
T Derived::* to a data member pointer of type T Base::*, where Base
is an accessible non-ambiguous non-virtual base class of Derived.
The offset parameter gives the offset in bytes of the Base base class
subobject within a Derived object.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.24.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
1.1.24.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
1.1.24.3. Results:¶
Result |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
1.1.25. cir.base_method (::cir::BaseMethodOp)¶
Cast a derived class pointer-to-member-function to a base class pointer-to-member-function
Syntax:
operation ::= `cir.base_method` $src `[` $offset `]` `:` qualified(type($src))
`->` qualified(type($result)) attr-dict
The cir.base_method operation casts a pointer-to-member-function of type
Ret (Derived::*)(Args) to a pointer-to-member-function of type
Ret (Base::*)(Args), where Base is a non-virtual base class of
Derived.
The offset parameter gives the offset in bytes of the Base base class
subobject within a Derived object.
Example:
%1 = cir.base_method %0 [16] : !cir.method<!cir.func<(!s32i)> in !rec_Derived> -> !cir.method<!cir.func<(!s32i)> in !rec_Base>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.25.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
1.1.25.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
1.1.25.3. Results:¶
Result |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
1.1.26. cir.begin_catch (::cir::BeginCatchOp)¶
Begin a catch handler
Syntax:
operation ::= `cir.begin_catch` $eh_token `:` type($eh_token) `->` `(` type($catch_token) `,`
qualified(type($exn_ptr)) `)` attr-dict
cir.begin_catch marks the beginning of a catch handler. It takes a
!cir.eh_token representing the inflight exception and returns a
!cir.catch_token along with a pointer to the exception object.
The catch token must be passed to the corresponding cir.end_catch
operation. The exception pointer points to the caught exception object
and can be used to access the exception value.
For catch(...) (catch all), the exception pointer type is
!cir.ptr<!void>.
In the high-level CIR representation, this operation appears as the
first operation in a catch handler region of a cir.try operation,
taking the region’s !cir.eh_token argument. In the flattened CIR
representation, it appears in a catch block, taking the block’s
!cir.eh_token argument.
Example:
// High-level form (inside cir.try catch handler region):
} catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
%catch_token, %exn_ptr = cir.begin_catch %eh_token
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
cir.cleanup.scope {
// Handle exception...
cir.yield
} cleanup eh {
cir.end_catch %catch_token : !cir.catch_token
cir.yield
}
cir.yield
}
// Flattened form (inside a catch block):
^catch_int(%eh_token : !cir.eh_token):
%catch_token, %exn_ptr = cir.begin_catch %eh_token
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
// Handle exception...
cir.end_catch %catch_token : !cir.catch_token
cir.br ^continue
1.1.26.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR exception handling token type |
1.1.26.2. Results:¶
Result |
Description |
|---|---|
|
CIR catch token type |
|
CIR pointer type |
1.1.27. cir.begin_cleanup (::cir::BeginCleanupOp)¶
Begin a cleanup block during exception unwinding
Syntax:
operation ::= `cir.begin_cleanup` $eh_token `:` type($eh_token) `->` type($cleanup_token) attr-dict
cir.begin_cleanup marks the beginning of a cleanup handler during
exception unwinding. It takes a !cir.eh_token and returns a
!cir.cleanup_token that must be passed to the corresponding
cir.end_cleanup operation.
The cleanup code between cir.begin_cleanup and cir.end_cleanup will be
executed during exception unwinding before control is transferred to
the exception dispatcher.
Example:
^cleanup(%eh_token : !cir.eh_token):
%cleanup_token = cir.begin_cleanup %eh_token : !cir.eh_token
-> !cir.cleanup_token
cir.call @destructor() : () -> ()
cir.end_cleanup %cleanup_token : !cir.cleanup_token
cir.br ^dispatch(%eh_token : !cir.eh_token)
Interfaces: InferTypeOpInterface
1.1.27.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR exception handling token type |
1.1.27.2. Results:¶
Result |
Description |
|---|---|
|
CIR cleanup token type |
1.1.28. cir.bitreverse (::cir::BitReverseOp)¶
Reverse the bit pattern of the operand integer
Syntax:
operation ::= `cir.bitreverse` $input `:` type($result) attr-dict
The cir.bitreverse operation reverses the bits of the operand integer. Its
only argument must be of unsigned integer types of width 8, 16, 32, or 64.
Example:
%1 = cir.bitreverse %0: !u32i
Traits: AlwaysSpeculatableImplTrait, Involution, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.28.1. Operands:¶
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64 |
1.1.28.2. Results:¶
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64 |
1.1.29. cir.block_address (::cir::BlockAddressOp)¶
Get the address of a cir.label within a function
Syntax:
operation ::= `cir.block_address` $block_addr_info `:` qualified(type($addr)) attr-dict
The cir.blockaddress operation takes a function name and a label and
produces a pointer value that represents the address of that cir.label
within the specified function.
This operation models GCC’s “labels as values” extension (&&label), which
allows taking the address of a local label and using it as a computed
jump target (e.g., with goto *addr;).
Example:
%1 = cir.alloca "ptr" align(8) init : !cir.ptr<!cir.ptr<!void>>
%addr = cir.block_address <@c, "label1"> : !cir.ptr<!cir.void>
cir.store align(8) %addr, %1 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
cir.br ^bb1
^bb1:
cir.label "label"
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.29.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
block_addr_info | ::cir::BlockAddrInfoAttr | Block address attribute |
1.1.29.2. Results:¶
Result |
Description |
|---|---|
|
pointer to void type |
1.1.30. cir.br (::cir::BrOp)¶
Unconditional branch
Syntax:
operation ::= `cir.br` $dest (`(` $destOperands^ `:` type($destOperands) `)`)? attr-dict
The cir.br branches unconditionally to a block. Used to represent C/C++
goto’s and general block branching.
Note that for source level goto’s crossing scope boundaries, those are
usually represented with the “symbolic” cir.goto operation.
Example:
...
cir.br ^bb3
^bb3:
cir.return
Traits: AlwaysSpeculatableImplTrait, Terminator
Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.30.1. Operands:¶
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.30.2. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
1.1.31. 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
it branches to ‘bb1’.
Example:
...
cir.brcond %a, ^bb3, ^bb4
^bb3:
cir.return
^bb4:
cir.yield
Traits: AlwaysSpeculatableImplTrait, AttrSizedOperandSegments, Terminator
Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.31.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR bool type |
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.31.2. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
1.1.32. cir.break (::cir::BreakOp)¶
C/C++ break statement equivalent
Syntax:
operation ::= `cir.break` attr-dict
The cir.break operation is used to cease the execution of the current loop
or switch operation and transfer control to the parent operation. It is only
allowed within a breakable operations (loops and switches).
Traits: HasAncestor<WhileOp, DoWhileOp, ForOp, SwitchOp>, Terminator
1.1.33. cir.builtin_int_cast (::cir::BuiltinIntCastOp)¶
Cast between a CIR integer and a builtin integer
Syntax:
operation ::= `cir.builtin_int_cast` $src `:` type($src) `->` type($result) attr-dict
Convert between a CIR integer type (!cir.int) and a builtin MLIR integer
type (AnyInteger, e.g. i32, si32, ui32) or index, and vice versa.
This allows using operations from e.g. OpenMP or OpenACC dialects that expect the builtin types with CIR operations. Casting can be done in either direction.
Example:
// CIR integer cast to a builtin integer.
%0 = cir.builtin_int_cast %ciri : !cir.int<s, 32> -> i32
// Builtin induction variable / bound cast to CIR type.
%1 = cir.builtin_int_cast %iv : index -> !cir.int<u, 64>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.33.1. Operands:¶
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit or integer or index |
1.1.33.2. Results:¶
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit or integer or index |
1.1.34. cir.byte_swap (::cir::ByteSwapOp)¶
Reverse the bytes in the object representation of the operand
Syntax:
operation ::= `cir.byte_swap` $input `:` type($result) attr-dict
The cir.byte_swap operation takes an integer as operand, reverse the bytes
in the object representation of the operand integer, and returns the result.
The operand integer must be an unsigned integer whose width is a multiple of
16 bits (e.g. 16, 32, 64, 128, or a wider _BitInt).
Example:
// %0 = 0x12345678
%0 = cir.const #cir.int<305419896> : !u32i
// %1 should be 0x78563412
%1 = cir.byte_swap %0 : !u32i
Traits: AlwaysSpeculatableImplTrait, Involution, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.34.1. Operands:¶
Operand |
Description |
|---|---|
|
unsigned integer type with a width that is a multiple of 16 bits |
1.1.34.2. Results:¶
Result |
Description |
|---|---|
|
unsigned integer type with a width that is a multiple of 16 bits |
1.1.35. cir.call (::cir::CallOp)¶
Call a function
The cir.call operation represents a function call. It could represent
either a direct call or an indirect call.
If the operation represents a direct call, the callee should be defined
within the same symbol scope as the call. The callee attribute contains a
symbol reference to the callee function. All operands of this operation are
arguments to the callee function.
If the operation represents an indirect call, the callee attribute is
empty. The first operand of this operation must be a pointer to the callee
function. The rest operands are arguments to the callee function.
Example:
%0 = cir.call @foo()
Traits: NoRegionArguments
Interfaces: ArgAndResultAttrsOpInterface, CIRCallOpInterface, CallOpInterface, SymbolUserOpInterface
1.1.35.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
nothrow | ::mlir::UnitAttr | unit attribute |
musttail | ::mlir::UnitAttr | unit attribute |
side_effect | ::cir::SideEffectAttr | allowed side effects of a function |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
1.1.35.2. Operands:¶
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.35.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.36. cir.call_llvm_intrinsic (::cir::LLVMIntrinsicCallOp)¶
Call to llvm intrinsic functions that is not defined in CIR
Syntax:
operation ::= `cir.call_llvm_intrinsic` $intrinsic_name $arg_ops `:` functional-type($arg_ops, $result) attr-dict
cir.call_llvm_intrinsic operation represents a call-like expression which has
return type and arguments that maps directly to a llvm intrinsic.
It only records intrinsic intrinsic_name.
1.1.36.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
intrinsic_name | ::mlir::StringAttr | string attribute |
1.1.36.2. Operands:¶
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.36.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.37. cir.case (::cir::CaseOp)¶
Case operation
Syntax:
operation ::= `cir.case` `(` $kind `,` $value `)` $caseRegion attr-dict
The cir.case operation represents a case within a C/C++ switch.
The cir.case operation must be in a cir.switch operation directly
or indirectly.
The cir.case have 4 kinds:
equal, <constant>: equality of the second case operand against the condition.anyof, [constant-list]: equals to any of the values in a subsequent following list.range, [lower-bound, upper-bound]: the condition is within the closed interval.default: any other value.
Each case region must be explicitly terminated.
Traits: AutomaticAllocationScope, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.37.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
value | ::mlir::ArrayAttr | array attribute |
kind | ::cir::CaseOpKindAttr | case kind |
1.1.38. cir.cast (::cir::CastOp)¶
Conversion between values of different types
Syntax:
operation ::= `cir.cast` $kind $src `:` type($src) `->` type($result) attr-dict
Apply the usual C/C++ conversion rules between values. This operation models
a subset of conversions as defined in Clang’s OperationKinds.def
(llvm-project/clang/include/clang/AST/OperationKinds.def).
Note: not all conversions are implemented using cir.cast. For instance,
lvalue-to-rvalue conversion is modeled as a cir.load instead. Currently
supported kinds:
bitcastarray_to_ptrdecay`member_ptr_to_bool
int_to_ptrptr_to_intptr_to_boolintegralint_to_boolint_to_floatfloat_to_intfloat_to_boolbool_to_intfloatingfloat_complexint_complex_to_realint_complex_to_boolint_complexint_complex_to_float_complexaddress_space
CIR also supports some additional conversions that are not part of the classic Clang codegen:
bool_to_float
Example:
%4 = cir.cast int_to_bool %3 : i32 -> !cir.bool
...
%x = cir.cast array_to_ptrdecay %0
: !cir.ptr<!cir.array<i32 x 10>> -> !cir.ptr<i32>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), PromotableOpInterface
Effects: MemoryEffects::Effect{}
1.1.38.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CastKindAttr | cast kind |
1.1.38.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.38.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.39. cir.catch_param (::cir::CatchParamOp)¶
Represents the catch clause formal parameter
Syntax:
operation ::= `cir.catch_param` (`:` qualified(type($param))^)?
attr-dict
The cir.catch_param is used to retrieve the exception object inside
the handler regions of cir.try.
This operation is used only before the CFG flatterning pass.
Example:
%exception = cir.catch_param : !cir.ptr<!void>
Traits: HasParent<TryOp>
1.1.39.1. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.40. cir.ceil (::cir::CeilOp)¶
Computes the ceiling of the specified value
Syntax:
operation ::= `cir.ceil` $src `:` type($src) attr-dict
cir.ceil computes the ceiling of a given value and returns a result
of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.40.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.40.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.41. cir.cleanup.scope (::cir::CleanupScopeOp)¶
Represents a scope with associated cleanup code
Syntax:
operation ::= `cir.cleanup.scope` $bodyRegion `cleanup` $cleanupKind $cleanupRegion attr-dict
cir.cleanup.scope contains a body region and a cleanup region. The body
region is executed first, and the cleanup region is executed when the body
region is exited, either normally or due to an exception.
The cleanup kind attribute specifies when the cleanup region should be executed:
none: No cleanup (cleanup region is empty/unused)normal: Cleanup is executed only on normal exiteh: Cleanup is executed only on exception unwindingall: Cleanup is executed on both normal exit and exception unwinding
Examples:
// Cleanup that runs on both normal and exception paths
cir.cleanup.scope {
cir.call @mayThrow() : () -> ()
cir.yield
} cleanup all {
cir.call @destructor() : () -> ()
cir.yield
}
// EH-only cleanup (destructor only called on exception)
cir.cleanup.scope {
cir.call @mayThrow() : () -> ()
cir.yield
} cleanup eh {
cir.call @destructor() : () -> ()
cir.yield
}
Both regions must be terminated. If a region has only one block, the
terminator can be left out, and cir.yield will be inserted implicitly.
Traits: AutomaticAllocationScope, NoRegionArguments, RecursiveMemoryEffects, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.41.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
cleanupKind | ::cir::CleanupKindAttr | Cleanup kind attribute |
1.1.42. cir.clear_cache (::cir::ClearCacheOp)¶
Clear the processor’s instruction cache if required.
Syntax:
operation ::= `cir.clear_cache` $begin `,` $end `:` qualified(type($begin))
attr-dict
The cir.clear_cache operation provides a representation for the
__builtin__clear_cache builtin and corresponds to the
llvm.clear_cache intrinsic in LLVM IR.
This operation ensures visibility of modifications in the specified range to the execution unit of the processor. On targets with non-unified instruction and data cache, the implementation flushes the instruction cache.
On platforms with coherent instruction and data caches (e.g., x86), this intrinsic is a nop. On platforms with non-coherent instruction and data cache (e.g., ARM, MIPS), the operation will be lowered either to appropriate instructions or a system call, if cache flushing requires special privileges.
The default behavior is to emit a call to __clear_cache from the
runtime library.
This operation does not empty the instruction pipeline. Modifications of the current function are outside the scope of the operation.
1.1.42.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
1.1.43. cir.clrsb (::cir::BitClrsbOp)¶
Get the number of leading redundant sign bits in the input
Syntax:
operation ::= `cir.clrsb` $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.clrsb operation returns the number
of consecutive bits following the sign bit that are identical to the sign
bit.
The bit width of the input integer must be either 32 or 64.
Examples:
// %0 = 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.clrsb %0 : !s32i
// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
%2 = cir.const #cir.int<1> : !s32i
// %3 will be 30 because there are 30 consecutive bits following the sign
// bit that are identical to the sign bit.
%3 = cir.clrsb %2 : !s32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.43.1. Operands:¶
Operand |
Description |
|---|---|
|
signed integer type of widths 32/64 |
1.1.43.2. Results:¶
Result |
Description |
|---|---|
|
signed integer type of widths 32/64 |
1.1.44. cir.clz (::cir::BitClzOp)¶
Get the number of leading 0-bits in the input
Syntax:
operation ::= `cir.clz` $input (`poison_zero` $poison_zero^)?
`:` type($result) attr-dict
Compute the number of leading 0-bits in the input.
The input integer must be an unsigned integer. The cir.clz operation
returns the number of consecutive 0-bits at the most significant bit
position in the input.
If the poison_zero attribute is present, this operation will have
undefined behavior if the input value is 0.
Example:
// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 28
%1 = cir.clz %0 poison_zero : !u32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.44.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
poison_zero | ::mlir::UnitAttr | unit attribute |
1.1.44.2. Operands:¶
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
1.1.44.3. Results:¶
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
1.1.45. cir.cmp (::cir::CmpOp)¶
Compare two values and produce a boolean result
Syntax:
operation ::= `cir.cmp` $kind $lhs `,` $rhs `:` type($lhs) attr-dict
The cir.cmp operation compares two operands of the same type and produces
a !cir.bool result. It supports integral, floating-point, and pointer
types.
The following comparison predicates are available:
lt: less thanle: less than or equalgt: greater thange: greater than or equaleq: equalne: not equalone: ordered and not equal (floating-point only)uno: unordered (floating-point only, true if either operand is NaN)
For floating-point comparisons, the predicate follows C semantics (e.g.
NaN comparisons return false for all predicates except ne).
The one and uno predicates are floating-point specific: one is
ordered not-equal (false for NaN), uno tests if either operand is NaN.
%0 = cir.cmp gt %1, %2 : !s32i
%1 = cir.cmp eq %a, %b : !cir.ptr<!u8i>
Traits: AlwaysSpeculatableImplTrait, SameTypeOperands
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.45.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CmpOpKindAttr | compare operation kind |
1.1.45.2. Operands:¶
Operand |
Description |
|---|---|
|
comparable type |
|
comparable type |
1.1.45.3. Results:¶
Result |
Description |
|---|---|
|
CIR bool type |
1.1.46. cir.cmp3way (::cir::CmpThreeWayOp)¶
Compare two values with C++ three-way comparison semantics
Syntax:
operation ::= `cir.cmp3way` qualified($info) $lhs `,` $rhs `:` qualified(type($lhs))
`->` qualified(type($result)) attr-dict
The cir.cmp3way operation models the builtin <=> 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 three kinds of ordering: strong, weak 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>
#cmpinfo_partial_ltn1eq0gt1unn127 =
#cir.cmp3way_info<partial, lt = -1, eq = 0, gt = 1, unordered = -127>
#cmpinfo_strong_ltn1eq0gt1 =
#cir.cmp3way_info<strong, lt = -1, eq = 0, gt = 1>
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.const #cir.int<1> : !s32i
%2 = cir.cmp3way #cmpinfo_strong_ltn1eq0gt1 %0, %1 : !s32i -> !s8i
%3 = cir.const #cir.fp<0.0> : !cir.float
%4 = cir.const #cir.fp<1.0> : !cir.float
%5 = cir.cmp3way #cmpinfo_partial_ltn1eq0gt1unn127 %3, %4 : !cir.float -> !s8i
Traits: AlwaysSpeculatableImplTrait, SameTypeOperands
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.46.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
info | ::cir::CmpThreeWayInfoAttr | Holds information about a three-way comparison operation |
1.1.46.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.46.3. Results:¶
Result |
Description |
|---|---|
|
signed integer type |
1.1.47. cir.co_return (::cir::CoReturnOp)¶
Coroutine return operation
Syntax:
operation ::= `cir.co_return` attr-dict
The cir.co_return operation models a coroutine return point inside a
cir.coro.body region.
This operation is expected to appear only within a cir.coro.body region,
but it may be nested within other operations or regions inside that body.
Traits: AlwaysSpeculatableImplTrait, HasAncestor<CoroBodyOp>, ReturnLike, Terminator
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface
Effects: MemoryEffects::Effect{}
1.1.48. cir.complex.add (::cir::ComplexAddOp)¶
Complex addition
Syntax:
operation ::= `cir.complex.add` $lhs `,` $rhs `:` qualified(type($result)) attr-dict
The cir.complex.add operation takes two complex numbers and returns
their sum.
Example:
%2 = cir.complex.add %0, %1 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.48.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR complex type |
|
CIR complex type |
1.1.48.2. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.49. cir.complex.conj (::cir::ComplexConjOp)¶
Complex conjugate
Syntax:
operation ::= `cir.complex.conj` $operand `:` qualified(type($operand)) attr-dict
The cir.complex.conj operation takes a complex number and returns its
complex conjugate, which is formed by negating the imaginary part.
Example:
%1 = cir.complex.conj %0 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.49.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR complex type |
1.1.49.2. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.50. cir.complex.create (::cir::ComplexCreateOp)¶
Create a complex value from its real and imaginary parts
Syntax:
operation ::= `cir.complex.create` $real `,` $imag
`:` qualified(type($real)) `->` qualified(type($result)) attr-dict
The cir.complex.create operation takes two operands that represent the
real and imaginary part of a complex number, and yields the complex number.
%0 = cir.const #cir.fp<1.000000e+00> : !cir.double
%1 = cir.const #cir.fp<2.000000e+00> : !cir.double
%2 = cir.complex.create %0, %1 : !cir.double -> !cir.complex<!cir.double>
Traits: AlwaysSpeculatableImplTrait, SameTypeOperands
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.50.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or floating point type |
|
integer or floating point type |
1.1.50.2. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.51. cir.complex.div (::cir::ComplexDivOp)¶
Complex division
Syntax:
operation ::= `cir.complex.div` $lhs `,` $rhs `range` `(` $range `)` `:` qualified(type($result)) attr-dict
The cir.complex.div operation takes two complex numbers and returns
their quotient.
For complex types with floating-point components, the range attribute
specifies the algorithm to be used when the operation is lowered to
the LLVM dialect. For division, ‘improved’ produces Smith’s algorithms for
Complex division with no additional handling for NaN values. If ‘promoted’
is used, the values are promoted to a higher precision type, if possible,
and the calculation is performed using the algebraic formula, with
no additional handling for NaN values. We fall back on Smith’s algorithm
when the target doesn’t support a higher precision type. If ‘full’ is used,
a runtime-library function is called if one of the intermediate
calculations produced a NaN value. and for ‘basic’ algebraic formula with
no additional handling for the NaN value will be used. For integers types
range attribute will be ignored.
Example:
%2 = cir.complex.div %0, %1 range(basic) : !cir.complex<!cir.float>
%2 = cir.complex.div %0, %1 range(full) : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.51.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
range | ::cir::ComplexRangeKindAttr | complex multiplication and division implementation |
1.1.51.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR complex type |
|
CIR complex type |
1.1.51.3. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.52. cir.complex.imag (::cir::ComplexImagOp)¶
Extract the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag` $operand `:` qualified(type($operand)) `->` qualified(type($result))
attr-dict
cir.complex.imag operation takes an operand of !cir.complex, !cir.int
!cir.bool or !cir.float. If the operand is !cir.complex, the imag
part of it will be returned, otherwise a zero value will be returned.
Example:
%imag = cir.complex.imag %complex : !cir.complex<!cir.float> -> !cir.float
%imag = cir.complex.imag %scalar : !cir.float -> !cir.float
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.52.1. Operands:¶
Operand |
Description |
|---|---|
|
complex, integer, boolean or floating point type |
1.1.52.2. Results:¶
Result |
Description |
|---|---|
|
integer, boolean or floating point type |
1.1.53. cir.complex.imag_ptr (::cir::ComplexImagPtrOp)¶
Derive a pointer to the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.imag_ptr operation takes a pointer operand that points to a
complex value of type !cir.complex and yields a pointer to the imaginary
part of the operand.
Example:
%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>>
-> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.53.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to complex type |
1.1.53.2. Results:¶
Result |
Description |
|---|---|
|
pointer to integer or floating point type |
1.1.54. cir.complex.mul (::cir::ComplexMulOp)¶
Complex multiplication
Syntax:
operation ::= `cir.complex.mul` $lhs `,` $rhs `range` `(` $range `)` `:` qualified(type($result)) attr-dict
The cir.complex.mul operation takes two complex numbers and returns
their product.
For complex types with floating-point components, the range attribute
specifies the algorithm to be used when the operation is lowered to
the LLVM dialect. For multiplication, ‘improved’, ‘promoted’, and ‘basic’
are all handled equivalently, producing the algebraic formula with no
special handling for NaN value. If ‘full’ is used, a runtime-library
function is called if one of the intermediate calculations produced
a NaN value.
Example:
%2 = cir.complex.mul %0, %1 range(basic) : !cir.complex<!cir.float>
%2 = cir.complex.mul %0, %1 range(full) : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.54.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
range | ::cir::ComplexRangeKindAttr | complex multiplication and division implementation |
1.1.54.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR complex type |
|
CIR complex type |
1.1.54.3. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.55. cir.complex.real (::cir::ComplexRealOp)¶
Extract the real part of a complex value
Syntax:
operation ::= `cir.complex.real` $operand `:` qualified(type($operand)) `->` qualified(type($result))
attr-dict
cir.complex.real operation takes an operand of !cir.complex, cir.int,
!cir.bool or !cir.float. If the operand is !cir.complex, the real
part of it will be returned, otherwise the value returned unmodified.
Example:
%real = cir.complex.real %complex : !cir.complex<!cir.float> -> !cir.float
%real = cir.complex.real %scalar : !cir.float -> !cir.float
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.55.1. Operands:¶
Operand |
Description |
|---|---|
|
complex, integer, boolean or floating point type |
1.1.55.2. Results:¶
Result |
Description |
|---|---|
|
integer, boolean or floating point type |
1.1.56. cir.complex.real_ptr (::cir::ComplexRealPtrOp)¶
Derive a pointer to the real part of a complex value
Syntax:
operation ::= `cir.complex.real_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.real_ptr operation takes a pointer operand that points to a
complex value of type !cir.complex and yields a pointer to the real part
of the operand.
Example:
%1 = cir.complex.real_ptr %0 : !cir.ptr<!cir.complex<!cir.double>>
-> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.56.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to complex type |
1.1.56.2. Results:¶
Result |
Description |
|---|---|
|
pointer to integer or floating point type |
1.1.57. cir.complex.sub (::cir::ComplexSubOp)¶
Complex subtraction
Syntax:
operation ::= `cir.complex.sub` $lhs `,` $rhs `:` qualified(type($result)) attr-dict
The cir.complex.sub operation takes two complex numbers and returns
their difference.
Example:
%2 = cir.complex.sub %0, %1 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.57.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR complex type |
|
CIR complex type |
1.1.57.2. Results:¶
Result |
Description |
|---|---|
|
CIR complex type |
1.1.58. 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
condregion of a loop, it continues the loop if true, or exits it if false.When in the
readyregion of acir.await, it branches to theresumeregion when true, and to thesuspendregion when false.
Example:
cir.for cond {
cir.condition(%val) // Branches to `step` region or exits.
} body {
cir.yield
} step {
cir.yield
}
cir.await(user, ready : {
cir.condition(%arg0) // Branches to `resume` or `suspend` region.
}, suspend : {
[...]
}, resume : {
[...]
},)
Traits: Terminator
Interfaces: RegionBranchTerminatorOpInterface
1.1.58.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR bool type |
1.1.59. cir.const (::cir::ConstantOp)¶
Create a CIR constant from a literal attribute
Syntax:
operation ::= `cir.const` $value attr-dict
The cir.const operation turns a literal into an SSA value. The data is
attached to the operation as an attribute.
%0 = cir.const #cir.int<4> : !u32i
%1 = cir.const #cir.fp<1.500000e+00> : !cir.float
%2 = cir.const #cir.ptr<null> : !cir.ptr<!void>
Traits: AlwaysSpeculatableImplTrait, ConstantLike
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.59.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
value | ::mlir::TypedAttr | TypedAttr instance |
1.1.59.2. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.60. cir.construct_catch_param (::cir::ConstructCatchParamOp)¶
Construct a catch parameter from the in-flight exception
Syntax:
operation ::= `cir.construct_catch_param` $kind $eh_token `to` $param_addr `using` ($copy_fn^)? `:`
qualified(type($param_addr)) attr-dict
cir.construct_catch_param abstractly represents the target-specific work
that must be performed before cir.begin_catch to bind the in-flight
exception object to the local alloca used for the catch parameter.
For example: for non-pointer, non-reference catch parameters whose type has
a non-trivial copy constructor, the Itanium C++ ABI requires
calling __cxa_get_exception_ptr to obtain the adjusted exception pointer
and then invoking the catch parameter’s copy constructor to create a local
copy of the object before __cxa_begin_catch is invoked.
This operation takes a !cir.eh_token that represents the in-flight
exception and the alloca value that is used for the local copy of the
exception object. The copy_fn attribute is a flat symbol reference to a
cir.func thunk that copies the exception object to a local alloca value.
This operation is replaced with a target-specific representation during the EHABI lowering pass. For some targets, such as the Microsoft ABI, this operation is a no-op and is simply erased during lowering.
Example:
cir.construct_catch_param non_trivial_copy %eh_token to %param_addr
using @__clang_cir_catch_init_T : !cir.ptr<!rec_T>
Interfaces: SymbolUserOpInterface
1.1.60.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::InitCatchKindAttr | allowed 32-bit signless integer cases: 0, 1, 2, 3, 4, 5 |
copy_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
1.1.60.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR exception handling token type |
|
CIR pointer type |
1.1.61. cir.continue (::cir::ContinueOp)¶
C/C++ continue statement equivalent
Syntax:
operation ::= `cir.continue` attr-dict
The cir.continue operation is used to end execution of the current
iteration of a loop and resume execution beginning at the next iteration.
It is only allowed within loop regions.
Traits: HasAncestor<WhileOp, DoWhileOp, ForOp>, Terminator
1.1.62. cir.copy (::cir::CopyOp)¶
Copies contents from a CIR pointer to another
Syntax:
operation ::= `cir.copy` $src `to` $dst (`volatile` $is_volatile^)?
(`skip_tail_padding` $skip_tail_padding^)?
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 number of bytes copied is inferred from the pointee type. The pointee
type of src and dst must match and both must implement the
DataLayoutTypeInterface.
The volatile keyword indicates that the operation is volatile.
The skip_tail_padding keyword indicates that only the data bytes should
be copied, excluding any tail padding. This is used when copying
potentially-overlapping subobjects where the tail padding might be occupied
by other objects (e.g. fields marked with [[no_unique_address]]). This
is only valid when the pointee type is a record type.
Examples:
// Copying contents from one record to another:
cir.copy %0 to %1 : !cir.ptr<!record_ty>
// Copying without tail padding (for overlapping subobjects):
cir.copy %0 to %1 skip_tail_padding : !cir.ptr<!record_ty>
Traits: SameTypeOperands
Interfaces: PromotableMemOpInterface
1.1.62.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
is_volatile | ::mlir::UnitAttr | unit attribute |
skip_tail_padding | ::mlir::UnitAttr | unit attribute |
1.1.62.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
1.1.63. cir.copysign (::cir::CopysignOp)¶
Copies the sign of a floating-point value
Syntax:
operation ::= `cir.copysign` $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict
cir.copysign returns a value with the magnitude of the first operand
and the sign of the second operand.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.63.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
1.1.63.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.64. cir.coro.body (::cir::CoroBodyOp)¶
Region containing the user-authored coroutine body
Syntax:
operation ::= `cir.coro.body` $body attr-dict
The cir.coro.body operation models the region where the user-authored
coroutine code is emitted.
This operation serves as a structural boundary separating the coroutine setup and teardown logic (e.g. initial suspend, final suspend, and cleanup) from the user-provided statements inside the coroutine.
The body region contains the code corresponding to the original function
body, including co_await and co_return expressions. In particular,
cir.co_return operations inside this region mark coroutine exit points
and introduce structured control flow that transfers execution to the
final suspend point of the coroutine.
Traits: AutomaticAllocationScope, NoRegionArguments, RecursiveMemoryEffects, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.65. cir.cos (::cir::CosOp)¶
Computes the floating-point cosine value
Syntax:
operation ::= `cir.cos` $src `:` type($src) attr-dict
cir.cos computes the cosine of a floating-point operand and returns
a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.65.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.65.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.66. cir.cpuid (::cir::CpuIdOp)¶
Get information about the CPU
Syntax:
operation ::= `cir.cpuid` $cpu_info`,` $function_id`,` $sub_function_id `:`
qualified(type($cpu_info)) `,`
type($function_id) `,`
type($sub_function_id) attr-dict
The cir.cpuid operation retrieves different types of CPU information and
stores it in an array of 4 integers.
This operation takes 3 arguments: cpu_info, a pointer to an array of 4
integers; function_id, an integer determining what type of information to
be retrieved (for instance, basic information, processor information and
features, or cache/TLB information); and sub_function_id, an integer that
adds more detail about what information is requested.
As a result, the array of 4 integers is filled with the requested information.
Example:
cir.cpuid %cpui_info, %function_id, %sub_function_id : (!cir.ptr<!s32i>,
!s32i, !s32i)
1.1.66.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to 32-bit signed integer |
|
32-bit signed integer |
|
32-bit signed integer |
1.1.67. cir.ctz (::cir::BitCtzOp)¶
Get the number of trailing 0-bits in the input
Syntax:
operation ::= `cir.ctz` $input (`poison_zero` $poison_zero^)?
`:` type($result) attr-dict
Compute the number of trailing 0-bits in the input.
The input integer must be an unsigned integer. The cir.ctz operation
counts the number of consecutive 0-bits starting from the least significant
bit.
If the poison_zero attribute is present, this operation will have
undefined behavior if the input value is 0.
Example:
// %0 = 0b1000
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 3
%1 = cir.ctz %0 poison_zero : !u32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.67.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
poison_zero | ::mlir::UnitAttr | unit attribute |
1.1.67.2. Operands:¶
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
1.1.67.3. Results:¶
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
1.1.68. cir.dec (::cir::DecOp)¶
Decrement an integer by one
Syntax:
operation ::= `cir.dec` (`nsw` $no_signed_wrap^)?
$input `:` type($input) attr-dict
The cir.dec operation decrements the operand by one. The operand and
result must have the same type.
The optional nsw (no signed wrap) attribute indicates that the result
is poison if signed overflow occurs.
Example:
%1 = cir.dec %0 : !s32i
%3 = cir.dec nsw %2 : !s32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), UnaryOpInterface
Effects: MemoryEffects::Effect{}
1.1.68.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
1.1.68.2. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.69. cir.delete_array (::cir::DeleteArrayOp)¶
Delete address representing an array
Syntax:
operation ::= `cir.delete_array` $address `:` qualified(type($address)) (`dtor_may_throw` $dtor_may_throw^)?
attr-dict
cir.delete_array operation deletes an array. For example, delete[] ptr;
will be translated to cir.delete_array %ptr.
The delete_fn attribute specifies the operator delete function to call.
The delete_params attribute describes the parameters needed by the
operator delete call.
The element_dtor attribute, when present, specifies the destructor to call
on each array element before deallocation.
The dtor_may_throw unit property, when present, indicates that the
element destructor may throw exceptions.
1.1.69.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
delete_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
delete_params | ::cir::UsualDeleteParamsAttr | Parameters describing the usual operator delete signature |
element_dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
1.1.69.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.70. cir.derived_class_addr (::cir::DerivedClassAddrOp)¶
Get the derived class address for a class/struct
Syntax:
operation ::= `cir.derived_class_addr` $base_addr `:` qualified(type($base_addr))
(`nonnull` $assume_not_null^)?
` ` `[` $offset `]` `->` qualified(type($derived_addr)) attr-dict
The cir.derived_class_addr operaration gets the address of a particular
derived class given a non-virtual base class pointer. The offset in bytes
of the base class must be passed in, similar to cir.base_class_addr, but
going into the other direction. This means lowering to a negative offset.
The operation contains a flag for whether or not the operand may be nullptr. That depends on the context and cannot be known by the operation, and that information affects how the operation is lowered.
The validity of the relationship of derived and base cannot yet be verified. If the target class is not a valid derived class for the object, the behavior is undefined.
Example:
class A {};
class B : public A {};
B *getAsB(A *a) {
return static_cast<B*>(a);
}
leads to
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
%3 = cir.base_class_addr %2 : !cir.ptr<!rec_B> [0] -> !cir.ptr<!rec_A>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.70.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
1.1.70.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.70.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.71. cir.derived_data_member (::cir::DerivedDataMemberOp)¶
Cast a base class data member pointer to a derived class data member pointer
Syntax:
operation ::= `cir.derived_data_member` $src `[` $offset `]` `:` qualified(type($src)) `->` qualified(type($result)) attr-dict
The cir.derived_data_member operation casts a data member pointer of type
T Base::* to a data member pointer of type T Derived::*, where Base
is an accessible non-ambiguous non-virtual base class of Derived.
The offset parameter gives the offset in bytes of the Base base class
subobject within a Derived object.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.71.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
1.1.71.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
1.1.71.3. Results:¶
Result |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
1.1.72. cir.derived_method (::cir::DerivedMethodOp)¶
Cast a base class pointer-to-member-function to a derived class pointer-to-member-function
Syntax:
operation ::= `cir.derived_method` $src `[` $offset `]` `:` qualified(type($src))
`->` qualified(type($result)) attr-dict
The cir.derived_method operation casts a pointer-to-member-function of
type Ret (Base::*)(Args) to a pointer-to-member-function of type
Ret (Derived::*)(Args), where Base is a non-virtual base class of
Derived.
The offset parameter gives the offset in bytes of the Base base class
subobject within a Derived object.
Example:
%1 = cir.derived_method %0 [16] : !cir.method<!cir.func<(!s32i)> in !rec_Base> -> !cir.method<!cir.func<(!s32i)> in !rec_Derived>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.72.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
1.1.72.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
1.1.72.3. Results:¶
Result |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
1.1.73. cir.div (::cir::DivOp)¶
Integer division
Syntax:
operation ::= `cir.div` $lhs `,` $rhs `:` type($lhs) attr-dict
The cir.div operation performs division on integer operands. Both
operands and the result must have the same integer or vector-of-integer
type.
Example:
%0 = cir.div %a, %b : !s32i
%1 = cir.div %a, %b : !u32i
%2 = cir.div %va, %vb : !cir.vector<4 x !s32i>
Traits: SameOperandsAndResultType
Interfaces: BinaryOpInterface, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.73.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
1.1.73.2. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.74. 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
1.1.75. cir.dyn_cast (::cir::DynamicCastOp)¶
Perform dynamic cast on record pointers
Syntax:
operation ::= `cir.dyn_cast` $kind (`relative_layout` $relative_layout^)? $src
`:` qualified(type($src)) `->` qualified(type($result))
(qualified($info)^)? attr-dict
The cir.dyn_cast operation models part of the semantics of the
dynamic_cast operator in C++. It can be used to perform 3 kinds of casts
on record pointers:
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 record pointer. The result of the operation is either a record pointer or a void pointer.
The parameter kind specifies the semantics of this operation. If its value
is ptr, then the operation models dynamic casts on pointers. Otherwise, if
its value is ref, the operation models dynamic casts on references.
Specifically:
When the input pointer is a null pointer value:
If
kindisref, 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
kindisref, the operation will throw abad_castexception.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.
Examples:
%0 = cir.dyn_cast ptr %p : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived>
%1 = cir.dyn_cast ptr relative_layout %p : !cir.ptr<!rec_Base>
-> !cir.ptr<!rec_Derived>
%2 = cir.dyn_cast ref %r : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived>
#cir.dyn_cast_info<
srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>,
destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>,
runtimeFunc = @__dynamic_cast,
badCastFunc = @__cxa_bad_cast,
offsetHint = #cir.int<0> : !s64i
>
1.1.75.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::DynamicCastKindAttr | dynamic cast kind |
info | ::cir::DynamicCastInfoAttr | ABI specific information about a dynamic cast |
relative_layout | ::mlir::UnitAttr | unit attribute |
1.1.75.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to record type |
1.1.75.3. Results:¶
Result |
Description |
|---|---|
|
pointer to any of CIR void type, CIR struct/class type, CIR union type |
1.1.76. cir.eh.dispatch (::cir::EhDispatchOp)¶
Dispatch to exception handlers based on exception type
Syntax:
operation ::= `cir.eh.dispatch` $eh_token `:` type($eh_token)
custom<EhDispatchDestinations>($catch_types, $catch_destinations,
$default_destination, $default_is_catch_all)
attr-dict
cir.eh.dispatch is a terminator operation that dispatches control flow
based on the type of the in-flight exception. It takes an !cir.eh_token
as input and branches to an eh handler block based on the exception type.
The operation contains a list of handlers specified as type-block pairs,
plus either a catch_all handler or an unwind handler, which continues
unwinding if no catch handler matches. Exactly one of catch_all or
unwind must be present.
When the type of the in-flight exception matches a type handler, control
is transfered to the corresponding block with the eh_token as an argument.
The catch_all handler, if present, catches any exception not matched by
another type handler. The unwind handler is used when no handler is
matched.
Example:
cir.eh.dispatch %eh_token : !cir.eh_token [
catch (#cir.global_view<@_ZTIi> : !cir.ptr<!u8i>) : ^catch_int,
catch (#cir.global_view<@_ZTIPKc> : !cir.ptr<!u8i>) : ^catch_str,
catch_all : ^catch_all
]
cir.eh.dispatch %eh_token : !cir.eh_token [
catch (#cir.global_view<type @_ZTIi> : !cir.ptr<!u8i>) : ^catch_int,
unwind : ^continue_unwind
]
Traits: Terminator
1.1.76.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
catch_types | ::mlir::ArrayAttr | array attribute |
default_is_catch_all | ::mlir::UnitAttr | unit attribute |
1.1.76.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR exception handling token type |
1.1.76.3. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
1.1.77. cir.eh.inflight_exception (::cir::EhInflightOp)¶
Materialize the catch clause formal parameter
Syntax:
operation ::= `cir.eh.inflight_exception` (`cleanup` $cleanup^)?
(`catch_all` $catch_all^)?
($catch_type_list^)?
attr-dict
cir.eh.inflight_exception returns two values:
exception_ptr: The exception pointer for the inflight exceptiontype_id: the type info index for the exception type This operation is expected to be the first operation in the unwind destination basic blocks of acir.try_calloperation.
The cleanup attribute indicates that clean up code must be run before the
values produced by this operation are used to dispatch the exception. This
cleanup code must be executed even if the exception is not caught.
This helps CIR to pass down more accurate information for LLVM lowering
to landingpads.
The catch_all attribute indicates that a catch-all handler exists for
the exception being dispatched. When lowered to LLVM IR, this results in
a catch ptr null clause on the landing pad. When catch_all is present
alongside typed catches, the landing pad will contain both the typed catch
clauses and a trailing catch ptr null.
Example:
%exception_ptr, %type_id = cir.eh.inflight_exception
%exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc]
%exception_ptr, %type_id = cir.eh.inflight_exception cleanup
%exception_ptr, %type_id = cir.eh.inflight_exception catch_all [@_ZTIi]
``
Interfaces: `InferTypeOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>cleanup</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>catch_all</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>catch_type_list</code></td><td>::mlir::ArrayAttr</td><td>flat symbol ref array attribute</td></tr>
</table>
#### Results:
| Result | Description |
| :----: | ----------- |
| `exception_ptr` | pointer to void type |
| `type_id` | 32-bit unsigned integer |
### `cir.eh.initiate` (::cir::EhInitiateOp)
_Initiate exception handling in flattened CIR_
Syntax:
operation ::= cir.eh.initiate (cleanup $cleanup^)? : type($eh_token) attr-dict
`cir.eh.initiate` is the first operation in the unwind destination of a
`cir.try_call` operation after CFG flattening. It returns an opaque
`!cir.eh_token` that represents the in-flight exception.
The `cleanup` attribute indicates that cleanup code must be executed before
the exception is dispatched to any handlers. When present, the operation
will be followed by cleanup code before branching to a `cir.eh.dispatch`
operation.
The returned token is passed to `cir.begin_cleanup`, `cir.begin_catch`,
or `cir.eh.dispatch` operations.
Example:
^unwind:
cir.br ^dispatch(%eh_token : !cir.eh_token)
^unwind_with_cleanup:
cir.br ^cleanup(%eh_token : !cir.eh_token)
Interfaces: `InferTypeOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>cleanup</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Results:
| Result | Description |
| :----: | ----------- |
| `eh_token` | CIR exception handling token type |
### `cir.eh.longjmp` (::cir::EhLongjmpOp)
_CIR longjmp operation_
Syntax:
operation ::= cir.eh.longjmp $env : qualified(type($env)) attr-dict
Restore the environment (e.g., stack pointer, instruction pointer,
signal mask, and other registers) at the time of setjmp() call, by using
the information saved in `env` by setjmp().
Examples:
cir.eh.longjmp %arg0 : !cir.ptr<!cir.void>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `env` | CIR pointer type |
### `cir.eh.setjmp` (::cir::EhSetjmpOp)
_CIR setjmp operation_
Syntax:
operation ::= cir.eh.setjmp $env : functional-type($env, results) attr-dict
Saves call-site information (e.g., stack pointer, instruction pointer,
signal mask, and other registers) in memory at `env` for use by longjmp().
In this case, setjmp() returns 0. Following a successful longjmp(),
execution proceeds from cir.eh.setjmp with the operation yielding a
non-zero value.
Examples:
Interfaces: `InferTypeOpInterface`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `env` | CIR pointer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `res` | 32-bit signed integer |
### `cir.eh.terminate` (::cir::EhTerminateOp)
_Terminate due to exception thrown during cleanup_
Syntax:
operation ::= cir.eh.terminate $eh_token : type($eh_token) attr-dict
`cir.eh.terminate` terminates program execution when an exception is thrown
while executing cleanup code during exception unwinding. The C++ standard
requires that `std::terminate()` be called in this scenario.
This operation takes an `!cir.eh_token` from a `cir.eh.initiate` operation
and acts as a terminator. It is produced during CFG flattening when throwing
calls are found in EH cleanup regions.
During EH ABI lowering, this is replaced with target-specific termination
code. For the Itanium ABI, the `cir.eh.initiate` is lowered to
`cir.eh.inflight_exception` (producing an exception pointer), and the
`cir.eh.terminate` becomes a call to `__clang_call_terminate` with that
pointer, followed by an unreachable operation.
Example:
^terminate_unwind:
cir.eh.terminate %eh_token : !cir.eh_token
Traits: `Terminator`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `eh_token` | CIR exception handling token type |
### `cir.eh.typeid` (::cir::EhTypeIdOp)
_Compute exception type id from its global type symbol_
Syntax:
operation ::= cir.eh.typeid $type_sym attr-dict
Returns the exception type id for a given global symbol representing
a type.
Example:
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`, `SymbolUserOpInterface`
Effects: `MemoryEffects::Effect{}`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>type_sym</code></td><td>::mlir::FlatSymbolRefAttr</td><td>flat symbol reference attribute</td></tr>
</table>
#### Results:
| Result | Description |
| :----: | ----------- |
| `type_id` | 32-bit unsigned integer |
### `cir.end_catch` (::cir::EndCatchOp)
_End a catch handler_
Syntax:
operation ::= cir.end_catch $catch_token : type($catch_token) attr-dict
`cir.end_catch` marks the end of a catch handler. It takes the
`!cir.catch_token` returned by the corresponding `cir.begin_catch`
operation.
In the high-level CIR representation, this operation appears inside
the cleanup region of the `cir.cleanup.scope` that follows
`cir.begin_catch` in a catch handler region. In the flattened CIR
representation, it appears at the end of a path that exits the catch
handler.
Example:
// High-level form (inside cir.try catch handler region): } catch [type #cir.global_view<@_ZTIi> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
cir.cleanup.scope { // Handle exception… cir.yield } cleanup eh { cir.end_catch %catch_token : !cir.catch_token cir.yield } }
// Flattened form: ^catch_int(%eh_token : !cir.eh_token):
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!s32i>)
// Handle exception… cir.end_catch %catch_token : !cir.catch_token cir.br ^continue
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `catch_token` | CIR catch token type |
### `cir.end_cleanup` (::cir::EndCleanupOp)
_End a cleanup block during exception unwinding_
Syntax:
operation ::= cir.end_cleanup $cleanup_token : type($cleanup_token) attr-dict
`cir.end_cleanup` marks the end of a cleanup block during exception
unwinding. It takes the `!cir.cleanup_token` returned by the corresponding
`cir.begin_cleanup` operation.
After the cleanup is complete, control typically transfers to either a
catch dispatch block or continues unwinding via `cir.resume`.
Example:
^cleanup(%eh_token : !cir.eh_token):
-> !cir.cleanup_token
cir.call @destructor() : () -> () cir.end_cleanup %cleanup_token : !cir.cleanup_token cir.br ^dispatch(%eh_token : !cir.eh_token)
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `cleanup_token` | CIR cleanup token type |
### `cir.exp` (::cir::ExpOp)
_Computes the floating-point base-e exponential value_
Syntax:
operation ::= cir.exp $src : type($src) attr-dict
`cir.exp` computes the exponential of a floating-point operand and returns
a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.exp2` (::cir::Exp2Op)
_Computes the floating-point base-2 exponential value_
Syntax:
operation ::= cir.exp2 $src : type($src) attr-dict
`cir.exp2` computes the base-2 exponential of a floating-point operand and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.expect` (::cir::ExpectOp)
_Tell the optimizer that two values are likely to be equal._
Syntax:
operation ::= cir.expect ( $val, $expected (, $prob^)? ) : type($val) attr-dict
The `cir.expect` operation may take 2 or 3 arguments.
When the argument `prob` is missing, this operation effectively models the
`__builtin_expect` builtin function. It tells the optimizer that `val` and
`expected` are likely to be equal.
When the argument `prob` is present, this operation effectively models the
`__builtin_expect_with_probability` builtin function. It tells the
optimizer that `val` and `expected` are equal to each other with a certain
probability.
`val` and `expected` must be integers and their types must match.
The result of this operation is always equal to `val`.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>prob</code></td><td>::mlir::FloatAttr</td><td>64-bit float attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `val` | fundamental integer type |
| `expected` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | fundamental integer type |
### `cir.extract_member` (::cir::ExtractMemberOp)
_Extract the value of a member of a record value_
Syntax:
operation ::= cir.extract_member $record [ $index ] attr-dict
: qualified(type($record)) -> qualified(type($result))
The `cir.extract_member` operation extracts the value of a particular member
from the input record. Unlike `cir.get_member` which derives pointers, this
operation operates on values. It takes a value of record type and extracts
the value of the specified record member from the input record value.
Currently `cir.extract_member` does not work on unions.
Example:
// Suppose we have a record with multiple members. !s32i = !cir.int<s, 32> !s8i = !cir.int<s, 32> !record_ty = !cir.record<”struct.Bar” {!s32i, !s8i}>
// And suppose we have a value of the record type.
#cir.int<2> : !s8i}> : !record_ty
// Extract the value of the second member of the record.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>index</code></td><td>::mlir::IntegerAttr</td><td>64-bit signless integer attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `record` | CIR record type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
### `cir.fabs` (::cir::FAbsOp)
_Computes the floating-point absolute value_
Syntax:
operation ::= cir.fabs $src : type($src) attr-dict
`cir.fabs` computes the absolute value of a floating-point operand
and returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fadd` (::cir::FAddOp)
_Floating-point addition_
Syntax:
operation ::= cir.fadd $lhs , $rhs : type($lhs) attr-dict
The `cir.fadd` operation performs floating-point addition on its operands.
Both operands and the result must have the same floating-point scalar or
vector-of-float type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fdiv` (::cir::FDivOp)
_Floating-point division_
Syntax:
operation ::= cir.fdiv $lhs , $rhs : type($lhs) attr-dict
The `cir.fdiv` operation performs floating-point division on its operands.
Both operands and the result must have the same floating-point scalar or
vector-of-float type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.ffs` (::cir::BitFfsOp)
_Get the position of the least significant 1-bit in input_
Syntax:
operation ::= cir.ffs $input : type($result) attr-dict
Compute the 1-based position of the least significant 1-bit of the input.
The input integer must be a signed integer. The `cir.ffs` operation returns
one plus the index of the least significant 1-bit of the input signed
integer. If the input integer is 0, `cir.ffs` yields 0.
Example:
!s32i = !cir.int<s, 32>
// %0 = 0x0010_1000
// #1 will be 4 since the 4th least significant bit is 1.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | signed integer type of widths 32/64 |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | signed integer type of widths 32/64 |
### `cir.floor` (::cir::FloorOp)
_Computes the floating-point floor value_
Syntax:
operation ::= cir.floor $src : type($src) attr-dict
`cir.floor` computes the floor of a floating-point operand and returns
a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Example:
// $x : !cir.double
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fmaximum` (::cir::FMaximumOp)
_Returns the larger of two floating-point values (IEEE 754-2019)_
Syntax:
operation ::= cir.fmaximum $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.fmaximum` returns the larger of its two operands according to
IEEE 754-2019 semantics. If either operand is NaN, NaN is returned.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fmaxnum` (::cir::FMaxNumOp)
_Returns the larger of two floating-point values_
Syntax:
operation ::= cir.fmaxnum $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.fmaxnum` returns the larger of its two operands. If one operand is
NaN, the other operand is returned.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fminimum` (::cir::FMinimumOp)
_Returns the smaller of two floating-point values (IEEE 754-2019)_
Syntax:
operation ::= cir.fminimum $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.fminimum` returns the smaller of its two operands according to
IEEE 754-2019 semantics. If either operand is NaN, NaN is returned.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fminnum` (::cir::FMinNumOp)
_Returns the smaller of two floating-point values_
Syntax:
operation ::= cir.fminnum $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.fminnum` returns the smaller of its two operands. If one operand is
NaN, the other operand is returned.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fmod` (::cir::FModOp)
_Computes the floating-point remainder_
Syntax:
operation ::= cir.fmod $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.fmod` computes the floating-point remainder of dividing the first
operand by the second operand.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fmul` (::cir::FMulOp)
_Floating-point multiplication_
Syntax:
operation ::= cir.fmul $lhs , $rhs : type($lhs) attr-dict
The `cir.fmul` operation performs floating-point multiplication on its
operands. Both operands and the result must have the same floating-point
scalar or vector-of-float type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.fneg` (::cir::FNegOp)
_Floating-point negation_
Syntax:
operation ::= cir.fneg $input : type($input) attr-dict
The `cir.fneg` operation negates the operand. The operand and result must
have the same type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`, `UnaryOpInterface`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point 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.frame_address` (::cir::FrameAddrOp)
_The frame address of the current function, or of one of its callers_
Syntax:
operation ::= cir.frame_address ( $level ) attr-dict : qualified(type($result))
Represents a call to builtin function ` __builtin_frame_address` in CIR.
This builtin function returns the frame address of the current function,
or of one of its callers. The frame is the area on the stack that holds
local variables and saved registers. The frame address is normally the
address of the first word pushed on to the stack by the function.
However, the exact definition depends upon the processor and the calling
convention. If the processor has a dedicated frame pointer register, and
the function has a frame, then __builtin_frame_address returns the value of
the frame pointer register.
The `level` argument is number of frames to scan up the call stack.
For instance, value of 0 yields the frame address of the current function,
value of 1 yields the frame address of the caller of the current function,
and so forth.
Examples:
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `level` | 32-bit unsigned integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR pointer type |
### `cir.frem` (::cir::FRemOp)
_Floating-point remainder_
Syntax:
operation ::= cir.frem $lhs , $rhs : type($lhs) attr-dict
The `cir.frem` operation computes the floating-point remainder of its
operands. Both operands and the result must have the same floating-point
scalar or vector-of-float type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.frexp` (::cir::FrexpOp)
_Decomposes a floating-point value into significand and exponent_
Syntax:
operation ::= cir.frexp $src : type($src) -> type($result) , type($exp) attr-dict
`cir.frexp` splits a floating-point value into a normalized significand
(in the range [0.5, 1.0)) and an integral power-of-two exponent, such
that `src = significand * 2^exp`. Returns both as separate results.
Lowers to `llvm.frexp`.
Example:
%sig, %exp = cir.frexp %x : !cir.float -> !cir.float, !s32i
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
| `exp` | integer type |
### `cir.fsub` (::cir::FSubOp)
_Floating-point subtraction_
Syntax:
operation ::= cir.fsub $lhs , $rhs : type($lhs) attr-dict
The `cir.fsub` operation performs floating-point subtraction on its
operands. Both operands and the result must have the same floating-point
scalar or vector-of-float type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.func` (::cir::FuncOp)
_Declare or define a function_
The `cir.func` operation defines a function, similar to the `mlir::FuncOp`
built-in.
The function linkage information is specified by `linkage`, as defined by
`GlobalLinkageKind` attribute.
The `calling_conv` attribute specifies the calling convention of the function.
By default calling convention is `CallingConv::C`. When printed, C calling
convention is omitted. Other calling conventions are printed as `cc(<mnemonic>)`,
e.g. `cc(amdgpu_kernel)`.
A compiler builtin function must be marked as `builtin` for further
processing when lowering from CIR.
The `coroutine` keyword is used to mark a 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 `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 `global_ctor` keyword indicates whether a function should execute before
`main()` function, as specified by `__attribute__((constructor))`. An
execution priority can also be specified `global_ctor(<priority>)`.
Similarly, for global destructors both `global_dtor` and
`global_dtor(<priority>)` are available.
The `no_inline` attribute marks a function that should not be inlined.
The `always_inline` attribute marks a function that should always be inlined.
The `inline_hint` attribute suggests that the function should be inlined.
The `personality` attribute specifies the personality function to use for
exception handling. This is a symbol reference to the personality function
(e.g., `@__gxx_personality_v0` for C++ exceptions).
Example:
// External function definitions. cir.func @abort()
// A function with internal linkage. cir.func internal @count(%x: i64) -> (i64) return %x : i64
// Linkage information cir.func linkonce_odr @some_method(…)
// Calling convention information cir.func @func1(…) cc(amdgpu_kernel)
// Inline information cir.func no_inline @some_method(…)
// Builtin function
cir.func builtin @__builtin_coro_end(!cir.ptr
Traits: `AutomaticAllocationScope`, `IsolatedFromAbove`
Interfaces: `ArgAndResultAttrsOpInterface`, `CIRGlobalValueInterface`, `CallableOpInterface`, `FunctionOpInterface`, `Symbol`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>sym_name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr>
<tr><td><code>function_type</code></td><td>::mlir::TypeAttr</td><td>type attribute of CIR function type</td></tr>
<tr><td><code>builtin</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>coroutine</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>inline_kind</code></td><td>::cir::InlineKindAttr</td><td>inlineKind</td></tr>
<tr><td><code>lambda</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>no_proto</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>dso_local</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>linkage</code></td><td>::cir::GlobalLinkageKindAttr</td><td>linkage kind</td></tr>
<tr><td><code>calling_conv</code></td><td>::cir::CallingConvAttr</td><td>calling convention</td></tr>
<tr><td><code>sym_visibility</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr>
<tr><td><code>comdat</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>arg_attrs</code></td><td>::mlir::ArrayAttr</td><td>Array of dictionary attributes</td></tr>
<tr><td><code>res_attrs</code></td><td>::mlir::ArrayAttr</td><td>Array of dictionary attributes</td></tr>
<tr><td><code>aliasee</code></td><td>::mlir::FlatSymbolRefAttr</td><td>flat symbol reference attribute</td></tr>
<tr><td><code>side_effect</code></td><td>::cir::SideEffectAttr</td><td>allowed side effects of a function</td></tr>
<tr><td><code>personality</code></td><td>::mlir::FlatSymbolRefAttr</td><td>flat symbol reference attribute</td></tr>
<tr><td><code>global_ctor_priority</code></td><td>::mlir::IntegerAttr</td><td>32-bit signless integer attribute whose minimum value is 101 whose maximum value is 65535</td></tr>
<tr><td><code>global_dtor_priority</code></td><td>::mlir::IntegerAttr</td><td>32-bit signless integer attribute whose minimum value is 101 whose maximum value is 65535</td></tr>
<tr><td><code>cxx_special_member</code></td><td>::mlir::Attribute</td><td>Marks a function as a C++ constructor or Marks a function as a CXX destructor or Marks a function as a CXX assignment operator</td></tr>
<tr><td><code>annotations</code></td><td>::mlir::ArrayAttr</td><td>array of cir.annotation attributes</td></tr>
</table>
### `cir.get_bitfield` (::cir::GetBitfieldOp)
_Get the information for a bitfield member_
Syntax:
operation ::= cir.get_bitfield (align ( $alignment^ ))?
($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.
cir.get_bitfield(#bfi, %0 {is_volatile} : !cir.ptr<!u64i>) -> !s32i
Example:
Suppose we have a struct with multiple bitfields stored in
different members. The `cir.get_bitfield` operation gets the value
of the bitfield.
```C++
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.e;
}
// 'e' is in the storage with the index 1
!cir.record<struct "S" packed padded {!u64i, !u16i, !cir.array<!u8i x 2>}>
#bfi_e = #cir.bitfield_info<name = "e", storage_type = !u16i, size = 15,
offset = 0, is_signed = true>
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type>
%3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type>
-> !cir.ptr<!u16i>
%4 = cir.get_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i
1.1.77.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
bitfield_info | ::cir::BitfieldInfoAttr | Represents info for a bit-field member |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.77.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.77.3. Results:¶
Result |
Description |
|---|---|
|
integer or boolean type |
1.1.78. cir.get_element (::cir::GetElementOp)¶
Get the address of an array element
Syntax:
operation ::= `cir.get_element` $base`[` $index `:` type($index) `]` attr-dict
`:` qualified(type($base)) `->` qualified(type($result))
The cir.get_element operation gets the address of a particular element
from the base array.
It expects a pointer to the base array and the index of the element.
The result pointer preserves the address space of the base pointer.
Example:
// Suppose we have a array.
!s32i = !cir.int<s, 32>
!arr_ty = !cir.array<!s32i x 4>
// Get the address of the element at index 1.
%elem_1 = cir.get_element %0[1 : !s32i] : !cir.ptr<!array_ty> -> !cir.ptr<!s32i>
// Get the address of the element at index %i.
%i = ...
%elem_i = cir.get_element %0[%i : !s32i] : !cir.ptr<!array_ty> -> !cir.ptr<!s32i>
// With address space (e.g., GPU private memory):
%elem_gpu = cir.get_element %gpu_arr[%i : !s32i] :
!cir.ptr<!cir.array<!s32i x 10>, target_address_space(5)> ->
!cir.ptr<!s32i, target_address_space(5)>
Interfaces: InferTypeOpInterface
1.1.78.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to array type |
|
fundamental integer type |
1.1.78.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.79. cir.get_global (::cir::GetGlobalOp)¶
Get the address of a global variable
Syntax:
operation ::= `cir.get_global` (`thread_local` $tls^)?
(`static_local` $static_local^)?
$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. The resulting type must always be a !cir.ptr<...> type with the
same address space as the global variable.
Addresses of thread local globals can only be retrieved if this operation
is marked thread_local, which indicates the address isn’t constant.
The static_local attribute indicates that this global is a function-local
static variable that requires guarded initialization (e.g., C++ static
local variables with non-constant initializers).
Example:
%x = cir.get_global @gv : !cir.ptr<i32>
...
%y = cir.get_global thread_local @tls_gv : !cir.ptr<i32>
...
%w = cir.get_global static_local @func_static : !cir.ptr<i32>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
1.1.79.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
tls | ::mlir::UnitAttr | unit attribute |
static_local | ::mlir::UnitAttr | unit attribute |
1.1.79.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.80. cir.get_member (::cir::GetMemberOp)¶
Get the address of a member of a record
Syntax:
operation ::= `cir.get_member` $addr `[` $index_attr `]` attr-dict
`:` qualified(type($addr)) `->` qualified(type($result))
The cir.get_member operation gets the address of a particular named
member from the input record.
It expects a pointer to the base record as well as the name of the member and its field index.
Example:
// Suppose we have a record with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 8>
!ty_B = !cir.record<"struct.B" {!s32i, !s8i}>
// Get the address of the member at index 1.
%1 = cir.get_member %0[1] {name = "i"} : (!cir.ptr<!ty_B>) -> !cir.ptr<!s8i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.80.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::StringAttr | string attribute |
index_attr | ::mlir::IntegerAttr | index attribute |
1.1.80.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.80.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.81. cir.get_method (::cir::GetMethodOp)¶
Resolve a method to a function pointer as callee
Syntax:
operation ::= `cir.get_method` $method `,` $object
`:` `(` qualified(type($method)) `,` qualified(type($object)) `)`
`->` `(` qualified(type($callee)) `,` qualified(type($adjusted_this)) `)`
attr-dict
The cir.get_method operation takes a pointer to method (!cir.method) and
a pointer to a class object (!cir.ptr<!cir.record>>) as input, and
yields a function pointer that points to the actual function corresponding
to the input method. The operation also applies any necessary adjustments to
the input object pointer for calling the method and yields the adjusted
pointer.
This operation is generated when calling a method through a pointer-to- member-function in C++:
// Foo *object;
// int arg;
// void (Foo::*method)(int);
(object->*method)(arg);
The code above will generate CIR similar to:
%callee, %this = cir.get_method %method, %object
cir.call %callee(%this, %arg)
The method type must match the callee type. That is:
The return type of the method must match the return type of the callee.
The first parameter of the callee must have type
!cir.ptr<!cir.void>.Types of other parameters of the callee must match the method’s parameters after the implicit
thispointer.
1.1.81.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
|
pointer to record type |
1.1.81.2. Results:¶
Result |
Description |
|---|---|
|
pointer to function type |
|
pointer to void type |
1.1.82. cir.get_runtime_member (::cir::GetRuntimeMemberOp)¶
Get the address of a member of a record
Syntax:
operation ::= `cir.get_runtime_member` $addr `[` $member `:` qualified(type($member)) `]` attr-dict
`:` qualified(type($addr)) `->` qualified(type($result))
The cir.get_runtime_member operation gets the address of a member from
the input record. The target member is given by a value of type
!cir.data_member (i.e. a pointer-to-data-member value).
This operation differs from cir.get_member in when the target member can
be determined. For the cir.get_member operation, the target member is
specified as a constant index so the member it returns access to is known
when the operation is constructed. For the cir.get_runtime_member
operation, the target member is given through a pointer-to-data-member
value which is unknown until the program being compiled is executed. In
other words, cir.get_member represents a normal member access through the
. operator in C/C++:
struct Foo { int x; };
Foo f;
(void)f.x; // cir.get_member
And cir.get_runtime_member represents a member access through the .* or
the ->* operator in C++:
struct Foo { int x; }
Foo f;
Foo *p;
int Foo::*member;
(void)f.*member; // cir.get_runtime_member
(void)p->*member; // cir.get_runtime_member
This operation expects a pointer to the base record as well as the pointer to the target member.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.82.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to record type |
|
CIR type that represents a pointer-to-data-member in C++ |
1.1.82.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.83. cir.global (::cir::GlobalOp)¶
Declare or define a global variable
Syntax:
operation ::= `cir.global` ($sym_visibility^)?
($global_visibility^)?
(`constant` $constant^)?
$linkage
(`comdat` $comdat^)?
($tls_model^)?
(`dyn_tls_refs` `=` $dyn_tls_refs^)?
(`dso_local` $dso_local^)?
(`static_local_guard` `` $static_local_guard^)?
(` ` custom<GlobalAddressSpaceValue>($addr_space)^ )?
$sym_name
(`alias` `(` $aliasee^ `)`)?
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value,
$ctorRegion, $dtorRegion)
($annotations^)?
attr-dict
The cir.global operation declares or defines a named global variable.
The backing memory for the variable is allocated statically and is described by the type of the variable.
The 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.
The static_local_guard attribute indicates that this global represents a
function-local static variable that requires guarded initialization
(e.g., C++ static local variables with non-constant initializers).
It contains the mangled name of the guard variable.
Traits: NoRegionArguments
Interfaces: CIRGlobalValueInterface, RegionBranchOpInterface, Symbol
1.1.83.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
sym_visibility | ::mlir::StringAttr | string attribute |
sym_type | ::mlir::TypeAttr | any type attribute |
linkage | ::cir::GlobalLinkageKindAttr | linkage kind |
addr_space | ::mlir::ptr::MemorySpaceAttrInterface | MemorySpaceAttrInterface instance |
tls_model | ::cir::TLS_ModelAttr | TLS model |
dyn_tls_refs | ::cir::ThreadLocalGlobalWrapperInitAttr | Wrapper and Init function names for thread local variables |
initial_value | ::mlir::Attribute | any attribute |
static_local_guard | ::cir::StaticLocalGuardAttr | Guard variable name for static local variables |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
ast | ::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
section | ::mlir::StringAttr | string attribute |
annotations | ::mlir::ArrayAttr | array of cir.annotation attributes |
aliasee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
1.1.84. cir.goto (::cir::GotoOp)¶
Syntax:
operation ::= `cir.goto` $label attr-dict
Transfers control to the specified label. This requires a corresponding
cir.label to exist and is used by to represent source level gotos
that jump across region boundaries. Alternatively, cir.br is used to
construct goto’s that don’t violate such boundaries.
cir.goto is completely symbolic (i.e. it “jumps” on a label that isn’t
yet materialized) and should be taken into account by passes and analysis
when deciding if it’s safe to make some assumptions about a given region
or basic block.
Example:
int test(int x) {
if (x)
goto label;
{
x = 10;
label:
return x;
}
}
cir.scope { // REGION #1
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.cast int_to_bool %2 : !s32i -> !cir.bool
cir.if %3 {
cir.goto "label"
}
}
cir.scope { // REGION #2
%2 = cir.const #cir.int<10> : !s32i
cir.store %2, %0 : !s32i, !cir.ptr<!s32i>
cir.br ^bb1
^bb1: // pred: ^bb0
cir.label "label"
%3 = cir.load %0 : !cir.ptr<!s32i>, !s32i
cir.store %3, %1 : !s32i, !cir.ptr<!s32i>
%4 = cir.load %1 : !cir.ptr<!s32i>, !s32i
cir.return %4 : !s32i
}
cir.unreachable
Traits: Terminator
1.1.84.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
label | ::mlir::StringAttr | string attribute |
1.1.85. 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 %cond {
...
} else {
...
}
cir.if %cond {
...
}
cir.if %cond {
...
cir.br ^a
^a:
cir.yield
}
cir.if defines no values and the ‘else’ can be omitted. The if/else
regions must be terminated. If the region has only one block, the terminator
can be left out, and cir.yield terminator will be inserted implictly.
Otherwise, the region must be explicitly terminated.
Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.85.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR bool type |
1.1.86. cir.inc (::cir::IncOp)¶
Increment an integer by one
Syntax:
operation ::= `cir.inc` (`nsw` $no_signed_wrap^)?
$input `:` type($input) attr-dict
The cir.inc operation increments the operand by one. The operand and
result must have the same type.
The optional nsw (no signed wrap) attribute indicates that the result
is poison if signed overflow occurs.
Example:
%1 = cir.inc %0 : !s32i
%3 = cir.inc nsw %2 : !s32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), UnaryOpInterface
Effects: MemoryEffects::Effect{}
1.1.86.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
1.1.86.2. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.87. cir.indirect_br (::cir::IndirectBrOp)¶
Indirect branch
Syntax:
operation ::= `cir.indirect_br` $addr ( `poison` $poison^ )? `:` qualified(type($addr)) `,`
custom<IndirectBrOpSucessors>(ref(type($addr)),
$successors,
$succ_operands,
type($succ_operands))
attr-dict
The cir.indirectbr operation represents an indirect branch to one of
several possible successor blocks. The target block is computed from
the value of the given address operand.
This operation is typically generated when handling constructs like
the GCC extension &&label combined with an indirect goto *ptr;.
The poison attribute is used to mark an indirectbr that was created
but is known to be invalid, for instance when a label address was
taken but no indirect branch was ever emitted.
Example:
%0 = cir.block_address <@A, "A"> : !cir.ptr<!void>
cir.indirectbr %0 poison : <!void>, [
^bb1
]
Traits: AlwaysSpeculatableImplTrait, SameVariadicOperandSize, Terminator
Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.87.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
poison | ::mlir::UnitAttr | unit attribute |
operand_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
1.1.87.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
variadic of any non-token type |
1.1.87.3. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
1.1.88. cir.init_catch_param (::cir::InitCatchParamOp)¶
Initialize a catch parameter from the exception pointer
Syntax:
operation ::= `cir.init_catch_param` $kind $exn_ptr `to` $param_addr `:`
qualified(type($exn_ptr)) `,` qualified(type($param_addr)) attr-dict
cir.init_catch_param represents copying or otherwise materializing the
caught exception object into the local catch parameter variable. It takes
the exception pointer returned by cir.begin_catch and the address of
the alloca created for the catch parameter, and has no result.
This operation is target-independent. It is replaced during EHABI lowering with the appropriate target/ABI-specific sequence (for example, the Itanium C++ ABI may emit a load and store for scalar/pointer catch types, an aggregate copy for record types, or a call to a copy constructor when one is required).
Example:
%catch_token, %exn_ptr = cir.begin_catch %eh_token
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!void>)
%param_addr = cir.alloca "e" align(4) init : !cir.ptr<!s32i>
cir.init_catch_param %exn_ptr to %param_addr
: !cir.ptr<!void>, !cir.ptr<!s32i>
1.1.88.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::InitCatchKindAttr | allowed 32-bit signless integer cases: 0, 1, 2, 3, 4, 5 |
1.1.88.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
1.1.89. cir.insert_member (::cir::InsertMemberOp)¶
Overwrite the value of a member of a record value
Syntax:
operation ::= `cir.insert_member` $record `[` $index `]` `,` $value attr-dict
`:` qualified(type($record)) `,` qualified(type($value))
The cir.insert_member operation overwrites the value of a particular
member in the input record, and returns the modified record. The result of
this operation is equal to the input record, except for the member specified
by index_attr whose value is equal to the given value.
This operation is named after the LLVM instruction insertvalue.
Currently cir.insert_member does not work on unions.
Example:
// Suppose we have a record with multiple members.
!s32i = !cir.int<s, 32>
!s8i = !cir.int<s, 32>
!record_ty = !cir.record<"struct.Bar" {!s32i, !s8i}>
// And suppose we have a value of the record type.
%0 = cir.const #cir.const_record<{#cir.int<1> : !s32i, #cir.int<2> : !s8i}> : !record_ty
// %0 is {1, 2}
// Overwrite the second member of the record value.
%1 = cir.const #cir.int<3> : !s8i
%2 = cir.insert_member %0[1], %1 : !record_ty, !s8i
// %2 is {1, 3}
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.89.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
index | ::mlir::IntegerAttr | 64-bit signless integer attribute |
1.1.89.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR record type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.89.3. Results:¶
Result |
Description |
|---|---|
|
CIR record type |
1.1.90. cir.is_constant (::cir::IsConstantOp)¶
Test for manifest compile-time constant
Syntax:
operation ::= `cir.is_constant` $val `:` qualified(type($val)) `->` qualified(type($result)) attr-dict
Returns true if the argument is known to be a manifest compile-time
constant otherwise returns false. If the argument is a constant expression
which refers to a global (the address of which is a constant, but not
manifest during the compile), then the intrinsic evaluates to false.
This is used to represent __builtin_constant_p in cases where the argument
isn’t known to be constant during initial translation of the source code but
might be proven to be constant after later optimizations.
Example:
%1 = cir.is_constant %2 : !s32i -> !cir.bool
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.90.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.90.2. Results:¶
Result |
Description |
|---|---|
|
CIR bool type |
1.1.91. cir.is_fp_class (::cir::IsFPClassOp)¶
Corresponding to the __builtin_fpclassify builtin function in clang
Syntax:
operation ::= `cir.is_fp_class` $src `,` $flags `:` functional-type($src, $result) attr-dict
The cir.is_fp_class operation takes a floating-point value as its first
argument and a bitfield of flags as its second argument. The operation
returns a boolean value indicating whether the floating-point value
satisfies the given flags.
The flags must be a compile time constant and the values are:
Bit # |
floating-point class |
|---|---|
0 |
Signaling NaN |
1 |
Quiet NaN |
2 |
Negative infinity |
3 |
Negative normal |
4 |
Negative subnormal |
5 |
Negative zero |
6 |
Positive zero |
7 |
Positive subnormal |
8 |
Positive normal |
9 |
Positive infinity |
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.91.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
flags | ::cir::FPClassTestAttr | floating-point class test flags |
1.1.91.2. Operands:¶
Operand |
Description |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
1.1.91.3. Results:¶
Result |
Description |
|---|---|
|
CIR bool type |
1.1.92. 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
1.1.92.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
label | ::mlir::StringAttr | string attribute |
1.1.93. cir.launder (::cir::LaunderOp)¶
Launder operation
Syntax:
operation ::= `cir.launder` $arg `:` qualified(type($result)) attr-dict
This operation represents a call to ‘launder’ in C++, which acts as an optimization boundary that breaks type invariance.
Example:
%0 = cir.alloca "" align(8) : !cir.ptr<!cir.ptr<!rec_S>>
%1 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
%2 = cir.launder(%1) : !cir.ptr<!rec_S>
Traits: SameOperandsAndResultType
Interfaces: InferTypeOpInterface
1.1.93.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.93.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.94. 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.
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)
Interfaces: InferTypeOpInterface
1.1.94.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
32-bit signed integer |
|
64-bit unsigned integer |
1.1.94.2. Results:¶
Result |
Description |
|---|---|
|
pointer to void type |
1.1.95. 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.
As is the case for memcpy in the C standard library, this operation exhibits undefined behavior (UB) if any of the following conditions hold:
srcand/ordstare null pointers; orthe memory regions referenced by
srcanddstoverlap.
Examples:
// Copying 2 bytes from one array to a record:
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memcpy %2 bytes from %arr to %record : !cir.ptr<!arr> -> !cir.ptr<!record>
1.1.95.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
|
fundamental unsigned integer type |
1.1.96. cir.libc.memmove (::cir::MemMoveOp)¶
Equivalent to libc’s memmove
Syntax:
operation ::= `cir.libc.memmove` $len `bytes` `from` $src `to` $dst attr-dict
`:` qualified(type($dst)) `,` type($len)
Given two CIR pointers, src and dst, cir.libc.memmove will copy len
bytes from the memory pointed by src to the memory pointed by dst.
similiar to cir.libc.memcpy but accounts for overlapping memory.
Examples:
// Copying 2 bytes from one array to a record:
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memmove %2 bytes from %arr to %record : !cir.ptr<!void>, !u64i
1.1.96.1. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
|
fundamental unsigned integer type |
1.1.97. cir.libc.memset (::cir::MemSetOp)¶
Equivalent to libc’s memset
Syntax:
operation ::= `cir.libc.memset` $len `bytes` `at` $dst (`align` `(` $alignment^ `)`)? `to` $val attr-dict
`:` qualified(type($dst)) `,` type($val) `,` type($len)
Given the CIR pointer, dst, cir.libc.memset will set the first len
bytes of the memory pointed by dst to the specified val.
Examples:
// Set 2 bytes in a record to 0:
%len = cir.const #cir.int<2> : !u32i
%zero = cir.const #cir.int<0> : !u8i
cir.libc.memset %len bytes at %record to %zero : !cir.ptr<!void>,
!s32i, !u64i
1.1.97.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
1.1.97.2. Operands:¶
Operand |
Description |
|---|---|
|
pointer to void type |
|
8-bit unsigned integer |
|
fundamental unsigned integer type |
1.1.98. cir.lifetime.end (::cir::LifetimeEndOp)¶
Marks the end of the lifetime of a variable produced by a cir.alloca operation
Syntax:
operation ::= `cir.lifetime.end` $ptr attr-dict `:` qualified(type($ptr))
The cir.lifetime.end operation marks the end of the lifetime of the
storage pointed to by $ptr. After this operation the underlying storage
is considered dead, and the optimizer is free to reuse the storage for
other purposes, until a subsequent cir.lifetime.start on the same
pointer revives it.
The cir.scope is the operation that models the block scope of the C/C++
source. Once ClangIR is no longer structured, cir.scope can no longer express
the lifetime of a local variable. This happens, for example, after FlattenCFG,
where cir.scope regions are dissolved into plain basic blocks, or after
HoistAllocas, where an alloca is moved to the function entry so that its
position no longer reflects the scope it was declared in. In that form, these
lifetime markers are what delimit the beginning and end of a variable’s
lifetime.
The verifier requires $ptr to be produced by a cir.alloca.
cir.lifetime.end should be preceded by a matching cir.lifetime.start on
the same pointer on every control-flow path that reaches it.
This operation corresponds to the LLVM intrinsic llvm.lifetime.end.
Example:
cir.lifetime.end %ptr : !cir.ptr<!s32i>
1.1.98.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.99. cir.lifetime.start (::cir::LifetimeStartOp)¶
Marks the start of the lifetime of a variable produced by a cir.alloca operation
Syntax:
operation ::= `cir.lifetime.start` $ptr attr-dict `:` qualified(type($ptr))
The cir.lifetime.start operation marks the beginning of the lifetime
of the storage pointed to by $ptr. Between this operation and a
matching cir.lifetime.end on the same pointer, the underlying storage
is considered live; outside that range it is considered dead, and the
optimizer is free to reuse the storage for other purposes.
The cir.scope is the operation that models the block scope of the C/C++
source. Once ClangIR is no longer structured, cir.scope can no longer express
the lifetime of a local variable. This happens, for example, after FlattenCFG,
where cir.scope regions are dissolved into plain basic blocks, or after
HoistAllocas, where an alloca is moved to the function entry so that its
position no longer reflects the scope it was declared in. In that form, these
lifetime markers are what delimit the beginning and end of a variable’s
lifetime.
The verifier requires $ptr to be produced by a cir.alloca. For the
lifetime to be meaningful, a matching cir.lifetime.end on the same
pointer should follow on every control-flow path. This is different from
LLVM, where an llvm.lifetime.start may appear without a matching
llvm.lifetime.end – there the storage is also implicitly marked dead
when the function returns (see the
LLVM LangRef).
This operation corresponds to the LLVM intrinsic llvm.lifetime.start.
Example:
cir.lifetime.start %ptr : !cir.ptr<!s32i>
1.1.99.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.100. cir.llrint (::cir::LlrintOp)¶
Rounds floating-point to long long integer using current rounding mode
Syntax:
operation ::= `cir.llrint` $src `:` type($src) `->` type($result) attr-dict
cir.llrint rounds a floating-point value to the nearest integer value
using the current rounding mode and returns the result as a long long.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.100.1. Operands:¶
Operand |
Description |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
1.1.100.2. Results:¶
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
1.1.101. cir.llround (::cir::LlroundOp)¶
Rounds floating-point to long long integer
Syntax:
operation ::= `cir.llround` $src `:` type($src) `->` type($result) attr-dict
cir.llround rounds a floating-point value to the nearest integer value,
rounding halfway cases away from zero, and returns the result as a
long long.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.101.1. Operands:¶
Operand |
Description |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
1.1.101.2. Results:¶
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
1.1.102. cir.load (::cir::LoadOp)¶
Load value from memory adddress
Syntax:
operation ::= `cir.load` (`deref` $isDeref^)?
(`volatile` $is_volatile^)?
(`nontemporal` $is_nontemporal^)?
(`invariant` $invariant^)?
(`align` `(` $alignment^ `)`)?
(`syncscope` `(` $sync_scope^ `)`)?
(`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>).
alignment can be used to specify an alignment that’s different from the
default, which is computed from result’s type ABI data layout.
A unit attribute invariant can be used to indicate that the loaded memory
never changes, mapping to LLVM IR’s !invariant.load metadata.
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
// Perform an invariant load from address in %0.
%5 = cir.load invariant %0 : !cir.ptr<i32>, i32
// Others
%x = cir.load align(16) atomic(seq_cst) %0 : !cir.ptr<i32>, i32
Interfaces: InferTypeOpInterface, PromotableMemOpInterface
1.1.102.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
isDeref | ::mlir::UnitAttr | unit attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
is_nontemporal | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
sync_scope | ::cir::SyncScopeKindAttr | sync scope kind |
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
invariant | ::mlir::UnitAttr | unit attribute |
1.1.102.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.102.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.103. cir.local_init (::cir::LocalInitOp)¶
Initialize a static or thread local object
Syntax:
operation ::= `cir.local_init` (`thread_local` $tls^) : (`static_local`)?
$globalName attr-dict
(`ctor` $ctorRegion^)?
(`dtor` $dtorRegion^)?
The ‘cir.local_init’ operation has no result, but is responsible for containing the regions to initialize and destroy the static local variable. This will be handled during lowering-prepare to include the guard variables correctly for the variable.
This operation may also represent a static local thread local variable, which would be indicated by the ‘tls’ flag.
Example:
// Note: despite this always being static_local, we print it anyway to be
// visually consistent with get_global, and as a 'counter' to 'tls'.
cir.local_init static_local @GlobalName ctor {
%4 = cir.get_global static_local @GlobalName : !cir.ptr<!rec_CtorDtor>
%5 = cir.call @_Z5get_iv() : () -> !s32i
cir.call @_ZN8CtorDtorC1Ei(%4, %5) : !cir.ptr<!rec_CtorDtor>
cir.yield
}, dtor {
%4 = cir.get_global static_local @_ZZ3foovE8localCD2 :
!cir.ptr<!rec_CtorDtor>
cir.call @_ZN8CtorDtorD1Ev(%4) : (!cir.ptr<!rec_CtorDtor>) -> ()
cir.yield
}
Traits: `HasAncestor<FuncOp>`, `NoRegionArguments`
Interfaces: `SymbolUserOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>globalName</code></td><td>::mlir::FlatSymbolRefAttr</td><td>flat symbol reference attribute</td></tr>
</table>
### `cir.log` (::cir::LogOp)
_Computes the floating-point natural logarithm_
Syntax:
operation ::= cir.log $src : type($src) attr-dict
`cir.log` computes the natural logarithm of a floating-point operand and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.log10` (::cir::Log10Op)
_Computes the floating-point base-10 logarithm_
Syntax:
operation ::= cir.log10 $src : type($src) attr-dict
`cir.log10` computes the base-10 logarithm of a floating-point operand and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.log2` (::cir::Log2Op)
_Computes the floating-point base-2 logarithm_
Syntax:
operation ::= cir.log2 $src : type($src) attr-dict
`cir.log2` computes the base-2 logarithm of a floating-point operand and
returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.lrint` (::cir::LrintOp)
_Rounds floating-point to long integer using current rounding mode_
Syntax:
operation ::= cir.lrint $src : type($src) -> type($result) attr-dict
`cir.lrint` rounds a floating-point value to the nearest integer value
using the current rounding mode and returns the result as a `long`.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | Integer type with arbitrary precision up to a fixed limit |
### `cir.lround` (::cir::LroundOp)
_Rounds floating-point to long integer_
Syntax:
operation ::= cir.lround $src : type($src) -> type($result) attr-dict
`cir.lround` rounds a floating-point value to the nearest integer value,
rounding halfway cases away from zero, and returns the result as a `long`.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | Integer type with arbitrary precision up to a fixed limit |
### `cir.max` (::cir::MaxOp)
_Integer maximum_
Syntax:
operation ::= cir.max $lhs , $rhs : type($lhs) attr-dict
The `cir.max` operation computes the maximum of two integer operands.
Both operands and the result must have the same integer type or vector of
integer type.
Example:
Traits: `Commutative`, `Idempotent`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | integer or vector of integer type |
| `rhs` | integer or vector of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of integer type |
### `cir.min` (::cir::MinOp)
_Integer minimum_
Syntax:
operation ::= cir.min $lhs , $rhs : type($lhs) attr-dict
The `cir.min` operation computes the minimum of two integer operands.
Both operands and the result must have the same integer type or vector of
integer type.
Example:
Traits: `Commutative`, `Idempotent`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | integer or vector of integer type |
| `rhs` | integer or vector of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of integer type |
### `cir.minus` (::cir::MinusOp)
_Integer unary minus (negation)_
Syntax:
operation ::= cir.minus (nsw $no_signed_wrap^)?
$input : type($input) attr-dict
The `cir.minus` operation negates the operand. The operand and result
must have the same type.
The optional `nsw` (no signed wrap) attribute indicates that the result
is poison if signed overflow occurs (e.g. negating the minimum signed
integer).
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`, `UnaryOpInterface`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | integer or vector of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of integer type |
### `cir.modf` (::cir::ModfOp)
_Decomposes a floating-point value into fractional and integral parts_
Syntax:
operation ::= cir.modf $src : type($src) -> type($fractional) , type($integral) attr-dict
`cir.modf` splits a floating-point value into its fractional and integral
parts. Both parts have the same sign as the input.
Lowers to `llvm.modf`.
Example:
%frac, %intpart = cir.modf %x : !cir.float -> !cir.float, !cir.float
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `fractional` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
| `integral` | single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
### `cir.mul` (::cir::MulOp)
_Integer multiplication_
Syntax:
operation ::= cir.mul (nsw $no_signed_wrap^)?
(nuw $no_unsigned_wrap^)?
$lhs , $rhs : type($lhs) attr-dict
The `cir.mul` operation performs multiplication on integer operands. Both
operands and the result must have the same integer or vector-of-integer
type.
The optional `nsw` (no signed wrap) and `nuw` (no unsigned wrap) unit
attributes indicate that the result is poison if signed or unsigned
overflow occurs, respectively.
Example:
Traits: `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | integer or vector of integer type |
| `rhs` | integer or vector of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of integer type |
### `cir.mul.overflow` (::cir::MulOverflowOp)
_Integer multiplication with overflow checking_
Syntax:
operation ::= cir.mul.overflow $lhs , $rhs : qualified(type($lhs)) -> qualified(type($result))
attr-dict
`cir.mul.overflow` performs multiplication with overflow checking on
integral operands. See `CIR_BinOpOverflow` for semantics.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `Commutative`, `SameTypeOperands`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### 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 or boolean type |
| `overflow` | CIR bool type |
### `cir.nearbyint` (::cir::NearbyintOp)
_Rounds floating-point value to nearest integer_
Syntax:
operation ::= cir.nearbyint $src : type($src) attr-dict
`cir.nearbyint` rounds a floating-point operand to the nearest integer value
and returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.not` (::cir::NotOp)
_Bitwise NOT / logical NOT_
Syntax:
operation ::= cir.not $input : type($input) attr-dict
The `cir.not` operation performs a bitwise NOT on integer types or a
logical NOT on boolean types. The operand and result must have the same
type.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `Involution`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`, `UnaryOpInterface`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | integer, boolean, or vector of integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer, boolean, or vector of integer |
### `cir.objsize` (::cir::ObjSizeOp)
_Implements the llvm.objsize builtin_
Syntax:
operation ::= cir.objsize (min $min^) : (max)?
(nullunknown $nullunknown^)?
(dynamic $dynamic^)?
$ptr : qualified(type($ptr)) -> qualified(type($result)) attr-dict
The `cir.objsize` operation is designed to provide information to the
optimizer to determine whether a) an operation (like memcpy) will
overflow a buffer that corresponds to an object, or b) that a runtime
check for overflow isn’t necessary. An object in this context means an
allocation of a specific class, structure, array, or other object.
When the `min` attribute is present, the operation returns the minimum
guaranteed accessible size. When absent (max mode), it returns the maximum
possible object size. Corresponds to `llvm.objectsize`'s `min` argument.
The `dynamic` attribute determines if the value should be evaluated at
runtime. Corresponds to `llvm.objectsize`'s `dynamic` argument.
The `nullunknown` attribute controls how null pointers are handled. When
present, null pointers are treated as having unknown size. When absent,
null pointers are treated as having 0 size (in min mode) or -1 size
(in max mode). Corresponds to `llvm.objectsize`'s `nullunknown` argument.
Example:
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>min</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>nullunknown</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
<tr><td><code>dynamic</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `ptr` | CIR pointer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | fundamental integer type |
### `cir.or` (::cir::OrOp)
_Bitwise OR_
Syntax:
operation ::= cir.or $lhs , $rhs : type($lhs) attr-dict
The `cir.or` operation performs a bitwise OR on integer operands.
Both operands and the result must have the same integer type.
Example:
Traits: `Commutative`, `Idempotent`, `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | integer, boolean, or vector of integer |
| `rhs` | integer, boolean, or vector of integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer, boolean, or vector of integer |
### `cir.parity` (::cir::BitParityOp)
_Get the parity of input_
Syntax:
operation ::= cir.parity $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:
// %0 = 0x0110_1000
// %1 will be 1 since there are three 1-bits in %0
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | unsigned integer type of widths 32/64 |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | unsigned integer type of widths 32/64 |
### `cir.popcount` (::cir::BitPopcountOp)
_Get the number of 1-bits in input_
Syntax:
operation ::= cir.popcount $input : type($result) attr-dict
Compute the number of 1-bits in the input.
The input must be an unsigned integer.
Example:
// %0 = 0x0110_1000
// %1 will be 3 since there are 3 1-bits in %0
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | unsigned integer type of widths 8/16/32/64/128 |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | unsigned integer type of widths 8/16/32/64/128 |
### `cir.pow` (::cir::PowOp)
_Computes the power of a floating-point value_
Syntax:
operation ::= cir.pow $lhs , $rhs : qualified(type($lhs)) attr-dict
`cir.pow` computes the first operand raised to the power of the second
operand.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | floating point or vector of floating point type |
| `rhs` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.prefetch` (::cir::PrefetchOp)
_Prefetch operation_
Syntax:
operation ::= cir.prefetch (write $isWrite^) : (read)?
locality ( $locality )
$addr : qualified(type($addr))
attr-dict
The `cir.prefetch` operation is a hint to the code generator to insert a
prefetch instruction if supported; otherwise, it is a noop. Prefetches
have no effect on the behavior of the program but can change its
performance characteristics.
cir.prefetch(%0 : !cir.ptr<!void>) locality(1) write
$locality is a temporal locality specifier ranging from (0) - no locality,
to (3) - extremely local, keep in cache. If $locality is not present, the
default value is 3.
$isWrite specifies whether the prefetch is for a 'read' or 'write'. If
$isWrite is not specified, it means that prefetch is prepared for 'read'.
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>locality</code></td><td>::mlir::IntegerAttr</td><td>32-bit signless integer attribute whose minimum value is 0 whose maximum value is 3</td></tr>
<tr><td><code>isWrite</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `addr` | pointer to void type |
### `cir.ptr_diff` (::cir::PtrDiffOp)
_Pointer subtraction arithmetic_
Syntax:
operation ::= cir.ptr_diff $lhs , $rhs : qualified(type($lhs)) -> qualified(type($result))
attr-dict
The cir.ptr_diff operation computes the difference between two pointers that
have the same element type.
The result reflects the ABI-defined size of the pointed-to type. For example,
subtracting two !cir.ptr<!u64i> values may yield 1, representing an 8-byte
difference. In contrast, for pointers to void or function types, a result of
8 corresponds to an 8-byte difference.
For pointers to types whose size are not aligned with the target data
layout, the size is generally rounded to the next power of 2 bits. For
example, subtracting two !cir.ptr<!s24i> values for the _BitInt(24) type may
yield 1, representing a 4-byte difference (as opposed to a 3-byte
difference).
Example:
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` | fundamental integer type |
### `cir.ptr_stride` (::cir::PtrStrideOp)
_Pointer access with stride_
Syntax:
operation ::= cir.ptr_stride $base, $stride : functional-type(operands, results) attr-dict
The `cir.ptr_stride` operation computes a new pointer from a base pointer
and an integer stride, similar to a single-index `getelementptr` in LLVM IR.
It moves the pointer by `stride * sizeof(element_type)` bytes.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `base` | CIR pointer type |
| `stride` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR pointer type |
### `cir.rem` (::cir::RemOp)
_Integer remainder_
Syntax:
operation ::= cir.rem $lhs , $rhs : type($lhs) attr-dict
The `cir.rem` operation computes the remainder of division on integer
operands. Both operands and the result must have the same integer or
vector-of-integer type.
Example:
Traits: `SameOperandsAndResultType`
Interfaces: `BinaryOpInterface`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | integer or vector of integer type |
| `rhs` | integer or vector of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of integer type |
### `cir.resume` (::cir::ResumeOp)
_Resumes execution after not catching exceptions_
Syntax:
operation ::= cir.resume $eh_token : type($eh_token) attr-dict
The `cir.resume` operation handles an uncaught exception scenario.
Before CFG flattening, this operation is used as the terminator of a
`CatchUnwind` region of `cir.try`, where it receives an `!cir.eh_token`
argument representing the in-flight exception.
During CFG flattening, this operation may temporarily appear inside any
structured CIR operation (scope, loop, switch, etc.) when an inner cleanup
scope is flattened before the enclosing structured op. When the enclosing
op is subsequently flattened, the resume will end up in a `cir.try`
operation or at function level.
After CFG flattening, this operation appears at the function level (inside
`cir.func`) to indicate that the exception should be re-thrown to the
caller after cleanup code has been executed.
Examples:
// Before CFG flattening (in try unwind region) cir.try { cir.yield } unwind (%eh_token : !cir.eh_token) { cir.resume %eh_token : !cir.eh_token }
// After CFG flattening (at function level, after cleanup) ^eh_cleanup(%eh_token : !cir.eh_token):
cir.call @destructor() : () -> () cir.end_cleanup %ct : !cir.cleanup_token cir.resume %eh_token : !cir.eh_token
Traits: `Terminator`
Interfaces: `RegionBranchTerminatorOpInterface`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `eh_token` | CIR exception handling token type |
### `cir.resume.flat` (::cir::ResumeFlatOp)
_A flattened version of `cir.resume`_
Syntax:
operation ::= cir.resume.flat $exception_ptr , $type_id
attr-dict
The `cir.resume.flat` operation is a region-less and simplified
version of the `cir.resume`.
Its representation is closer to LLVM IR dialect
than the C/C++ language feature.
This operation is used only after the CFG flatterning pass.
Examples:
cir.resume.flat %exception_ptr, %type_id
Traits: `ReturnLike`, `Terminator`
Interfaces: `RegionBranchTerminatorOpInterface`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `exception_ptr` | pointer to void type |
| `type_id` | 32-bit unsigned integer |
### `cir.return` (::cir::ReturnOp)
_Return from function_
Syntax:
operation ::= cir.return ($input^ : type($input))? attr-dict
The "return" operation represents a return operation within a function.
The operation takes an optional operand and produces no results.
The operand type must match the signature of the function that contains
the operation.
func @foo() -> i32 { … cir.return %0 : i32 }
Traits: `HasParent<FuncOp, ScopeOp, IfOp, SwitchOp, CaseOp, CleanupScopeOp, DoWhileOp, WhileOp, ForOp, TryOp>`, `Terminator`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
### `cir.return_address` (::cir::ReturnAddrOp)
_The return address of the current function, or of one of its callers_
Syntax:
operation ::= cir.return_address ( $level ) attr-dict
Represents a call to builtin function ` __builtin_return_address` in CIR.
This builtin function returns the return address of the current function,
or of one of its callers.
The `level` argument is number of frames to scan up the call stack.
For instance, value of 0 yields the return address of the current function,
value of 1 yields the return address of the caller of the current function,
and so forth.
Examples:
Interfaces: `InferTypeOpInterface`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `level` | 32-bit unsigned integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | pointer to void type |
### `cir.rint` (::cir::RintOp)
_Rounds floating-point value to nearest integer_
Syntax:
operation ::= cir.rint $src : type($src) attr-dict
`cir.rint` rounds a floating-point operand to the nearest integer value
and returns a result of the same type.
This operation does not set `errno`. Unlike `cir.nearbyint`, this operation
may raise the `FE_INEXACT` exception if the input value is not an exact
integer, but this is not guaranteed to happen.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.rotate` (::cir::RotateOp)
_Rotate the bits in the operand integer_
Syntax:
operation ::= cir.rotate (left $rotateLeft^) : (right)?
$input , $amount : type($result) attr-dict
The `cir.rotate` rotates the bits in `input` by the given amount `amount`.
The rotate direction is specified by the `left` and `right` keyword.
`input` must be an unsigned integer and its width must be either 8, 16, 32,
or 64. The types of `input`, `amount`, and the result must all match.
Example:
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>rotateLeft</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `input` | unsigned integer type of widths 8/16/32/64 |
| `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.round` (::cir::RoundOp)
_Rounds floating-point value to nearest integer_
Syntax:
operation ::= cir.round $src : type($src) attr-dict
`cir.round` rounds a floating-point operand to the nearest integer value
and returns a result of the same type.
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.roundeven` (::cir::RoundEvenOp)
_Rounds floating-point value to nearest integer, ties to even_
Syntax:
operation ::= cir.roundeven $src : type($src) attr-dict
`cir.roundeven` rounds a floating-point operand to the nearest integer
value, with ties rounding to even (banker's rounding).
Floating-point exceptions are ignored, and it does not set `errno`.
Traits: `AlwaysSpeculatableImplTrait`, `SameOperandsAndResultType`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `src` | floating point or vector of floating point type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | floating point or vector of floating point type |
### `cir.scope` (::cir::ScopeOp)
_Represents a C/C++ scope_
Syntax:
operation ::= cir.scope custom: 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`:
… cir.yield %value }
The blocks can be terminated by `cir.yield`, `cir.return` or `cir.throw`.
If `cir.scope` yields no value, the `cir.yield` can be left out, and
will be inserted implicitly.
Traits: `AutomaticAllocationScope`, `NoRegionArguments`, `RecursiveMemoryEffects`, `RecursivelySpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `RegionBranchOpInterface`
#### Results:
| Result | Description |
| :----: | ----------- |
| `results` | CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
### `cir.select` (::cir::SelectOp)
_Yield one of two values based on a boolean value_
Syntax:
operation ::= cir.select if $condition then $true_value else $false_value
: (
qualified(type($condition)) ,
qualified(type($true_value)) ,
qualified(type($false_value))
) -> qualified(type($result)) attr-dict
The `cir.select` operation takes three operands. The first operand
`condition` is either a boolean value of type `!cir.bool` or a boolean
vector of type `!cir.bool`. The second and the third operand can be of
any CIR types, but their types must be the same. If the first operand
is `true`, the operation yields its second operand. Otherwise, the
operation yields its third operand.
In the case where the first operand is a boolean vector, then the second
and third operand needs to also be of some vectors of the same type to
each other and that the number of elements of all three operands needs to
be the same as well.
Example:
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `condition` | CIR bool type or vector of CIR bool type |
| `true_value` | CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
| `false_value` | CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
### `cir.set_bitfield` (::cir::SetBitfieldOp)
_Set the value of a bitfield member_
Syntax:
operation ::= cir.set_bitfield (align ( $alignment^ ))?
($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.
A bitfield info attribute must be provided to describe the location of
the bitfield within the memory referenced by the $addr argument.
The $src argument is inserted at the appropriate place in the memory and
the value that was stored. Returns the value being stored.
A unit attribute `volatile` can be used to indicate a volatile store of the
bitfield.
cir.set_bitfield(#bfi, %0 : !cir.ptr<!u32i>, %1 : !s32i) {is_volatile}
-> !s32i
Example.
Suppose we have a struct with multiple bitfields stored in
different storages. The `cir.set_bitfield` operation sets the value
of the bitfield.
```C++
typedef struct {
int a : 4;
int b : 27;
int c : 17;
int d : 2;
int e : 15;
} S;
void store_bitfield(S& s) {
s.e = 3;
}
// 'e' is in the storage with the index 1
!record_type = !cir.record<struct "S" packed padded {!u64i, !u16i,
!cir.array<!u8i x 2>} #cir.record.decl.ast>
#bfi_e = #cir.bitfield_info<name = "e", storage_type = !u16i, size = 15,
offset = 0, is_signed = true>
%1 = cir.const #cir.int<3> : !s32i
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type>
%3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type>
-> !cir.ptr<!u16i>
%4 = cir.set_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i)
-> !s32i
1.1.103.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
bitfield_info | ::cir::BitfieldInfoAttr | Represents info for a bit-field member |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
1.1.103.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.103.3. Results:¶
Result |
Description |
|---|---|
|
integer or boolean type |
1.1.104. cir.shift (::cir::ShiftOp)¶
Shift
Syntax:
operation ::= `cir.shift` `(`
(`left` $isShiftleft^) : (```right`)?
`,` $value `:` type($value)
`,` $amount `:` type($amount)
`)` `->` type($result) attr-dict
The cir.shift operation performs a bitwise shift, either to the left or to
the right, based on the first operand. The second operand specifies the
value to be shifted, and the third operand determines the number of
positions by which the shift is applied, They must be either all vector of
integer type, or all integer type. If they are vectors, each vector element of
the shift target is shifted by the corresponding shift amount in
the shift amount vector.
%res = cir.shift(left, %lhs : !u64i, %amount : !s32i) -> !u64i
%new_vec = cir.shift(left, %lhs : !cir.vector<2 x !s32i>, %rhs :
!cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.104.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
isShiftleft | ::mlir::UnitAttr | unit attribute |
1.1.104.2. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
1.1.104.3. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.105. cir.signbit (::cir::SignBitOp)¶
Checks the sign of a floating-point number
Syntax:
operation ::= `cir.signbit` $input attr-dict `:` type($input) `->` qualified(type($res))
It returns whether the sign bit (i.e. the highest bit) of the input operand is set.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.105.1. Operands:¶
Operand |
Description |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
1.1.105.2. Results:¶
Result |
Description |
|---|---|
|
CIR bool type |
1.1.106. cir.sin (::cir::SinOp)¶
Computes the floating-point sine
Syntax:
operation ::= `cir.sin` $src `:` type($src) attr-dict
cir.sin computes the sine of a floating-point operand and returns
a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.106.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.106.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.107. cir.sqrt (::cir::SqrtOp)¶
Floating-point square root operation
Syntax:
operation ::= `cir.sqrt` $src `:` type($src) attr-dict
Computes the square root of a floating-point value or vector.
The input must be either: • a floating-point scalar type, or • a vector whose element type is floating-point.
The result type must match the input type exactly.
Examples: // scalar
// vector
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.107.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.107.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.108. cir.stackrestore (::cir::StackRestoreOp)¶
Restores the state of the function stack
Syntax:
operation ::= `cir.stackrestore` $ptr attr-dict `:` qualified(type($ptr))
Restore the state of the function stack to the state it was in when the corresponding cir.stacksave executed. This is used during the lowering of variable length array allocas.
This operation corresponds to LLVM intrinsic stackrestore.
%0 = cir.alloca "saved_stack" align(8) : !cir.ptr<!cir.ptr<!u8i>>
%1 = cir.stacksave : <!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.stackrestore %2 : !cir.ptr<!u8i>
1.1.108.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.109. cir.stacksave (::cir::StackSaveOp)¶
Remembers the current state of the function stack
Syntax:
operation ::= `cir.stacksave` attr-dict `:` qualified(type($result))
Saves current state of the function stack. Returns a pointer to an opaque object that later can be passed into cir.stackrestore. This is used during the lowering of variable length array allocas.
This operation corresponds to LLVM intrinsic stacksave.
%0 = cir.stacksave : <!u8i>
1.1.109.1. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.110. cir.store (::cir::StoreOp)¶
Store value to memory address
Syntax:
operation ::= `cir.store` (`volatile` $is_volatile^)?
(`nontemporal` $is_nontemporal^)?
(`align` `(` $alignment^ `)`)?
(`syncscope` `(` $sync_scope^ `)`)?
(`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>).
alignment can be used to specify an alignment that’s different from the
default, which is computed from result’s type ABI data layout.
Example:
// Store a function argument to local storage, address in %0.
cir.store %arg0, %0 : i32, !cir.ptr<i32>
// Perform a volatile store into memory location at the address in %0.
cir.store volatile %arg0, %0 : i32, !cir.ptr<i32>
// Others
cir.store align(16) atomic(seq_cst) %x, %addr : i32, !cir.ptr<i32>
Interfaces: PromotableMemOpInterface
1.1.110.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
is_volatile | ::mlir::UnitAttr | unit attribute |
is_nontemporal | ::mlir::UnitAttr | unit attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
sync_scope | ::cir::SyncScopeKindAttr | sync scope kind |
mem_order | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
1.1.110.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
|
CIR pointer type |
1.1.111. cir.sub (::cir::SubOp)¶
Integer subtraction
Syntax:
operation ::= `cir.sub` (`nsw` $no_signed_wrap^)?
(`nuw` $no_unsigned_wrap^)?
(`sat` $saturated^)?
$lhs `,` $rhs `:` type($lhs) attr-dict
The cir.sub operation performs subtraction on integer operands. Both
operands and the result must have the same integer or vector-of-integer
type.
The optional nsw (no signed wrap) and nuw (no unsigned wrap) unit
attributes indicate that the result is poison if signed or unsigned
overflow occurs, respectively. The optional sat (saturated) attribute
clamps the result to the type’s representable range. The nsw/nuw
flags and sat are mutually exclusive.
Example:
%0 = cir.sub %a, %b : !s32i
%1 = cir.sub nsw %a, %b : !s32i
%2 = cir.sub sat %a, %b : !s32i
%3 = cir.sub %va, %vb : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.111.1. Operands:¶
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
1.1.111.2. Results:¶
Result |
Description |
|---|---|
|
integer or vector of integer type |
1.1.112. cir.sub.overflow (::cir::SubOverflowOp)¶
Integer subtraction with overflow checking
Syntax:
operation ::= `cir.sub.overflow` $lhs `,` $rhs `:` qualified(type($lhs)) `->` qualified(type($result))
attr-dict
cir.sub.overflow performs subtraction with overflow checking on integral
operands. See CIR_BinOpOverflow for semantics.
Example:
%result, %overflow = cir.sub.overflow %a, %b : !u32i -> !u32i
Traits: AlwaysSpeculatableImplTrait, SameTypeOperands
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.112.1. Operands:¶
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
|
Integer type with arbitrary precision up to a fixed limit |
1.1.112.2. Results:¶
Result |
Description |
|---|---|
|
integer or boolean type |
|
CIR bool type |
1.1.113. cir.switch (::cir::SwitchOp)¶
Switch operation
Syntax:
operation ::= `cir.switch` `(` $condition `:` qualified(type($condition)) `)`
(`all_enum_cases_covered` $all_enum_cases_covered^)?
$body
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.
Besides taking an integer condition and CIR regions, it also accepts an
all_enum_cases_covered attribute indicating whether all enum cases are
handled by the operation. Note that the presence of a default CaseOp does
not imply all_enum_cases_covered. The original AST switch must explicitly list
every enum case.
The set of cir.case operations and their enclosing cir.switch
represent the semantics of a C/C++ switch statement. Users can use
collectCases(llvm::SmallVector<CaseOp> &cases) to collect the cir.case
operation in the cir.switch operation easily.
The cir.case operations don’t have to be in the region of cir.switch
directly. However, when all the cir.case operations live in the region
of cir.switch directly and there are no other operations except the ending
cir.yield operation in the region of cir.switch directly, we say the
cir.switch operation is in a simple form. Users can use
bool isSimpleForm(llvm::SmallVector<CaseOp> &cases) member function to
detect if the cir.switch operation is in a simple form. The simple form
makes it easier for analyses to handle the cir.switch operation
and makes the boundary to give up clear.
To make the simple form as common as possible, CIR code generation attaches
operations corresponding to the statements that lives between top level
cases into the closest cir.case operation.
For example,
switch(int cond) {
case 4:
a++;
b++;
case 5:
c++;
...
}
The statement b++ is not a sub-statement of the case statement case 4.
But to make the generated cir.switch a simple form, we will attach the
statement b++ into the closest cir.case operation. So that the generated
code will be like:
cir.switch(int cond) {
cir.case(equal, 4) {
a++;
b++;
cir.yield
}
cir.case(equal, 5) {
c++;
cir.yield
}
...
}
For the same reason, we will hoist the case statement as the substatement of another case statement so that they will be in the same level. For example,
switch(int cond) {
case 4:
default;
case 5:
a++;
...
}
will be generated as
cir.switch(int cond) {
cir.case(equal, 4) {
cir.yield
}
cir.case(default) {
cir.yield
}
cir.case(equal, 5) {
a++;
cir.yield
}
...
}
The cir.switch is not be considered “simple” if any of the following is true:
There are case statements of the switch statement that are scope other than the top level compound statement scope. Note that a case statement itself doesn’t form a scope.
The sub-statement of the switch statement is not a compound statement.
There is any code before the first case statement. For example,
switch(int cond) {
l:
b++;
case 4:
a++;
break;
case 5:
goto l;
...
}
the generated CIR for this non-simple switch would be:
cir.switch(int cond) {
cir.label "l"
b++;
cir.case(4) {
a++;
cir.break
}
cir.case(5) {
goto "l"
}
cir.yield
}
Traits: AutomaticAllocationScope, NoRegionArguments, RecursiveMemoryEffects, RecursivelySpeculatableImplTrait, SameVariadicOperandSize
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.113.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
all_enum_cases_covered | ::mlir::UnitAttr | unit attribute |
1.1.113.2. Operands:¶
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
1.1.114. cir.switch.flat (::cir::SwitchFlatOp)¶
A flattened version of cir.switch
Syntax:
operation ::= `cir.switch.flat` $condition `:` type($condition) `,`
$defaultDestination (`(` $defaultOperands^ `:` type($defaultOperands) `)`)?
custom<SwitchFlatOpCases>(ref(type($condition)), $caseValues,
$caseDestinations, $caseOperands,
type($caseOperands))
attr-dict
The cir.switch.flat operation is a region-less and simplified
version of the cir.switch.
Its representation is closer to LLVM IR dialect
than the C/C++ language feature.
Traits: AttrSizedOperandSegments, Terminator
1.1.114.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
caseValues | ::mlir::ArrayAttr | array attribute |
case_operand_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
1.1.114.2. Operands:¶
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
|
variadic of any non-token type |
|
variadic of any non-token type |
1.1.114.3. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
1.1.115. cir.tan (::cir::TanOp)¶
Computes the floating-point tangent
Syntax:
operation ::= `cir.tan` $src `:` type($src) attr-dict
cir.tan computes the tangent of a floating-point operand and returns
a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.115.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.115.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.116. 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. The 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.
cir.ternary also represents the GNU binary conditional operator ?: which
reuses the parent operation for both the condition and the true branch to
evaluate it only once.
Example:
// 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
1.1.116.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR bool type |
1.1.116.2. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.117. cir.throw (::cir::ThrowOp)¶
(Re)Throws an exception
Syntax:
operation ::= `cir.throw` ($exception_ptr^ `:` type($exception_ptr))?
(`,` $type_info^)?
(`,` $dtor^)?
attr-dict
This operation is equivalent to either __cxa_throw or __cxa_rethrow, depending on the arguments.
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.alloc_exception) and finally an optional dtor, which might run as
part of this operation.
Example:
// re-throw;
cir.throw
// if (b == 0)
// throw "Division by zero condition!";
// Type info for char const*
cir.global "private" constant external @_ZTIPKc : !cir.ptr<!u8i>
cir.if %cond {
%exception_addr = cir.alloc_exception 8 -> !cir.ptr<!void>
...
// Store string addr for "Division by zero condition!"
cir.store %string_addr, %exception_addr : !cir.ptr<!s8i>,
!cir.ptr<!cir.ptr<!s8i>>
cir.throw %exception_addr : !cir.ptr<!cir.ptr<!u8i>>,
@_ZTIPKc
1.1.117.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
type_info | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
1.1.117.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.118. 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
1.1.119. cir.trunc (::cir::TruncOp)¶
Truncates floating-point value to integer
Syntax:
operation ::= `cir.trunc` $src `:` type($src) attr-dict
cir.trunc truncates a floating-point operand to an integer value
and returns a result of the same type.
Floating-point exceptions are ignored, and it does not set errno.
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.119.1. Operands:¶
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.119.2. Results:¶
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
1.1.120. cir.try (::cir::TryOp)¶
C++ try block
Syntax:
operation ::= `cir.try` (`cleanup` $cleanup^)?
$try_region
custom<TryHandlerRegions>($handler_regions, $handler_types)
attr-dict
Holds the lexical scope of try {}. Note that resources used on catch
clauses are usually allocated in the same parent as cir.try.
cleanup: indicates that there are cleanups that must be performed
when exiting the try region via exception, even if the exception is not
caught.
Each catch handler region and unwind region receives a !cir.eh_token
argument representing the inflight exception. The first operation in a
catch handler region must be a cir.begin_catch operation. This must
be followed by a cir.cleanup.scope operation, with the cir.end_catch
operation in its cleanup region. The catch handling code will be emitted
into the body of the cleanup scope. This ensures that all paths out of the
catch handler will execute the end_catch operation.
Example:
cir.try {
cir.call exception @function() : () -> ()
cir.yield
} catch [type #cir.global_view<@_ZTIPf> : !cir.ptr<!u8i>] (%eh_token : !cir.eh_token) {
%catch_token, %exn_ptr = cir.begin_catch %eh_token
: !cir.eh_token -> (!cir.catch_token, !cir.ptr<!cir.float>)
cir.cleanup.scope {
...
cir.yield
} cleanup eh {
cir.end_catch %catch_token : !cir.catch_token
cir.yield
}
cir.yield
} unwind (%eh_token : !cir.eh_token) {
cir.resume %eh_token : !cir.eh_token
}
Traits: AutomaticAllocationScope, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
1.1.120.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
cleanup | ::mlir::UnitAttr | unit attribute |
handler_types | ::mlir::ArrayAttr | catch all or unwind or global view array attribute |
1.1.121. cir.try_call (::cir::TryCallOp)¶
Try_call operation
Similar to cir.call but requires two destination blocks,
one which is used if the call returns without throwing an
exception (the “normal” destination) and another which is used
if an exception is thrown (the “unwind” destination).
This operation is used only after the CFG flatterning pass.
Example:
// Before CFG flattening
cir.try {
%call = cir.call @division(%a, %b) : () -> !s32i
cir.yield
} catch all {
cir.yield
}
// After CFG flattening
%call = cir.try_call @division(%a, %b) ^normalDest, ^unwindDest
: (f32, f32) -> f32
^normalDest:
cir.br ^afterTryBlock
^unwindDest:
%exception_ptr, %type_id = cir.eh.inflight_exception
cir.br ^catchHandlerBlock(%exception_ptr : !cir.ptr<!void>)
^catchHandlerBlock:
...
Traits: Terminator
Interfaces: ArgAndResultAttrsOpInterface, CIRCallOpInterface, CallOpInterface, SymbolUserOpInterface
1.1.121.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
nothrow | ::mlir::UnitAttr | unit attribute |
musttail | ::mlir::UnitAttr | unit attribute |
side_effect | ::cir::SideEffectAttr | allowed side effects of a function |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
1.1.121.2. Operands:¶
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.121.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.121.4. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
1.1.122. cir.try_throw (::cir::TryThrowOp)¶
Throw an exception with an unwind destination
Syntax:
operation ::= `cir.try_throw` ($exception_ptr^ `:` type($exception_ptr))?
(`,` $type_info^)?
(`,` $dtor^)?
$normalDest `,` $unwindDest
attr-dict
Similar to cir.throw but acts as a terminator with two destination
blocks: a normalDest that should contain a cir.unreachable
operation (since a throw never returns) and an unwindDest that
receives control when the throw needs to unwind through an enclosing
cleanup or catch handler. This is the EH counterpart of cir.throw,
analogous to how cir.try_call is the EH counterpart of cir.call.
Like cir.throw, the absence of operands means rethrow. With operands,
it carries the same exception pointer, type info, and optional
destructor as cir.throw.
This operation is produced by the FlattenCFG pass for cir.throw
operations that appear inside a cleanup scope or try region. It is
later lowered by the EHABI lowering pass to a cir.try_call of
__cxa_throw (or __cxa_rethrow).
Example:
cir.try_throw %exception_addr : !cir.ptr<!s32i>, @_ZTIi
^normalDest, ^unwindDest
^normalDest:
cir.unreachable
^unwindDest:
...
Traits: Terminator
1.1.122.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
type_info | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
1.1.122.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.122.3. Successors:¶
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
1.1.123. 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
1.1.124. 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)
The cir.va_arg operation models the C/C++ va_arg macro by reading the
next argument from an active variable argument list and producing it as a
value of a specified result type.
The operand must be a pointer to the target’s va_list representation.
The operation advances the va_list state as a side effect and returns
the fetched value as the result, whose type is chosen by the user of the
operation.
A cir.va_arg must only be used on a va_list that has been initialized
with cir.va.start and not yet finalized by cir.va.end. The semantics
(including alignment and promotion rules) follow the platform ABI; the
frontend is responsible for providing a va_list pointer that matches the
target representation.
Example:
// %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
%p = cir.cast array_to_ptrdecay %args
: !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
-> !cir.ptr<!rec___va_list_tag>
cir.va.start %p : !cir.ptr<!rec___va_list_tag>
// Fetch an `int` from the vararg list.
%v = cir.va_arg %p : (!cir.ptr<!rec___va_list_tag>) -> !s32i
cir.va.end %p : !cir.ptr<!rec___va_list_tag>
1.1.124.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.124.2. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.125. cir.va_copy (::cir::VACopyOp)¶
Copied a variable argument list
Syntax:
operation ::= `cir.va_copy` $src_list `to` $dst_list attr-dict `:` type(operands)
The cir.copy operation models the C/C++ va_copy macro.
The variable argument list passed as the $src_list is copied to an
unitialized va_list in the destination operand. The next argument that
can be extracted from the copied list is the same as the next argument in
the source list. The copied list must be destroyed with va_end.
Example:
// %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
%p = cir.cast array_to_ptrdecay %args
: !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
-> !cir.ptr<!rec___va_list_tag>
cir.va_copy %p to %dst
: (!cir.ptr<!rec___va_list_tag>, !cir.ptr<!rec___va_list_tag>)
1.1.125.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
1.1.126. cir.va_end (::cir::VAEndOp)¶
Ends a variable argument list
Syntax:
operation ::= `cir.va_end` $arg_list attr-dict `:` type(operands)
The cir.va_end operation models the C/C++ va_end macro by finalizing
and cleaning up a variable argument list previously initialized with
cir.va_start.
The operand must be a pointer to the target’s va_list representation.
This operation has no results and produces its effect by mutating the
storage referenced by the pointer operand.
cir.va_end must only be called after a matching cir.va_start on the
same va_list along all control-flow paths. After cir.va_end, the
va_list is invalid and must not be accessed unless reinitialized.
Lowering typically maps this to the LLVM intrinsic llvm.va_end,
passing the appropriately decayed pointer to the underlying va_list
storage.
Example:
// %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
%p = cir.cast array_to_ptrdecay %args
: !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
-> !cir.ptr<!rec___va_list_tag>
cir.va_end %p : !cir.ptr<!rec___va_list_tag>
1.1.126.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.127. cir.va_start (::cir::VAStartOp)¶
Starts a variable argument list
Syntax:
operation ::= `cir.va_start` $arg_list attr-dict `:` type(operands)
The cir.va_start operation models the C/C++ va_start macro by initializing a variable argument list at the given va_list storage location.
The operand must be a pointer to the target’s va_list representation.
This operation has no results and produces its effect by mutating the
storage referenced by the pointer operand.
Each cir.va_start must be paired with a corresponding cir.va_end
on the same logical va_list object along all control-flow paths. After
cir.va_end, the va_list must not be accessed unless reinitialized
with another cir.va_start.
Lowering maps this to the LLVM intrinsic llvm.va_start, passing the
appropriately decayed pointer to the underlying va_list storage.
Example:
// %args : !cir.ptr<!cir.array<!rec___va_list_tag x 1>>
%p = cir.cast array_to_ptrdecay %args
: !cir.ptr<!cir.array<!rec___va_list_tag x 1>>)
-> !cir.ptr<!rec___va_list_tag>
cir.va_start %p : !cir.ptr<!rec___va_list_tag>
1.1.127.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.128. 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.
%eq = cir.vec.cmp(eq, %vec_a, %vec_b) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>
%lt = cir.vec.cmp(lt, %vec_a, %vec_b) : !cir.vector<4 x !s32i>, !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameTypeOperands
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.128.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CmpOpKindAttr | compare operation kind |
1.1.128.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR vector type |
|
CIR vector type |
1.1.128.3. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.129. 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{}
1.1.129.1. Operands:¶
Operand |
Description |
|---|---|
|
variadic of any cir boolean, integer, floating point or pointer type |
1.1.129.2. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.130. 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.
%tmp = cir.load %vec : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
%idx = cir.const #cir.int<1> : !s32i
%element = cir.vec.extract %tmp[%idx : !s32i] : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.130.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR vector type |
|
fundamental integer type |
1.1.130.2. Results:¶
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point or pointer type |
1.1.131. 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 produces a new vector by replacing
the element of the input vector at index with value.
%value = cir.const #cir.int<5> : !s32i
%index = cir.const #cir.int<2> : !s32i
%vec_tmp = cir.load %0 : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
%new_vec = cir.vec.insert %value, %vec_tmp[%index : !s32i] : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.131.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR vector type |
|
any cir boolean, integer, floating point or pointer type |
|
fundamental integer type |
1.1.131.2. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.132. cir.vec.masked_load (::cir::VecMaskedLoadOp)¶
Masked vector load from memory
Syntax:
operation ::= `cir.vec.masked_load` (`align` `(` $alignment^ `)`)?
$addr `,` $mask `,` $pass_thru
`:` qualified(type($addr)) `,` type($mask) `,` type($pass_thru)
`->` type($result)
attr-dict
cir.masked_load conditionally loads elements from memory based on a mask.
Elements for which the mask is false are taken from pass_thru.
This operation corresponds to LLVM’s masked load op (llvm.intr.maskedload)
and lower directly to it.
alignment can be provided to override the default alignment derived from
the pointee/element type data layout.
Example:
%v = cir.masked_load align(16) %ptr, %mask, %passthru
: !cir.ptr<i32>, <4xi1>, <4xi32> -> <4xi32>
Interfaces: InferTypeOpInterface
1.1.132.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute whose value is positive and whose value is a power of two > 0 |
1.1.132.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR vector type |
|
CIR vector type |
1.1.132.3. Results:¶
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.133. 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.
%new_vec = cir.vec.shuffle(%vec_1, %vec_2 : !cir.vector<2 x !s32i>)
[#cir.int<3> : !s64i, #cir.int<1> : !s64i] : !cir.vector<2 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.133.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
indices | ::mlir::ArrayAttr | integer array attribute |
1.1.133.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR vector type |
|
CIR vector type |
1.1.133.3. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.134. 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.
%new_vec = cir.vec.shuffle.dynamic %vec : !cir.vector<4 x !s32i>, %indices
: !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.134.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR vector type |
|
vector of integer type |
1.1.134.2. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.135. 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.
It’s a separate operation from cir.vec.create because more
efficient LLVM IR can be generated for it, and because some optimization and
analysis passes can benefit from knowing that all elements of the vector
have the same value.
%value = cir.const #cir.int<3> : !s32i
%value_vec = cir.vec.splat %value : !s32i, !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.135.1. Operands:¶
Operand |
Description |
|---|---|
|
any cir boolean, integer, floating point or pointer type |
1.1.135.2. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.136. cir.vec.ternary (::cir::VecTernaryOp)¶
The cond ? a : b ternary operator for vector types
Syntax:
operation ::= `cir.vec.ternary` `(` $cond `,` $lhs`,` $rhs `)` `:` qualified(type($cond)) `,`
qualified(type($lhs)) 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{}
1.1.136.1. Operands:¶
Operand |
Description |
|---|---|
|
vector of integer type |
|
CIR vector type |
|
CIR vector type |
1.1.136.2. Results:¶
Result |
Description |
|---|---|
|
CIR vector type |
1.1.137. cir.vtable.address_point (::cir::VTableAddrPointOp)¶
Get the vtable (global variable) address point
Syntax:
operation ::= `cir.vtable.address_point` `(`
$name `,` `address_point` `=` $address_point
`)`
`:` qualified(type($addr)) attr-dict
The vtable.address_point operation retrieves the “effective” address
(address point) of a C++ virtual table. An object internal __vptr
gets initializated on top of the value returned by this operation.
address_point.index (vtable index) provides the appropriate vtable within
the vtable group (as specified by Itanium ABI), and address_point.offset
(address point index) the actual address point within that vtable.
The return type is always !cir.vptr.
Example:
cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.vtable.address_point(@_ZTV1B,
address_point = <index = 0, offset = 2>) : !cir.vptr
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
1.1.137.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
address_point | ::cir::AddressPointAttr | Address point attribute |
1.1.137.2. Results:¶
Result |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
1.1.138. cir.vtable.get_type_info (::cir::VTableGetTypeInfoOp)¶
Get the address of the type_info from the vtable
Syntax:
operation ::= `cir.vtable.get_type_info` $vptr attr-dict `:` qualified(type($vptr)) `->` qualified(type($result))
The vtable.get_type_info operation retreives the address of the dynamic
type_info/rtti object from an object’s vtable. This is an ABI independent
abstraction of this operation.
The vptr operand must be a !cir.vptr value, which would have been
returned by a previous call to cir.vtable.get_vptr.
The return type is a loadable pointer to a type_info struct.
Example:
%5 = cir.vtable.get_vptr %2 : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
%6 = cir.load align(8) %5 : !cir.ptr<!cir.vptr>, !cir.vptr
%7 = cir.vtable.get_type_info %6 : !cir.vptr -> !cir.ptr<!cir.ptr<!rec_std3A3Atype_info>>
%8 = cir.load align(8) %7 : !cir.ptr<!cir.ptr<!rec_std3A3Atype_info>>, !cir.ptr<!rec_std3A3Atype_info>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.138.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
1.1.138.2. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.139. cir.vtable.get_virtual_fn_addr (::cir::VTableGetVirtualFnAddrOp)¶
Get a the address of a virtual function pointer
Syntax:
operation ::= `cir.vtable.get_virtual_fn_addr` $vptr `[` $index `]` attr-dict
`:` qualified(type($vptr)) `->` qualified(type($result))
The vtable.get_virtual_fn_addr operation retrieves the address of a
virtual function pointer from an object’s vtable (__vptr).
This is an abstraction to perform the basic pointer arithmetic to get
the address of the virtual function pointer, which can then be loaded and
called.
The vptr operand must be a !cir.ptr<!cir.vptr> value, which would
have been returned by a previous call to cir.vtable.get_vptr. The
index operand is an index of the virtual function in the vtable.
The return type is a pointer-to-pointer to the function type.
Example:
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
%3 = cir.vtable.get_vptr %2 : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
%4 = cir.load %3 : !cir.ptr<!cir.vptr>, !cir.vptr
%5 = cir.vtable.get_virtual_fn_addr %4[2] : !cir.vptr
-> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_C>) -> !s32i>>>
%6 = cir.load align(8) %5 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_C>)
-> !s32i>>>,
!cir.ptr<!cir.func<(!cir.ptr<!rec_C>) -> !s32i>>
%7 = cir.call %6(%2) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_C>) -> !s32i>>,
!cir.ptr<!rec_C>) -> !s32i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.139.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
index | ::mlir::IntegerAttr | 64-bit signless integer attribute |
1.1.139.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
1.1.139.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.140. cir.vtable.get_vptr (::cir::VTableGetVPtrOp)¶
Get a the address of the vtable pointer for an object
Syntax:
operation ::= `cir.vtable.get_vptr` $src `:` qualified(type($src)) `->` qualified(type($result)) attr-dict
The vtable.get_vptr operation retrieves the address of the vptr for a
C++ object. This operation requires that the object pointer points to
the start of a complete object. (TODO: Describe how we get that).
The vptr will always be at offset zero in the object, but this operation
is more explicit about what is being retrieved than a direct bitcast.
The return type is always !cir.ptr<!cir.vptr>.
Example:
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!rec_C>>, !cir.ptr<!rec_C>
%3 = cir.vtable.get_vptr %2 : !cir.ptr<!rec_C> -> !cir.ptr<!cir.vptr>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.140.1. Operands:¶
Operand |
Description |
|---|---|
|
CIR pointer type |
1.1.140.2. Results:¶
Result |
Description |
|---|---|
|
pointer to vptr type |
1.1.141. cir.vtt.address_point (::cir::VTTAddrPointOp)¶
Get the VTT address point
Syntax:
operation ::= `cir.vtt.address_point` ($name^)?
($sym_addr^ `:` type($sym_addr))?
`,`
`offset` `=` $offset
`->` qualified(type($addr)) attr-dict
The vtt.address_point operation retrieves an element from the virtual
table table (VTT), which is the address point of a C++ vtable. In virtual
inheritance, a set of internal __vptr members for an object are
initialized by this operation, which assigns an element from the VTT. The
initialization order is as follows:
The complete object constructors and destructors find the VTT, via the mangled name of the VTT global variable. They pass the address of the subobject’s sub-VTT entry in the VTT as a second parameter when calling the base object constructors and destructors. The base object constructors and destructors use the address passed to initialize the primary virtual pointer and virtual pointers that point to the classes which either have virtual bases or override virtual functions with a virtual step.
The first parameter is either the mangled name of VTT global variable
or the address of the subobject’s sub-VTT entry in the VTT.
The second parameter offset provides a virtual step to adjust to
the actual address point of the vtable.
The return type is always a !cir.ptr<!cir.ptr<void>>.
Example:
cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.base_class_addr(%1 : !cir.ptr<!rec_D> nonnull) [0]
-> !cir.ptr<!rec_B>
%4 = cir.vtt.address_point @_ZTT1D, offset = 1
-> !cir.ptr<!cir.ptr<!void>>
cir.call @_ZN1BC2Ev(%3, %4)
Or:
%7 = cir.vtt.address_point %3 : !cir.ptr<!cir.ptr<!void>>, offset = 1
-> !cir.ptr<!cir.ptr<!void>>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
1.1.141.1. Attributes:¶
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
offset | ::mlir::IntegerAttr | 32-bit signless integer attribute |
1.1.141.2. Operands:¶
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.1.141.3. Results:¶
Result |
Description |
|---|---|
|
CIR pointer type |
1.1.142. 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 acir.conditionoperation.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
1.1.143. cir.xor (::cir::XorOp)¶
Bitwise XOR
Syntax:
operation ::= `cir.xor` $lhs `,` $rhs `:` type($lhs) attr-dict
The cir.xor operation performs a bitwise XOR on integer operands.
Both operands and the result must have the same integer type.
Example:
%0 = cir.xor %a, %b : !s32i
%1 = cir.xor %a, %b : !cir.bool
Traits: Commutative, SameOperandsAndResultType
Interfaces: BinaryOpInterface, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
1.1.143.1. Operands:¶
Operand |
Description |
|---|---|
|
integer, boolean, or vector of integer |
|
integer, boolean, or vector of integer |
1.1.143.2. Results:¶
Result |
Description |
|---|---|
|
integer, boolean, or vector of integer |
1.1.144. cir.yield (::cir::YieldOp)¶
Represents the default branching behaviour of a region
Syntax:
operation ::= `cir.yield` ($args^ `:` type($args))? attr-dict
The cir.yield operation terminates regions on different CIR operations,
and it is used to represent the default branching behaviour of a region.
Said branching behaviour is determinted by the parent operation. For
example, a yield in a switch-case region implies a fallthrough, while
a yield in a cir.if region implies a branch to the exit block, and so
on.
In some cases, it might yield an SSA value and the semantics of how the
values are yielded is defined by the parent operation. For example, a
cir.ternary operation yields a value from one of its regions.
As a general rule, cir.yield must be explicitly used whenever a region has
more than one block and no terminator, or within cir.switch regions not
cir.return terminated.
Examples:
cir.if %4 {
...
cir.yield
}
cir.switch (%5) [
case (equal, 3) {
...
cir.yield
}, ...
]
cir.scope {
...
cir.yield
}
%x = cir.scope {
...
cir.yield %val
}
%y = cir.ternary {
...
cir.yield %val : i32
} : i32
Traits: HasParent<ArrayCtor, ArrayDtor, AwaitOp, CaseOp, CleanupScopeOp, CoroBodyOp, DoWhileOp, ForOp, GlobalOp, IfOp, LocalInitOp, ScopeOp, SwitchOp, TernaryOp, TryOp, WhileOp>, ReturnLike, Terminator
Interfaces: NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface
Effects: MemoryEffects::Effect{}
1.1.144.1. Operands:¶
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or Integer type with arbitrary precision up to a fixed limit or single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type or CIR pointer type or CIR function type or CIR struct/class type or CIR union type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CIR type that represents a pointer-to-data-member in C++ or CIR type that represents C++ pointer-to-member-function type or CIR exception handling token type or CIR cleanup token type or CIR catch token type |
1.2. Attributes¶
1.2.1. ASTVarDeclAttr¶
Wraps a ‘const clang::VarDecl *’ AST node.
Operations optionally refer to this node, they could be available depending on the CIR lowering stage. Whether it’s attached to the appropriate CIR operation is delegated to the operation verifier.
Note: the AST pointer can be null when CIR is parsed from text, since there is no serialization support for AST nodes yet.
1.2.1.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
ast |
|
1.2.2. AddressPointAttr¶
Address point attribute
Syntax:
#cir.address_point<
int32_t, # index
int32_t # offset
>
Attribute specifying the address point within a C++ virtual table (vtable).
The index (vtable index) parameter identifies which vtable to use within a
vtable group, while the offset (address point index) specifies the offset
within that vtable where the address begins.
Example:
cir.global linkonce_odr @_ZTV1B = ...
...
%3 = cir.vtable.address_point(@_ZTV1B,
address_point = <index = 0, offset = 2>)
: !cir.vptr
1.2.2.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
index |
|
|
offset |
|
1.2.3. AnnotationAttr¶
Annotation attribute for global variables and functions
Syntax:
#cir.annotation<
::mlir::StringAttr, # name
mlir::ArrayAttr # args
>
Represents a C/C++ __attribute__((annotate(...))) in CIR.
Example C code:
int *a __attribute__((annotate("testptr", "21", 12)));
In CIR, the attribute for above annotation looks like:
[#cir.annotation<"testptr", ["21", 12 : i32]>]
1.2.3.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
args |
|
1.2.4. BitfieldInfoAttr¶
Represents info for a bit-field member
Syntax:
#cir.bitfield_info<
mlir::StringAttr, # name
mlir::Type, # storage_type
uint64_t, # size
uint64_t, # offset
bool # is_signed
>
Holds the following information about bitfields: name, storage type, size
and position in the storage, and signedness.
Example:
Given the following struct with bitfields:
c++ typedef struct { int a : 4; int b : 27; int c : 17; int d : 2; int e : 15; } S;
The CIR representation of the struct S might look like:
!rec_S = !cir.record<struct "S" packed padded {!u64i, !u16i,
!cir.array<!u8i x 2>}>
And the bitfield info attribute for member a would be:
#bfi_a = #cir.bitfield_info<name = "a", storage_type = !u64i,
size = 4, offset = 0, is_signed = true>
This metadata describes that field a is stored in a 64-bit integer,
is 4 bits wide, starts at offset 0, and is signed.
1.2.4.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
storage_type |
|
|
size |
|
|
offset |
|
|
is_signed |
|
1.2.5. BlockAddrInfoAttr¶
Block address attribute
Syntax:
#cir.block_addr_info<
cir::PointerType, # type
mlir::FlatSymbolRefAttr, # func
mlir::StringAttr # label
>
This attribute is used to represent the address of a basic block within a function. It combines the symbol reference to a function with the name of a label inside that function.
1.2.5.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
func |
|
|
label |
|
1.2.6. BoolAttr¶
Represent true/false for !cir.bool types
Syntax:
#cir.bool<
cir::BoolType, # type
bool # value
>
The BoolAttr represents a ‘true’ or ‘false’ value.
1.2.6.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
1.2.7. CUDABinaryHandleAttr¶
Fat binary handle for device code.
Syntax:
#cir.cu.binary_handle<
mlir::StringAttr # name
>
This attribute is attached to the ModuleOp and records the binary file name passed to host.
CUDA first compiles device-side code into a fat binary file. The file name is then passed into host-side code, which is used to create a handle and then generate various registration functions.
1.2.7.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
1.2.8. CUDAExternallyInitializedAttr¶
The marked variable is externally initialized.
Syntax: #cir.cu.externally_initialized
CUDA device and constant variables, along with surface and textures, might be initialized by host, hence “externally initialized”. Therefore they must be emitted even if they are not referenced.
The attribute corresponds to the attribute on LLVM with the same name.
1.2.9. CUDAKernelNameAttr¶
Device-side function name for this stub.
Syntax:
#cir.cu.kernel_name<
mlir::StringAttr # kernel_name
>
This attribute is attached to function definitions and records the mangled name of the kernel function used on the device.
In CUDA, global functions (kernels) are processed differently for host and device. On host, Clang generates device stubs; on device, they are treated as normal functions. As they probably have different mangled names, we must record the corresponding device-side name for a stub. Preserving the device-side kernel name is crucial for performing its respective function runtime registration on the host.
1.2.9.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
kernel_name |
|
1.2.10. CUDAVarRegistrationInfoAttr¶
Device variable registration flags.
1.2.10.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
device_side_name |
|
|
kind |
|
|
isExtern |
|
|
isConstant |
|
|
isManaged |
|
1.2.11. CXXAssignAttr¶
Marks a function as a CXX assignment operator
Syntax:
#cir.cxx_assign<
mlir::Type, # type
`copy` | `move`, # assign_kind
bool # is_trivial
>
This attribute identifies a C++ assignment operator and classifies its kind:
copy: a copy assignmentmove: a move assignment
1.2.11.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
assign_kind |
|
an enum of type AssignKind |
is_trivial |
|
1.2.12. CXXCtorAttr¶
Marks a function as a C++ constructor
Syntax:
#cir.cxx_ctor<
mlir::Type, # type
`custom` | `default` | `copy` | `move`, # ctor_kind
bool # is_trivial
>
This attribute identifies a C++ constructor and classifies its kind:
custom: a user-defined constructordefault: a default constructorcopy: a copy constructormove: a move constructor
Example:
#cir.cxx_ctor<!rec_a, copy>
#cir.cxx_ctor<!rec_b, default, trivial>
1.2.12.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
ctor_kind |
|
an enum of type CtorKind |
is_trivial |
|
1.2.13. CXXDtorAttr¶
Marks a function as a CXX destructor
Syntax:
#cir.cxx_dtor<
mlir::Type, # type
bool # is_trivial
>
This attribute identifies a C++ destructor.
1.2.13.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
is_trivial |
|
1.2.14. CatchAllAttr¶
Syntax: #cir.all
1.2.15. CleanupKindAttr¶
Cleanup kind attribute
Syntax:
#cir.cleanup_kind<
`normal` | `eh` | `all` # value
>
Cleanup kind attributes.
1.2.15.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CleanupKind |
1.2.16. CmpThreeWayInfoAttr¶
Holds information about a three-way comparison operation
Syntax:
#cir.cmp3way_info<
`strong` | `weak` | `partial`, # ordering
int64_t, # lt
int64_t, # eq
int64_t, # gt
std::optional<int64_t> # unordered
>
The #cmpinfo attribute contains information about a three-way
comparison operation cir.cmp3way.
The ordering parameter gives the ordering kind of the three-way comparison
operation: strong ordering, weak ordering, or partial ordering. Strong and
weak orderings are both total orderings (i.e. every two elements are comparable),
while partial orderings can have incomparable elements.
Given the two input operands of the three-way comparison operation lhs and
rhs, the lt, eq, gt, and unordered parameters gives the result
value that should be produced by the three-way comparison operation when the
ordering between lhs and rhs is lhs < rhs, lhs == rhs, lhs > rhs,
or neither, respectively.
Example:
!s32i = !cir.int<s, 32>
#cmpinfo_partial_ltn1eq0gt1unn127 = #cir.cmp3way_info<partial, lt = -1, eq = 0, gt = 1, unordered = -127>
#cmpinfo_strong_ltn1eq0gt1 = #cir.cmp3way_info<strong, lt = -1, eq = 0, gt = 1>
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.const #cir.int<1> : !s32i
%2 = cir.cmp3way(%0 : !s32i, %1, #cmpinfo_strong_ltn1eq0gt1) : !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, #cmpinfo_partial_ltn1eq0gt1unn127) : !s8
1.2.16.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
ordering |
|
an enum of type CmpOrdering |
lt |
|
|
eq |
|
|
gt |
|
|
unordered |
|
1.2.17. ConstArrayAttr¶
A constant array from ArrayAttr or StringRefAttr
An CIR array attribute is an array of literals of the specified attr types.
1.2.17.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
elts |
|
|
trailingZerosNum |
|
1.2.18. ConstComplexAttr¶
An attribute that contains a constant complex value
Syntax:
#cir.const_complex<
cir::ComplexType, # type
::mlir::TypedAttr, # real
::mlir::TypedAttr # imag
>
The #cir.const_complex attribute contains a constant value of complex
number type. The real parameter gives the real part of the complex number
and the imag parameter gives the imaginary part of the complex number.
The real and imag parameters must both reference the same type and must
be either IntAttr or FPAttr.
%ci = #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> : !s32i>
: !cir.complex<!s32i>
%cf = #cir.const_complex<#cir.fp<1.000000e+00> : !cir.float,
#cir.fp<2.000000e+00> : !cir.float> : !cir.complex<!cir.float>
1.2.18.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
real |
|
integer or floating point type |
imag |
|
integer or floating point type |
1.2.19. ConstPtrAttr¶
Holds a constant pointer value
Syntax:
#cir.ptr<
::cir::PointerType, # type
mlir::IntegerAttr # value
>
A pointer attribute is a literal attribute that represents an integral value of a pointer type.
1.2.19.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
1.2.20. ConstRecordAttr¶
Represents a constant record
Syntax:
#cir.const_record<
::mlir::Type, # type
mlir::ArrayAttr # members
>
Effectively supports “struct-like” constants. It’s must be built from
an mlir::ArrayAttr instance where each element is a typed attribute
(mlir::TypedAttribute).
Example:
cir.global external @rgb2 = #cir.const_record<{0 : i8,
5 : i64, #cir.null : !cir.ptr<i8>
}> : !cir.record<"", i8, i64, !cir.ptr<i8>>
1.2.20.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
members |
|
1.2.21. ConstVectorAttr¶
A constant vector from ArrayAttr
Syntax:
#cir.const_vector<
::mlir::Type, # type
mlir::ArrayAttr # elts
>
A CIR vector attribute is an array of literals of the specified attribute types.
1.2.21.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
elts |
|
1.2.22. DataMemberAttr¶
Holds a constant data member pointer value
Syntax:
#cir.data_member<
cir::DataMemberType, # type
mlir::DenseI32ArrayAttr # member_path
>
A data member attribute is a literal attribute that represents a constant pointer-to-data-member value.
The member_path parameter is a GEP-like sequence of field indices
navigating from classTy down to the pointed-to member. An absent
member_path represents a null pointer-to-data-member.
Examples:
// int Point::*p = &Point::z (z is field 2)
#cir.data_member<[2]> : !cir.data_member<!s32i in !rec_Point>
// int Derived::*p = &Derived::x (Base subobject at [0], x at [0])
#cir.data_member<[0, 0]> : !cir.data_member<!s32i in !rec_Derived>
// null
#cir.data_member<null> : !cir.data_member<!s32i in !rec_Point>
1.2.22.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
member_path |
|
1.2.23. DynamicCastInfoAttr¶
ABI specific information about a dynamic cast
Syntax:
#cir.dyn_cast_info<
::cir::GlobalViewAttr, # src_rtti
::cir::GlobalViewAttr, # dest_rtti
mlir::FlatSymbolRefAttr, # runtime_func
mlir::FlatSymbolRefAttr, # bad_cast_func
::cir::IntAttr # offset_hint
>
Provide ABI specific information about a dynamic cast operation.
The src_rtti and the dest_rtti parameters give the RTTI of the source
record type and the destination record type, respectively.
The runtime_func parameter gives the __dynamic_cast function which is
provided by the runtime. The bad_cast_func parameter gives the
__cxa_bad_cast function which is also provided by the runtime.
The offset_hint parameter gives the hint value that should be passed to
the __dynamic_cast runtime function.
1.2.23.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
src_rtti |
|
Provides constant access to a global address |
dest_rtti |
|
Provides constant access to a global address |
runtime_func |
|
|
bad_cast_func |
|
|
offset_hint |
|
An attribute containing an integer value |
1.2.24. FPAttr¶
An attribute containing a floating-point value
Syntax:
#cir.fp<
::cir::FPTypeInterface, # type
::llvm::APFloat # value
>
An fp attribute is a literal attribute that represents a floating-point value of the specified floating-point type. Supporting only CIR FP types.
1.2.24.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
1.2.25. GlobalCtorAttr¶
Marks a function as a global constructor
Syntax:
#cir.global_ctor<
mlir::StringAttr, # name
int # priority
>
Marks the function as a global constructor in the module’s constructor list. It will be executed before main() is called.
1.2.25.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
priority |
|
1.2.26. GlobalDtorAttr¶
Marks a function as a global destructor
Syntax:
#cir.global_dtor<
mlir::StringAttr, # name
int # priority
>
Marks a function as a global destructor in the module dtors list. The function will be executed before the module unloading.
1.2.26.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
priority |
|
1.2.27. GlobalViewAttr¶
Provides constant access to a global address
Syntax:
#cir.global_view<
::mlir::Type, # type
mlir::FlatSymbolRefAttr, # symbol
mlir::ArrayAttr # indices
>
Get constant address of global symbol and optionally apply offsets to
access existing subelements. It provides a way to access globals from other
global and always produces a pointer.
The type of the input symbol can be different from #cir.global_view
output type, since a given view of the global might require a static
cast for initializing other globals.
A list of indices can be optionally passed and each element subsequently
indexes underlying types. For symbol types like !cir.array
and !cir.record, it leads to the constant address of sub-elements, while
for !cir.ptr, an offset is applied. The first index is relative to the
original symbol type, not the produced one.
The result type of this attribute may be an integer type. In such a case, the pointer to the referenced global is casted to an integer and this attribute represents the casted result.
Example:
cir.global external @s = @".str2": !cir.ptr<i8>
cir.global external @x = #cir.global_view<@s> : !cir.ptr<i8>
cir.global external @s_addr = #cir.global_view<@s> : !s64i
cir.global external @rgb = #cir.const_array<[0 : i8, -23 : i8, 33 : i8]
: !cir.array<i8 x 3>>
cir.global external @elt_ptr = #cir.global_view<@rgb, [1]> : !cir.ptr<i8>
Note, that unlike LLVM IR’s gep instruction, CIR doesn’t add the leading zero index when it’s known to be constant zero, e.g. for pointers, i.e. we use indexes exactly to access sub elements or for the offset. The leading zero index is added later in the lowering.
Example:
struct A {
int a;
};
struct B: virtual A {
int b;
};
VTT for B in CIR:
cir.global linkonce_odr @_ZTT1B = #cir.const_array<[
#cir.global_view<@_ZTV1B, [0 : i32, 3 : i32]> : !cir.ptr<!u8i>]>
: !cir.array<!cir.ptr<!u8i> x 1>
VTT for B in LLVM IR:
@_ZTT1B = linkonce_odr global [1 x ptr] [ptr getelementptr inbounds
({ [3 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3)], align 8
1.2.27.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
symbol |
|
|
indices |
|
1.2.28. IntAttr¶
An attribute containing an integer value
Syntax:
#cir.int<
cir::IntTypeInterface, # type
::llvm::APInt # value
>
An integer attribute is a literal attribute that represents an integral value of the specified integer type.
1.2.28.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
1.2.29. LangAddressSpaceAttr¶
Represents a language address space
Syntax:
#cir.lang_address_space<
`default` | `offload_private` | `offload_local` | `offload_global` | `offload_constant` | `offload_generic` | `offload_global_device` | `offload_global_host` # value
>
Encodes the semantic address spaces defined by the front-end language
(e.g. __shared__, __constant__, __local__). Values are stored using the
cir::LangAddressSpace enum, keeping the representation compact and
preserving the qualifier until it is mapped onto target/LLVM address-space
numbers.
Example:
!cir.ptr<!s32i, lang_address_space(offload_local)>
cir.global constant external lang_address_space(offload_constant)
1.2.29.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type LangAddressSpace |
1.2.30. MethodAttr¶
Holds a constant pointer-to-member-function value
A method attribute is a literal attribute that represents a constant pointer-to-member-function value.
If the member function is a non-virtual function, the symbol parameter
gives the global symbol for the non-virtual member function.
If the member function is a virtual function, the vtable_offset parameter
gives the offset of the vtable entry corresponding to the virtual member
function.
symbol and vtable_offset cannot be present at the same time. If both of
symbol and vtable_offset are not present, the attribute represents a
null pointer constant.
Examples:
// Non-virtual method
%0 = cir.const #cir.method<@_ZN1S2m1Ei> :
!cir.method<!cir.func<(!s32i)> in !rec_S>
// Virtual method
%1 = cir.const #cir.method<vtable_offset = 8> :
!cir.method<!cir.func<(!s32i)> in !rec_S>
// Null method pointer
%0 = cir.const #cir.method<null> :
!cir.method<!cir.func<(!s32i)> in !rec_S>
1.2.30.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
symbol |
|
|
vtable_offset |
|
1.2.31. OpenCLKernelArgMetadataAttr¶
OpenCL kernel argument metadata
Syntax:
#cir.cl.kernel_arg_metadata<
::mlir::ArrayAttr, # addr_space
::mlir::ArrayAttr, # access_qual
::mlir::ArrayAttr, # type
::mlir::ArrayAttr, # base_type
::mlir::ArrayAttr, # type_qual
::mlir::ArrayAttr # name
>
Stores the OpenCL kernel argument metadata emitted to LLVM IR as
kernel_arg_* metadata.
All parameters are arrays containing the argument information in source
order. The name field is optional and is emitted only when requested by
-cl-kernel-arg-info.
1.2.31.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
addr_space |
|
language address space array attribute |
access_qual |
|
string array attribute |
type |
|
string array attribute |
base_type |
|
string array attribute |
type_qual |
|
string array attribute |
name |
|
string array attribute or null |
1.2.32. OptInfoAttr¶
A module-level attribute that holds the optimization information
Syntax:
#cir.opt_info<
unsigned, # level
unsigned # size
>
The #cir.opt_info attribute holds optimization related information. For
now this attribute is a module-level attribute that gets attached to the
module operation during CIRGen.
The level parameter gives the optimization level. It must be an integer
between 0 and 3, inclusive. It corresponds to the OptimizationLevel field
within the clang::CodeGenOptions structure.
The size parameter gives the code size optimization level. It must be an
integer between 0 and 2, inclusive. It corresponds to the OptimizeSize
field within the clang::CodeGenOptions structure.
The level and size parameters correspond to the optimization level
command line options passed to clang driver. The table below lists the
current correspondance relationship:
Flag |
|
|
|---|---|---|
|
0 |
0 |
|
1 |
0 |
|
2 |
0 |
|
3 |
0 |
|
2 |
1 |
|
2 |
2 |
Examples:
#cir.opt_info<level = 2, size = 0> // -O2
1.2.32.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
level |
|
|
size |
|
1.2.33. PoisonAttr¶
Represent a typed poison constant
Syntax:
#cir.poison<
::mlir::Type # type
>
The PoisonAttr represents a typed poison constant, corresponding to LLVM’s notion of poison.
1.2.33.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
1.2.34. RecordLayoutAttr¶
ABI layout metadata for a record type
Syntax:
#cir.record_layout<
`can_pass_in_regs` | `cannot_pass_in_regs` | `can_never_pass_in_regs`, # arg_passing_kind
bool, # has_trivial_dtor
uint64_t # record_align
>
Holds AST-derived ABI metadata for a named record type. These properties are translation-unit / target properties, not intrinsic to the type, so they live on the module rather than on RecordType.
Fields:
arg_passing_kind: whether the record can be passed in registers per the C++ ABI (mirrorsRecordDecl::getArgPassingRestrictions()).has_trivial_destructor: fromCXXRecordDecl::hasTrivialDestructor().record_align_in_bytes: fromASTRecordLayout::getAlignment(). Needed because CIR’s DataLayout cannot account for__attribute__((aligned(N))).
Example:
module attributes {
cir.record_layouts = {
"Trivial" = #cir.record_layout<
arg_passing_kind = can_pass_in_regs,
has_trivial_dtor = true,
record_align = 4>,
"NonTrivialDtor" = #cir.record_layout<
arg_passing_kind = cannot_pass_in_regs,
has_trivial_dtor = false,
record_align = 4>
}
}
1.2.34.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
arg_passing_kind |
|
an enum of type ArgPassingKind |
has_trivial_dtor |
|
|
record_align |
|
1.2.35. SourceLanguageAttr¶
Module source language
Syntax:
#cir.lang<
`c` | `cxx` # value
>
Represents the source language used to generate the module.
Example:
// Module compiled from C.
module attributes {cir.lang = cir.lang<c>} {}
// Module compiled from C++.
module attributes {cir.lang = cir.lang<cxx>} {}
Module source language attribute name is cir.lang is defined by
getSourceLanguageAttrName method in CIRDialect class.
1.2.35.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type SourceLanguage |
1.2.36. StaticLocalGuardAttr¶
Guard variable name for static local variables
Syntax:
#cir.static_local_guard<
mlir::StringAttr # name
>
Contains the mangled guard variable name for static local variable initialization.
Example:
cir.global internal static_local_guard<"_ZGVZ3foovE1x"> @_ZZ3foovE1x = ...
1.2.36.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
1.2.37. TargetAddressSpaceAttr¶
Represents a target-specific numeric address space
Syntax:
#cir.target_address_space<
unsigned # value
>
The TargetAddressSpaceAttr represents a target-specific numeric address space,
corresponding to the LLVM IR addrspace qualifier and the clang
address_space attribute.
A value of zero represents the default address space. The semantics of non-zero address spaces are target-specific.
Example:
// Target-specific numeric address spaces
!cir.ptr<!s32i, addrspace(target<1>)>
!cir.ptr<!s32i, addrspace(target<10>)>
1.2.37.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
1.2.38. ThreadLocalGlobalWrapperInitAttr¶
Wrapper and Init function names for thread local variables
Syntax:
#cir.tls_wrapper_init<
mlir::StringAttr, # wrapper_name
mlir::StringAttr, # init_name
mlir::StringAttr # guard_name
>
Contains the mangled name of the wrapper function, init function, and guard variable for a namespace/global scope thread local variable. The guard variable is optional, as it is only required for unordered thread local variables, as ordered thread local variables share a guard.
Unordered global thread local variables (such as variable template instantiations) are individually initialized when first used on a thread. Ordered global thread local variables are ALL initialized together when any that require initialization are referenced.
This is accomplished by rewriting all calls to these variables as calls to the wrapper. If the variable requires initialization, the wrapper calls the init function, then returns the global variable reference.
Throughout CIR though, these are just represented as normal get_global
calls to globals with ctor/dtor regions (if necessary). The
lowering-prepare pass manages the generation of the wrapper,x
initialization, and call rewrites.
Example:
cir.global tls_dyn dyn_tls_refs = <"_ZTW7tls_var", "_ZTH7tls_var"> @_ZZZ7tls_var = ...
...
cir.get_global thread_local @ZZZ7tls_var : !cir.ptr<!s32i>
1.2.38.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
wrapper_name |
|
|
init_name |
|
|
guard_name |
|
1.2.39. TypeInfoAttr¶
Represents a typeinfo used for RTTI
Syntax:
#cir.typeinfo<
::mlir::Type, # type
::mlir::ArrayAttr # data
>
The typeinfo data for a given class is stored into an ArrayAttr. The layout is determined by the C++ ABI used (clang only implements itanium on CIRGen).
The verifier enforces that the output type is always a !cir.record,
and that the ArrayAttr element types match the equivalent member type
for the resulting record, i.e, a GlobalViewAttr for symbol reference or
an IntAttr for flags.
Example:
cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE
: !cir.ptr<i32>
!rec_anon_struct = !cir.record<struct {!cir.ptr<!u8i>, !cir.ptr<!u8i>,
!cir.ptr<!u8i>}>
cir.global constant external @type_info = #cir.typeinfo<{
#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]>
: !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>,
#cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !rec_anon_struct
1.2.39.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
data |
|
integer or global view array attribute |
1.2.40. UndefAttr¶
Represent an undef constant
Syntax:
#cir.undef<
::mlir::Type # type
>
The UndefAttr represents an undef constant, corresponding to LLVM’s notion of undef.
1.2.40.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
1.2.41. UnwindAttr¶
Syntax: #cir.unwind
1.2.42. UsualDeleteParamsAttr¶
Parameters describing the usual operator delete signature
Syntax:
#cir.usual_delete_params<
bool, # size
bool, # alignment
bool, # type_aware_delete
bool # destroying_delete
>
Captures the properties of the usual deallocation function associated with
an operator delete. These mirror the fields of clang::UsualDeleteParams.
1.2.42.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
size |
|
|
alignment |
|
|
type_aware_delete |
|
|
destroying_delete |
|
1.2.43. VTableAttr¶
Represents a C++ vtable
Syntax:
#cir.vtable<
::mlir::Type, # type
mlir::ArrayAttr # data
>
Wraps a #cir.const_record containing one or more vtable arrays.
In most cases, the anonymous record type wrapped by this attribute will contain a single array corresponding to the vtable for one class. However, in the case of multiple inheritence, the anonymous structure may contain multiple arrays, each of which is a vtable.
Example 1 (single vtable):
cir.global linkonce_odr @_ZTV6Mother =
#cir.vtable<{
#cir.const_array<[
#cir.ptr<null> : !cir.ptr<!u8i>,
#cir.global_view<@_ZTI6Mother> : !cir.ptr<!u8i>,
#cir.global_view<@_ZN6Mother9MotherFooEv> : !cir.ptr<!u8i>,
#cir.global_view<@_ZN6Mother10MotherFoo2Ev> : !cir.ptr<!u8i>
]> : !cir.array<!cir.ptr<!u8i> x 4>
}> : !rec_anon_struct1
Example 2 (multiple vtables):
cir.global linkonce_odr @_ZTV5Child =
#cir.vtable<{
#cir.const_array<[
#cir.ptr<null> : !cir.ptr<!u8i>,
#cir.global_view<@_ZTI5Child> : !cir.ptr<!u8i>,
#cir.global_view<@_ZN5Child9MotherFooEv> : !cir.ptr<!u8i>,
#cir.global_view<@_ZN6Mother10MotherFoo2Ev> : !cir.ptr<!u8i>
]> : !cir.array<!cir.ptr<!u8i> x 4>,
#cir.const_array<[
#cir.ptr<-8 : i64> : !cir.ptr<!u8i>,
#cir.global_view<@_ZTI5Child> : !cir.ptr<!u8i>,
#cir.global_view<@_ZN6Father9FatherFooEv> : !cir.ptr<!u8i>
]> : !cir.array<!cir.ptr<!u8i> x 3>
}> : !rec_anon_struct2
1.2.43.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
data |
|
1.2.44. VisibilityAttr¶
Visibility attribute
Syntax:
#cir.visibility<
`default` | `hidden` | `protected` # value
>
Visibility attributes.
1.2.44.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type VisibilityKind |
1.2.45. ZeroAttr¶
Attribute to represent zero initialization
Syntax:
#cir.zero<
::mlir::Type # type
>
The ZeroAttr is used to indicate zero initialization on structs.
1.2.45.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
1.3. Types¶
1.3.1. ArrayType¶
CIR array type
Syntax:
!cir.array<
mlir::Type, # elementType
uint64_t # size
>
!cir.array represents C/C++ constant arrays.
1.3.1.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
elementType |
|
|
size |
|
1.3.2. BF16Type¶
CIR bfloat16 16-bit float type
Syntax: !cir.bf16
A 16-bit floating-point type in the bfloat16 format, which is the same as
IEEE binary32 except that the lower 16 bits of the mantissa are missing.
It represents the type std::bfloat16_t in C++, also spelled __bf16 in
some implementations.
1.3.3. BoolType¶
CIR bool type
Syntax: !cir.bool
!cir.bool represents C++ bool type.
1.3.4. CatchTokenType¶
CIR catch token type
Syntax: !cir.catch_token
!cir.catch_token is an opaque type used to track catch handling state
in flattened CIR. It is returned by cir.begin_catch and consumed by
cir.end_catch.
This token ensures that catch handlers are properly paired and allows the ABI lowering pass to generate appropriate exception catching code.
1.3.5. CleanupTokenType¶
CIR cleanup token type
Syntax: !cir.cleanup_token
!cir.cleanup_token is an opaque type used to track cleanup handling state
in flattened CIR. It is returned by cir.begin_cleanup and consumed by
cir.end_cleanup.
This token ensures that cleanup regions are properly paired and allows the ABI lowering pass to generate appropriate cleanup handling code.
1.3.6. ComplexType¶
CIR complex type
Syntax:
!cir.complex<
::mlir::Type # elementType
>
CIR type that represents a C complex number. cir.complex models the C type
T _Complex.
cir.complex type is not directly mapped to std::complex.
The type models complex values, per C99 6.2.5p11. It supports the C99 complex float types as well as the GCC integer complex extensions.
The parameter elementType gives the type of the real and imaginary part of
the complex number. elementType must be either a CIR integer type or a CIR
floating-point type.
!cir.complex<!s32i>
!cir.complex<!cir.float>
1.3.6.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
elementType |
|
integer or floating point type |
1.3.7. DataMemberType¶
CIR type that represents a pointer-to-data-member in C++
Syntax:
!cir.data_member<
mlir::Type, # member_ty
cir::RecordType # class_ty
>
cir.data_member models a pointer-to-data-member in C++. Values of this
type are essentially offsets of the pointed-to member within one of its
containing record.
1.3.7.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
member_ty |
|
|
class_ty |
|
1.3.8. DoubleType¶
CIR double-precision 64-bit float type
Syntax: !cir.double
A 64-bit floating-point type whose format is IEEE-754 binary64. It
represents the types double', '_Float64, std::float64_t, and _Float32x
in C and C++. This is the underlying type for long double on some
platforms, including Windows.
1.3.9. EhTokenType¶
CIR exception handling token type
Syntax: !cir.eh_token
!cir.eh_token is an opaque type used to track exception handling state
in flattened CIR. It is returned by cir.eh.initiate and passed to
cir.eh.dispatch, cir.begin_cleanup, and cir.begin_catch operations.
This token represents an in-flight exception and is used during ABI-lowering to generate the appropriate exception handling code.
1.3.10. FP16Type¶
CIR half-precision 16-bit float type
Syntax: !cir.f16
A 16-bit floating-point type whose format is IEEE-754 binary16. It
represents the types ‘_Float16andstd::float16_t` in C and C++.
1.3.11. FP80Type¶
CIR x87 80-bit float type
Syntax: !cir.f80
An 80-bit floating-point type in the x87 extended precision format. The
size and alignment of the type are both 128 bits, even though only 80 of
those bits are used. This is the underlying type for long double on Linux
x86 platforms, and it is available as an extension in some implementations.
1.3.12. FP128Type¶
CIR quad-precision 128-bit float type
Syntax: !cir.f128
A 128-bit floating-point type whose format is IEEE-754 binary128. It
represents the types _Float128 and std::float128_t in C and C++, and the
extension __float128 in some implementations. This is the underlying type
for long double on some platforms including Linux Arm.
1.3.13. FuncType¶
CIR function type
Syntax:
!cir.func<
::llvm::ArrayRef<mlir::Type>, # inputs
mlir::Type, # optionalReturnType
bool # varArg
>
The !cir.func is a function type. It consists of an optional return type,
a list of parameter types and can optionally be variadic.
Example:
!cir.func<()>
!cir.func<() -> bool>
!cir.func<(!s8i, !s8i)>
!cir.func<(!s8i, !s8i) -> !s32i>
!cir.func<(!s32i, ...) -> !s32i>
1.3.13.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
inputs |
|
|
optionalReturnType |
|
|
varArg |
|
1.3.14. IntType¶
Integer type with arbitrary precision up to a fixed limit
CIR type that represents integer types with arbitrary precision, including
standard integral types such as int and long, extended integral types
such as __int128, and arbitrary width types such as _BitInt(n).
Those integer types that are directly available in C/C++ standard are called
fundamental integer types. Said types are: signed char, short, int,
long, long long, and their unsigned variations.
Examples: !cir.int<s, 32>, !cir.int<u, 64>, !cir.int<s, 128, bitint>
1.3.14.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
width |
|
|
is_signed |
|
|
is_bit_int |
|
1.3.15. LongDoubleType¶
CIR float type for long double
Syntax:
!cir.long_double<
::mlir::Type # underlying
>
A floating-point type that represents the long double type in C and C++.
The underlying floating-point format of a long double value depends on the
target platform and the implementation. The underlying parameter specifies
the CIR floating-point type that corresponds to this format. Underlying
types of IEEE 64-bit, IEEE 128-bit, x87 80-bit, and IBM’s double-double
format are all in use.
1.3.15.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
underlying |
|
expects !cir.double, !cir.fp80 or !cir.fp128 |
1.3.16. MethodType¶
CIR type that represents C++ pointer-to-member-function type
Syntax:
!cir.method<
cir::FuncType, # member_func_ty
cir::RecordType # class_ty
>
cir.method models the pointer-to-member-function type in C++. The layout
of this type is ABI-dependent.
1.3.16.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
member_func_ty |
|
|
class_ty |
|
1.3.17. PointerType¶
CIR pointer type
Syntax:
!cir.ptr<
mlir::Type, # pointee
mlir::ptr::MemorySpaceAttrInterface # addrSpace
>
The !cir.ptr type is a typed pointer type. It is used to represent
pointers to objects in C/C++. The type of the pointed-to object is given by
the pointee parameter. The addrSpace parameter is an optional address
space attribute that specifies the address space of the pointer. If not
specified, the pointer is assumed to be in the default address space.
The !cir.ptr type can point to any type, including fundamental types,
records, arrays, vectors, functions, and other pointers. It can also point
to incomplete types, such as incomplete records.
Examples:
!cir.ptr<!cir.int<u, 8>>
!cir.ptr<!cir.float>
!cir.ptr<!cir.record<struct "MyStruct">>
!cir.ptr<!cir.int<u, 8>, target_address_space(1)>
!cir.ptr<!cir.record<struct "MyStruct">, target_address_space(5)>
1.3.17.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
pointee |
|
|
addrSpace |
|
1.3.18. SingleType¶
CIR single-precision 32-bit float type
Syntax: !cir.float
A 32-bit floating-point type whose format is IEEE-754 binary32. It
represents the types float, _Float32, and std::float32_t in C and C++.
1.3.19. StructType¶
CIR struct/class type
Each unique clang::RecordDecl with struct or class kind is mapped to a
cir.struct type. Any object in C/C++ that has a struct or class type
will have a !cir.struct in CIR.
There are three possible formats:
Identified and complete: unique name and a known body.
Identified and incomplete: unique name and unknown body.
Anonymous: no name and a known body.
The optional class keyword distinguishes C++ class declarations from
plain struct declarations. Both are semantically identical; the keyword
preserves the original source spelling.
Examples:
!rec_complete = !cir.struct<"complete" {!u8i}>
!rec_class = !cir.struct<class "MyClass" {!s32i}>
!rec_incomplete = !cir.struct<"incomplete" incomplete>
!anonymous = !cir.struct<{!u8i}>
!rec_packed = !cir.struct<"p1" packed {!u8i, !u8i}>
!rec_padded = !cir.struct<"p2" padded {!u8i, !u8i}>
!recursive = !cir.struct<"Node" {!cir.ptr<!cir.struct<"Node">>}>
1.3.19.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
members |
|
|
name |
|
|
incomplete |
|
|
packed |
|
|
padded |
|
|
is_class |
|
1.3.20. UnionType¶
CIR union type
Each unique clang::RecordDecl with union kind is mapped to a cir.union
type. Any object in C/C++ that has a union type will have a !cir.union
in CIR.
There are three possible formats:
Identified and complete: unique name and a known body.
Identified and incomplete: unique name and unknown body.
Anonymous: no name and a known body.
Padded unions carry an explicit tail-padding type to ensure the LLVM struct that models the union has the correct byte size.
Examples:
!u_complete = !cir.union<"U" {!s32i, !u8i}>
!u_incomplete = !cir.union<"U" incomplete>
!u_anonymous = !cir.union<{!s32i, !u8i}>
!u_padded = !cir.union<"U" {!s32i, !u8i}, padding = {!u8i}>
1.3.20.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
members |
|
|
name |
|
|
incomplete |
|
|
packed |
|
|
padding |
|
1.3.21. VPtrType¶
CIR type that is used for the vptr member of C++ objects
Syntax: !cir.vptr
cir.vptr is a special type used as the type for the vptr member of a C++
object. This avoids using arbitrary pointer types to declare vptr values
and allows stronger type-based checking for operations that use or provide
access to the vptr.
This type will be the element type of the ‘vptr’ member of structures that
require a vtable pointer. The cir.vtable.address_point operation returns
this type. The cir.vtable.get_vptr operations returns a pointer to this
type. This pointer may be passed to the cir.vtable.get_virtual_fn_addr
operation to get the address of a virtual function pointer.
The pointer may also be cast to other pointer types in order to perform pointer arithmetic based on information encoded in the AST layout to get the offset from a pointer to a dynamic object to the base object pointer, the base object offset value from the vtable, or the type information entry for an object. TODO: We should have special operations to do that too.
1.3.22. VectorType¶
CIR vector type
The !cir.vector type represents a one-dimensional vector.
It takes three parameters: the element type, the number of elements and the
scalability flag (optional, defaults to false).
Syntax:
vector-type ::= !cir.vector<size x element-type>
size ::= (decimal-literal | `[` decimal-literal `]`)
element-type ::= float-type | integer-type | pointer-type
The element-type must be a scalar CIR type. Zero-sized vectors are not
allowed. The size must be a positive integer.
Examples:
!cir.vector<4 x !cir.int<u, 8>>
!cir.vector<2 x !cir.float>
Scalable vectors are indicated by enclosing size in square brackets.
Example:
!cir.vector<[4] x !cir.int<u, 8>>
1.3.22.1. Parameters:¶
Parameter |
C++ type |
Description |
|---|---|---|
element_type |
|
any cir boolean, integer, floating point or pointer type |
size |
|
|
is_scalable |
|
1.3.23. VoidType¶
CIR void type
Syntax: !cir.void
The !cir.void type represents the C and C++ void type.
1.4. Enums¶
1.4.1. ArgPassingKind¶
Record argument passing eligibility
1.4.1.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
CanPassInRegs |
|
can_pass_in_regs |
CannotPassInRegs |
|
cannot_pass_in_regs |
CanNeverPassInRegs |
|
can_never_pass_in_regs |
1.4.2. AsmFlavor¶
ATT or Intel
1.4.2.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
x86_att |
|
x86_att |
x86_intel |
|
x86_intel |
1.4.3. AssignKind¶
CXX Assignment Operator Kind
1.4.3.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Copy |
|
copy |
Move |
|
move |
1.4.4. AssumeBundleKind¶
Kind of cir.assume operand bundle
1.4.4.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
None |
|
None |
Align |
|
align |
SeparateStorage |
|
separate_storage |
Dereferenceable |
|
dereferenceable |
1.4.5. AtomicFetchKind¶
Binary opcode for atomic fetch-and-update operations
1.4.5.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Add |
|
add |
Sub |
|
sub |
And |
|
and |
Xor |
|
xor |
Or |
|
or |
Nand |
|
nand |
Max |
|
max |
Min |
|
min |
UIncWrap |
|
uinc_wrap |
UDecWrap |
|
udec_wrap |
1.4.6. AwaitKind¶
Await kind
1.4.6.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Init |
|
init |
User |
|
user |
Yield |
|
yield |
Final |
|
final |
1.4.7. CUDADeviceVarKind¶
CUDA device variable kind
1.4.7.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Variable |
|
Variable |
Surface |
|
Surface |
Texture |
|
Texture |
1.4.8. CallingConv¶
Calling convention
1.4.8.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
C |
|
c |
PTXKernel |
|
ptx_kernel |
SpirFunction |
|
spir_function |
SpirKernel |
|
spir_kernel |
AMDGPUKernel |
|
amdgpu_kernel |
1.4.9. CaseOpKind¶
Case kind
1.4.9.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Default |
|
default |
Equal |
|
equal |
Anyof |
|
anyof |
Range |
|
range |
1.4.10. CastKind¶
Cast kind
1.4.10.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
bitcast |
|
bitcast |
array_to_ptrdecay |
|
array_to_ptrdecay |
member_ptr_to_bool |
|
member_ptr_to_bool |
int_to_ptr |
|
int_to_ptr |
ptr_to_int |
|
ptr_to_int |
ptr_to_bool |
|
ptr_to_bool |
integral |
|
integral |
int_to_bool |
|
int_to_bool |
int_to_float |
|
int_to_float |
float_to_int |
|
float_to_int |
float_to_bool |
|
float_to_bool |
bool_to_int |
|
bool_to_int |
floating |
|
floating |
float_to_complex |
|
float_to_complex |
float_complex_to_real |
|
float_complex_to_real |
float_complex_to_bool |
|
float_complex_to_bool |
float_complex |
|
float_complex |
float_complex_to_int_complex |
|
float_complex_to_int_complex |
int_to_complex |
|
int_to_complex |
int_complex_to_real |
|
int_complex_to_real |
int_complex_to_bool |
|
int_complex_to_bool |
int_complex |
|
int_complex |
int_complex_to_float_complex |
|
int_complex_to_float_complex |
address_space |
|
address_space |
bool_to_float |
|
bool_to_float |
1.4.11. CleanupKind¶
Cleanup kind
1.4.11.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Normal |
|
normal |
EH |
|
eh |
All |
|
all |
1.4.12. CmpOpKind¶
Compare operation kind
1.4.12.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
lt |
|
lt |
le |
|
le |
gt |
|
gt |
ge |
|
ge |
eq |
|
eq |
ne |
|
ne |
one |
|
one |
uno |
|
uno |
1.4.13. CmpOrdering¶
Three-way comparison ordering kind
1.4.13.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Strong |
|
strong |
Weak |
|
weak |
Partial |
|
partial |
1.4.14. ComplexRangeKind¶
Complex multiplication and division implementation
1.4.14.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Full |
|
full |
Improved |
|
improved |
Promoted |
|
promoted |
Basic |
|
basic |
1.4.15. CtorKind¶
CXX Constructor Kind
1.4.15.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Custom |
|
custom |
Default |
|
default |
Copy |
|
copy |
Move |
|
move |
1.4.16. DynamicCastKind¶
Dynamic cast kind
1.4.16.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Ptr |
|
ptr |
Ref |
|
ref |
1.4.17. GlobalLinkageKind¶
Linkage kind
1.4.17.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
ExternalLinkage |
|
external |
AvailableExternallyLinkage |
|
available_externally |
LinkOnceAnyLinkage |
|
linkonce |
LinkOnceODRLinkage |
|
linkonce_odr |
WeakAnyLinkage |
|
weak |
WeakODRLinkage |
|
weak_odr |
AppendingLinkage |
|
appending |
InternalLinkage |
|
internal |
PrivateLinkage |
|
cir_private |
ExternalWeakLinkage |
|
extern_weak |
CommonLinkage |
|
common |
1.4.18. InitCatchKind¶
Allowed 32-bit signless integer cases: 0, 1, 2, 3, 4, 5
1.4.18.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Reference |
|
reference |
Pointer |
|
pointer |
Scalar |
|
scalar |
Objc |
|
objc |
TrivialCopy |
|
trivial_copy |
NonTrivialCopy |
|
non_trivial_copy |
1.4.19. InlineKind¶
InlineKind
1.4.19.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
NoInline |
|
no_inline |
AlwaysInline |
|
always_inline |
InlineHint |
|
inline_hint |
1.4.20. LangAddressSpace¶
Language address space kind
1.4.20.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Default |
|
default |
OffloadPrivate |
|
offload_private |
OffloadLocal |
|
offload_local |
OffloadGlobal |
|
offload_global |
OffloadConstant |
|
offload_constant |
OffloadGeneric |
|
offload_generic |
OffloadGlobalDevice |
|
offload_global_device |
OffloadGlobalHost |
|
offload_global_host |
1.4.21. MemOrder¶
Memory order according to C++11 memory model
1.4.21.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Relaxed |
|
relaxed |
Consume |
|
consume |
Acquire |
|
acquire |
Release |
|
release |
AcquireRelease |
|
acq_rel |
SequentiallyConsistent |
|
seq_cst |
1.4.22. SideEffect¶
Allowed side effects of a function
1.4.22.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
All |
|
all |
Pure |
|
pure |
Const |
|
const |
1.4.23. SourceLanguage¶
Source language
1.4.23.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
C |
|
c |
CXX |
|
cxx |
1.4.24. SyncScopeKind¶
Sync scope kind
1.4.24.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
SingleThread |
|
single_thread |
System |
|
system |
Device |
|
device |
Workgroup |
|
workgroup |
Wavefront |
|
wavefront |
Cluster |
|
cluster |
HIPSingleThread |
|
hip_single_thread |
HIPSystem |
|
hip_system |
HIPAgent |
|
hip_agent |
HIPWorkgroup |
|
hip_workgroup |
HIPWavefront |
|
hip_wavefront |
HIPCluster |
|
hip_cluster |
OpenCLWorkGroup |
|
opencl_work_group |
OpenCLDevice |
|
opencl_device |
OpenCLAllSVMDevices |
|
opencl_all_svm_devices |
OpenCLSubGroup |
|
opencl_sub_group |
1.4.25. TLS_Model¶
TLS model
1.4.25.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
GeneralDynamic |
|
tls_dyn |
LocalDynamic |
|
tls_local_dyn |
InitialExec |
|
tls_init_exec |
LocalExec |
|
tls_local_exec |
1.4.26. VisibilityKind¶
C/C++ visibility
1.4.26.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
Default |
|
default |
Hidden |
|
hidden |
Protected |
|
protected |
1.4.27. FPClassTest¶
Floating-point class test flags
1.4.27.1. Cases:¶
Symbol |
Value |
String |
|---|---|---|
SignalingNaN |
|
fcSNan |
QuietNaN |
|
fcQNan |
NegativeInfinity |
|
fcNegInf |
NegativeNormal |
|
fcNegNormal |
NegativeSubnormal |
|
fcNegSubnormal |
NegativeZero |
|
fcNegZero |
PositiveZero |
|
fcPosZero |
PositiveSubnormal |
|
fcPosSubnormal |
PositiveNormal |
|
fcPosNormal |
PositiveInfinity |
|
fcPosInf |
Nan |
|
fcNan |
Infinity |
|
fcInf |
Normal |
|
fcNormal |
Subnormal |
|
fcSubnormal |
Zero |
|
fcZero |
PositiveFinite |
|
fcPosFinite |
NegativeFinite |
|
fcNegFinite |
Finite |
|
fcFinite |
Positive |
|
fcPositive |
Negative |
|
fcNegative |
All |
|
fcAllFlags |