CIR Dialect Reference#
A high-level dialect for analyzing and optimizing Clang supported languages
Passes#
-cir-call-conv-lowering#
Lower CIR function signatures and call sites to match target ABI
This pass rewrites cir.func signatures and cir.call sites to match the
target ABI’s calling convention requirements (extension attributes, struct
coercion, sret/byval indirect passing, struct flattening, etc.).
Requirements on the input IR:
All C++-specific CIR types must already be lowered to ABI-relevant shapes. In particular, member pointers and method types must have been rewritten by
CXXABILoweringso that the pass sees only the final ABI representation of each value.The module must carry a
dlti.dl_specattribute so the classifier can query type sizes and alignments.
Two driver modes select how each function’s classification is computed:
target=<name>selects an ABI target. The clang pipeline picks the target from the module triple. Supported targets:"x86_64": System V."amdgpu": AMDGPU."test": the MLIR test target inmlir/lib/ABI/Targets/Test/. Other targets will be added as the LLVM ABI library ships them.
classification-attr=<name>reads aDictionaryAttrnamed<name>from eachcir.funcand parses it via the test-target injection helper. Used by tests to inject arbitrary classifications without depending on a real ABI target.
Exactly one of the two options must be set.
Options#
-target : Target whose ABI rules drive classification
-classification-attr : Function attribute name carrying a pre-built FunctionClassification DictionaryAttr (alternative to target=, used by tests)
-x86-avx-abi-level : AVX ABI level for the x86_64 target
-x86-target-attr-avx : Let a function's own target features raise its AVX ABI level above x86-avx-abi-level
-cir-canonicalize#
Performs CIR canonicalization
Perform canonicalizations on CIR and removes some redundant operations.
This pass performs basic cleanup and canonicalization transformations that
are not intended to affect CIR-to-source fidelity and high-level code
analysis passes. Example transformations performed in this pass include
empty scope cleanup, trivial try cleanup, redundant branch cleanup, etc.
Those more “heavyweight” transformations and those transformations that
could significantly affect CIR-to-source fidelity are performed in the
cir-simplify pass.
-cir-cxxabi-lowering#
Lower CIR according to C++ ABI requirements
This pass lowers CIR operations and types that represent high-level C/C++ constructs to a more fundamental form according to the target ABI requirements.
See the description of the TargetLowering pass for the difference between
this pass and the TargetLowering pass.
-cir-eh-abi-lowering#
Lower flattened CIR EH operations to target-specific ABI form
This pass lowers the ABI-agnostic exception handling operations produced by CFG flattening into an ABI-specific form. Currently only the Itanium C++ ABI is implemented.
For the Itanium ABI, the pass performs the following transformations:
Replaces
cir.eh.initiatewithcir.eh.inflight_exceptionReplaces
cir.eh.dispatchwithcir.eh.typeid+ comparison chainsRemoves
cir.begin_cleanupandcir.end_cleanupoperationsReplaces
cir.begin_catchwith a call to__cxa_begin_catchReplaces
cir.end_catchwith a call to__cxa_end_catchReplaces
cir.resumewithcir.resume.flatSets the personality function attribute on functions that require EH
If a non-Itanium ABI is specified, the pass emits a diagnostic indicating that the target is not yet implemented.
-cir-flatten-cfg#
Produces flatten CFG
This pass transforms CIR by inlining all the nested regions. Thus, the following conditions are true after the pass applied:
there are no nested regions in any function body
all the blocks in a function belong to the parent region In other words, this pass removes such CIR operations like IfOp, LoopOp, ScopeOp and etc. and produces a flat CIR.
-cir-goto-solver#
Replaces goto operations with branches
This pass transforms CIR and replaces goto-s with branch operations to the proper blocks.
-cir-hoist-allocas#
Hoist allocas to the entry of the function
This pass hoist all non-dynamic allocas to the entry of the function. This is helpful for later code generation.
-cir-idiom-recognizer#
Raise calls to C/C++ libraries to CIR operations
This pass recognizes idiomatic C++ usage and captures information about C++ standard library containers, library functions calls, and types into CIR operations, attributes and types.
-cir-lib-opt#
Optimize C/C++ library calls
This pass applies transformations on C/C++ standard library idioms,
such as library function calls and structs raised to CIR operations
using the cir-idiom-recognize pass.
-cir-lowering-prepare#
Lower to more fine-grained CIR operations before lowering to other dialects
This pass does preparation work for lowering to other dialects. For example, it may expand the global variable initialziation in a more ABI-friendly form.
-cir-simplify#
Performs CIR simplification and code optimization
The pass performs semantics-preserving code simplifications and optimizations on CIR while maintaining strict program correctness.
Unlike the cir-canonicalize pass, these transformations may reduce the IR’s
structural similarity to the original source code as a trade-off for improved
code quality. This can affect debugging fidelity by altering intermediate
representations of folded expressions, hoisted operations, and other
optimized constructs.
Example transformations include ternary expression folding and code hoisting while preserving program semantics.
-cir-target-lowering#
Lower CIR to a target-specific form
This pass lowers CIR operations from a target-agnostic form to a target-specific form without considering ABI requirements.
CIR has three passes in its lowering pipeline that transform input CIR according to target-specific requirements, scheduled in the pipeline by the following order:
The
TargetLoweringpass.The
CXXABILoweringpass.The
CallConvLoweringpass.
The TargetLowering pass acts more like a legalization pass. It ensures
every operation in CIR conforms to the target’s constraints. An example
would be the handling of synchronization scopes of atomic operations. The
x86 family of targets only support a system-wide synchronization scope, thus
any atomic operations with a different synchronization scope would be
transformed to use the system-wide scope in this pass.
The CXXABILowering pass and the CallConvLowering pass transform the
CIR according to the target’s ABI requirements. The former handles all
ABI-related lowering except for calling convention handling, which is
handled specifically in the latter. Example transformations that the
CXXABILowering pass could make include:
Replace C/C++ types that have an ABI-defined layout with more fundamental types corresponding to the ABI requirements. For example, the layout of the pointer-to-data-member type in C++ is ABI-defined, thus the
CXXABILoweringpass would replace all occurrences of this type according to the ABI requirements. With a typical target ABI, it will be replaced by theptrdiff_ttype since this is the type most ABIs use for the layout of the pointer-to-data-member type.Replace CIR operations that have ABI-dependent implementations with more fundamental operations. For example, the
dynamic_castoperator in C++ is implemented in an ABI-dependent way, typically by calling into a library function provided by the implementation. TheCXXABILoweringpass would thus replace allcir.dyn_castoperations with corresponding library function calls.
The CallConvLowering pass is dedicated to handle calling conventions. It
rewrites function signatures according to calling convention requirements,
and updates function body and call sites accordingly. For example, when
passing a large struct by value in C/C++, most ABIs require passing a
pointer to a copy of the struct instead. Thus, the CallConvLowering pass
would rewrite function signatures that take a value of a large struct type
to take a pointer to the struct type instead, and update the function body
and the call sites accordingly.
Operations#
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
min_is_poison | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
signed integer or vector of signed integer type |
Results:#
Result |
Description |
|---|---|
|
signed integer or vector of signed integer type |
cir.acos (::cir::ACosOp)#
Computes the arcus cosine of the specified value
Syntax:
operation ::= `cir.acos` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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, vector-of-integer or
matrix-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>
%5 = cir.add %ma, %mb : !cir.matrix<3 x 3 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector/matrix of integer type |
|
integer or vector/matrix of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector/matrix of integer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
|
Integer type with arbitrary precision up to a fixed limit |
Results:#
Result |
Description |
|---|---|
|
integer or boolean type |
|
CIR bool type |
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>
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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>>, ...
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
size | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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
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 |
Operands:#
Operand |
Description |
|---|---|
|
64-bit unsigned integer |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
integer, boolean, or vector of bool or integer |
|
integer, boolean, or vector of bool or integer |
Results:#
Result |
Description |
|---|---|
|
integer, boolean, or vector of bool or integer |
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
Operands:#
Operand |
Description |
|---|---|
|
pointer type |
|
integer type |
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
Operands:#
Operand |
Description |
|---|---|
|
pointer type |
|
integer type |
cir.asin (::cir::ASinOp)#
Computes the arcus sine of the specified value
Syntax:
operation ::= `cir.asin` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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
Interfaces: MemoryEffectOpInterface
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 |
Operands:#
Operand |
Description |
|---|---|
|
variadic of any non-token type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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).
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
bundle_kind | ::cir::AssumeBundleKindAttr | kind of cir.assume operand bundle |
Operands:#
Operand |
Description |
|---|---|
|
CIR bool type |
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.atan (::cir::ATanOp)#
Computes the floating-point arcus tangent value
Syntax:
operation ::= `cir.atan` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.atan2 (::cir::ATan2Op)#
Computes the arc tangent of y/x
Syntax:
operation ::= `cir.atan2` $lhs `,` $rhs `:` qualified(type($lhs))
(`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.atomic.clear (::cir::AtomicClearOp)#
Atomic clear
Syntax:
operation ::= `cir.atomic.clear` enum($mem_order) $ptr
(`align` `(` $alignment^ `)`)?
(`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>
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 |
Operands:#
Operand |
Description |
|---|---|
|
pointer to 8-bit signed integer |
cir.atomic.cmpxchg (::cir::AtomicCmpXchgOp)#
Atomic compare and exchange
Syntax:
operation ::= `cir.atomic.cmpxchg` (`weak` $weak^)?
`success` `(` enum($succ_order) `)` `failure` `(` enum($fail_order) `)`
`syncscope` `(` enum($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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
cir.atomic.fence (::cir::AtomicFenceOp)#
Atomic thread fence
Syntax:
operation ::= `cir.atomic.fence` (`syncscope` `(` enum($syncscope)^ `)`)? enum($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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
ordering | ::cir::MemOrderAttr | Memory order according to C++11 memory model |
syncscope | ::cir::SyncScopeKindAttr | sync scope kind |
cir.atomic.fetch (::cir::AtomicFetchOp)#
Atomic fetch-and-update operation
Syntax:
operation ::= `cir.atomic.fetch` enum($binop) enum($mem_order)
`syncscope` `(` enum($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, udec_wrap, maximum, minimum, maximum_num, and
minimum_num.
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.
The primary difference between max, maximum, and maximum_num is how
they handle floating-point inputs:
maxon floating-point inputs corresponds to theatomicrmw fmaxLLVM instruction.maximumcorresponds to theatomicrmw fmaximumLLVM instruction.maximum_numcorresponds to theatomicrmw fmaximumnumLLVM instruction.
Similar rules apply to min, minimum, and minimum_num. See the
reference for the LLVM instruction atomicrmw for more information.
The operation maximum, minimum, maximum_num, and minimum_num only
accept floating-point inputs.
Example:
: (!cir.ptr<!s32i>, !s32i) -> !s32i
Interfaces: InferTypeOpInterface
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 |
Operands:#
Operand |
Description |
|---|---|
|
pointer to integer or floating point type |
|
integer or floating point type |
Results:#
Result |
Description |
|---|---|
|
integer or floating point type |
cir.atomic.test_and_set (::cir::AtomicTestAndSetOp)#
Atomic test and set
Syntax:
operation ::= `cir.atomic.test_and_set` enum($mem_order) $ptr
(`align` `(` $alignment^ `)`)?
(`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
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 |
Operands:#
Operand |
Description |
|---|---|
|
pointer to 8-bit signed integer |
Results:#
Result |
Description |
|---|---|
|
CIR bool type |
cir.atomic.xchg (::cir::AtomicXchgOp)#
Atomic exchange
Syntax:
operation ::= `cir.atomic.xchg` enum($mem_order)
`syncscope` `(` enum($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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.await (::cir::AwaitOp)#
Wraps C++ co_await implicit logic
Syntax:
operation ::= `cir.await` `(` enum($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: HasAncestor<CoroutineOp>, NoRegionArguments, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::AwaitKindAttr | await kind |
cir.base_class_addr (::cir::BaseClassAddrOp)#
Get the base class address for a class/struct
Syntax:
operation ::= `cir.base_class_addr` (`nonnull` $assume_not_null^)?
$src_addr ` ` `[` $offset `]`
`:` qualified(type($src_addr)) `->` qualified(type($result))
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 nonnull %1 [0] : !cir.ptr<!rec_Derived> -> !cir.ptr<!rec_Base>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.base_data_member (::cir::BaseDataMemberOp)#
Cast a derived class data member pointer to a base class data member pointer
Syntax:
operation ::= `cir.base_data_member` $src `[` $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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
Results:#
Result |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
cir.base_method (::cir::BaseMethodOp)#
Cast a derived class pointer-to-member-function to a base class pointer-to-member-function
Syntax:
operation ::= `cir.base_method` $src `[` $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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
Results:#
Result |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
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
Operands:#
Operand |
Description |
|---|---|
|
CIR exception handling token type |
Results:#
Result |
Description |
|---|---|
|
CIR catch token type |
|
CIR pointer type |
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
Operands:#
Operand |
Description |
|---|---|
|
CIR exception handling token type |
Results:#
Result |
Description |
|---|---|
|
CIR cleanup token type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64 |
Results:#
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64 |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
block_addr_info | ::cir::BlockAddrInfoAttr | Block address attribute |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.br (::cir::BrOp)#
Unconditional branch
Syntax:
operation ::= `cir.br` $dest (`(` $destOperands^ `:` type($destOperands) `)`)?
(`loop_hints` $loop_hints^)? 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.
When a loop is flattened, the optional loop_hints attribute is placed on
the branches that form the loop’s back edge (see cir.brcond).
Example:
...
cir.br ^bb3
^bb3:
cir.return
Traits: AlwaysSpeculatableImplTrait, Terminator
Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
loop_hints | ::cir::LoopHintAttr | Optimizer hints and guarantees attached to a loop |
Operands:#
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
cir.brcond (::cir::BrCondOp)#
Conditional branch
Syntax:
operation ::= `cir.brcond` $cond
$destTrue (`(` $destOperandsTrue^ `:` type($destOperandsTrue) `)`)?
`,`
$destFalse (`(` $destOperandsFalse^ `:` type($destOperandsFalse) `)`)?
(`loop_hints` $loop_hints^)? attr-dict
The cir.brcond %cond, ^bb0, ^bb1 branches to ‘bb0’ block in case
it branches to ‘bb1’.
The optional loop_hints attribute is attached by CFG flattening to
branches that target a loop header (i.e. the loop’s back edge), carrying
the #cir.loop_hint of the original loop op.
Example:
...
cir.brcond %a, ^bb3, ^bb4
^bb3:
cir.return
^bb4:
cir.yield
Traits: AlwaysSpeculatableImplTrait, AttrSizedOperandSegments, Terminator
Interfaces: BranchOpInterface, ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
loop_hints | ::cir::LoopHintAttr | Optimizer hints and guarantees attached to a loop |
Operands:#
Operand |
Description |
|---|---|
|
CIR bool type |
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
cir.break (::cir::BreakOp)#
C/C++ break statement equivalent
Syntax:
operation ::= `cir.break` attr-dict
The cir.break operation is used to cease the 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
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{}
Operands:#
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit or integer or index |
Results:#
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit or integer or index |
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{}
Operands:#
Operand |
Description |
|---|---|
|
unsigned integer type with a width that is a multiple of 16 bits |
Results:#
Result |
Description |
|---|---|
|
unsigned integer type with a width that is a multiple of 16 bits |
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.
The calling_conv attribute specifies the calling convention used at the
call site. It defaults to CallingConv::C, which is omitted when printed.
Other calling conventions are printed as cc(<mnemonic>), e.g.
cc(spir_function).
Example:
%0 = cir.call @foo()
cir.call @bar() cc(spir_function) : () -> ()
Traits: NoRegionArguments
Interfaces: ArgAndResultAttrsOpInterface, CIRCallOpInterface, CallOpInterface, SymbolUserOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
nothrow | ::mlir::UnitAttr | unit attribute |
nounwind | ::mlir::UnitAttr | unit attribute |
willreturn | ::mlir::UnitAttr | unit attribute |
inline_kind | ::cir::InlineKindAttr | inline kind |
musttail | ::mlir::UnitAttr | unit attribute |
memory_effects | ::cir::MemoryEffectsAttr | Describes the possible memory effects of a function or callee |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
calling_conv | ::cir::CallingConvAttr | calling convention |
Operands:#
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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)
(`fastmath` `` $fastmath_flags^)? 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.
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
intrinsic_name | ::mlir::StringAttr | string attribute |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.case (::cir::CaseOp)#
Case operation
Syntax:
operation ::= `cir.case` `(` enum($kind) `,` $value `)` $caseRegion attr-dict
The cir.case operation represents a case within a C/C++ switch.
The cir.case operation must be in a cir.switch operation directly
or indirectly.
The cir.case have 4 kinds:
equal, <constant>: equality of the second case operand against the condition.anyof, [constant-list]: equals to any of the values in a subsequent following list.range, [lower-bound, upper-bound]: the condition is within the closed interval.default: any other value.
Each case region must be explicitly terminated.
Traits: AutomaticAllocationScope, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
value | ::mlir::ArrayAttr | array attribute |
kind | ::cir::CaseOpKindAttr | case kind |
cir.cast (::cir::CastOp)#
Conversion between values of different types
Syntax:
operation ::= `cir.cast` enum($kind) $src `:` type($src) `->` type($result)
(`fenv` `` $fenv^)? 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
The optional fenv attribute describes constraints on the floating-point
handling of the operation. It is only valid for floating-point cast kinds:
floating, int_to_float, float_to_int, float_to_bool,
bool_to_float, float_to_complex, float_complex_to_real,
float_complex_to_bool, float_complex, float_complex_to_int_complex,
and int_complex_to_float_complex.
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>
%y = cir.cast floating %f : !cir.double -> !cir.float fenv<>
Traits: CIR_FenvOpTrait
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, MemoryEffectsOpInterface, PromotableOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CastKindAttr | cast kind |
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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>
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.ceil (::cir::CeilOp)#
Computes the ceiling of the specified value
Syntax:
operation ::= `cir.ceil` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.cleanup.scope (::cir::CleanupScopeOp)#
Represents a scope with associated cleanup code
Syntax:
operation ::= `cir.cleanup.scope` $bodyRegion `cleanup` enum($cleanupKind) $cleanupRegion attr-dict
cir.cleanup.scope contains a body region and a cleanup region. The body
region runs first, and the cleanup region may run when the body region is
exited.
The cleanup kind attribute specifies which exits from the body region run the cleanup region:
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanupKind | ::cir::CleanupKindAttr | cleanup kind |
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.
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
cir.clear_padding (::cir::ClearPaddingOp)#
Clear Padding Operation
Syntax:
operation ::= `cir.clear_padding` `(` `align` `(` $alignment `)` $arg `,`
$padding `)` `:` type($arg) `->` `(` `)` attr-dict
This operation represents a __builtin_clear_padding call, which sets all
padding bits in the pointee arg to zero. The arg’s alignment is also
stored in this operation so we can properly emit the stores/loads later.
Offsets into the variable are stored as an OffsetPairAttr.
During LLVM-IR lowering, this is converted into getelementptr and store
operations.
Example:
cir.clear_padding(align(1) %1,
[#cir.offset_pair<0, 2>, #cir.offset_pair<6, 8>])
: <rec_Type> -> ()
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute whose minimum value is 1 |
padding | ::mlir::ArrayAttr | array of padding locations |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
signed integer type of widths 32/64 |
Results:#
Result |
Description |
|---|---|
|
signed integer type of widths 32/64 |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
poison_zero | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
Results:#
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
cir.cmp (::cir::CmpOp)#
Compare two values and produce a boolean result
Syntax:
operation ::= `cir.cmp` enum($kind) $lhs `,` $rhs `:` type($lhs)
(`fenv` `` $fenv^)? attr-dict
The cir.cmp operation compares two operands of the same type and produces
a !cir.bool result. It supports integral, boolean, floating-point, and
pointer types. Booleans (including enums with a boolean underlying type)
are compared as unsigned integers.
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.
The optional fenv attribute describes constraints on the floating-point
handling of the operation. It is only valid for floating-point
comparisons.
%0 = cir.cmp gt %1, %2 : !s32i
%1 = cir.cmp eq %a, %b : !cir.ptr<!u8i>
%2 = cir.cmp lt %x, %y : !cir.float fenv<>
Traits: CIR_FenvOpTrait, SameTypeOperands
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CmpOpKindAttr | compare operation kind |
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
comparable type |
|
comparable type |
Results:#
Result |
Description |
|---|---|
|
CIR bool type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
info | ::cir::CmpThreeWayInfoAttr | Holds information about a three-way comparison operation |
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
signed integer type |
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 the
body region of a cir.coroutine. It may be nested within other
operations or regions inside that body.
Traits: AlwaysSpeculatableImplTrait, HasAncestor<CoroutineOp>, ReturnLike, Terminator
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface
Effects: MemoryEffects::Effect{}
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<s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
complex of integer type |
|
complex of integer type |
Results:#
Result |
Description |
|---|---|
|
complex of integer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR complex type |
Results:#
Result |
Description |
|---|---|
|
CIR complex type |
cir.complex.create (::cir::ComplexCreateOp)#
Create a complex value from its real and imaginary parts
Syntax:
operation ::= `cir.complex.create` $real `,` $imag
`:` qualified(type($real)) `->` qualified(type($result)) attr-dict
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{}
Operands:#
Operand |
Description |
|---|---|
|
integer or floating point type |
|
integer or floating point type |
Results:#
Result |
Description |
|---|---|
|
CIR complex type |
cir.complex.div (::cir::ComplexDivOp)#
Complex division
Syntax:
operation ::= `cir.complex.div` $lhs `,` $rhs `:` qualified(type($result)) attr-dict
The cir.complex.div operation takes two complex numbers and returns
their quotient.
Example:
%2 = cir.complex.div %0, %1 : !cir.complex<s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
complex of integer type |
|
complex of integer type |
Results:#
Result |
Description |
|---|---|
|
complex of integer type |
cir.complex.fadd (::cir::ComplexFAddOp)#
Complex addition
Syntax:
operation ::= `cir.complex.fadd` $lhs `,` $rhs `:` qualified(type($result)) (`fenv` `` $fenv^)? attr-dict
The cir.complex.fadd operation takes two complex numbers and returns
their sum.
Example:
%2 = cir.complex.fadd %0, %1 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
|
complex of 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 |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.complex.fdiv (::cir::ComplexFDivOp)#
Complex division
Syntax:
operation ::= `cir.complex.fdiv` $lhs `,` $rhs `range` `(` enum($range) `)` `:` qualified(type($result))
attr-dict
The cir.complex.div operation takes two complex numbers and returns
their quotient.
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.fdiv %0, %1 range(basic) : !cir.complex<!cir.float>
%2 = cir.complex.fdiv %0, %1 range(full) : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
range | ::cir::ComplexRangeKindAttr | complex multiplication and division implementation |
Operands:#
Operand |
Description |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
|
complex of 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 |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.complex.fmul (::cir::ComplexFMulOp)#
Complex multiplication
Syntax:
operation ::= `cir.complex.fmul` $lhs `,` $rhs `range` `(` enum($range) `)` `:` qualified(type($result))
attr-dict
The cir.complex.mul operation takes two complex numbers and returns
their product.
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.fmul %0, %1 range(basic) : !cir.complex<!cir.float>
%2 = cir.complex.fmul %0, %1 range(full) : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
range | ::cir::ComplexRangeKindAttr | complex multiplication and division implementation |
Operands:#
Operand |
Description |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
|
complex of 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 |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.complex.fsub (::cir::ComplexFSubOp)#
Complex subtraction
Syntax:
operation ::= `cir.complex.fsub` $lhs `,` $rhs `:` qualified(type($result)) (`fenv` `` $fenv^)? attr-dict
The cir.complex.fsub operation takes two complex numbers and returns
their difference.
Example:
%2 = cir.complex.fsub %0, %1 : !cir.complex<!cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
|
complex of 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 |
|---|---|
|
complex of single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.complex.imag (::cir::ComplexImagOp)#
Extract the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag` $operand `:` qualified(type($operand)) `->` qualified(type($result))
attr-dict
cir.complex.imag operation takes an operand of !cir.complex, !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{}
Operands:#
Operand |
Description |
|---|---|
|
complex, integer, boolean or floating point type |
Results:#
Result |
Description |
|---|---|
|
integer, boolean or floating point type |
cir.complex.imag_ptr (::cir::ComplexImagPtrOp)#
Derive a pointer to the imaginary part of a complex value
Syntax:
operation ::= `cir.complex.imag_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.imag_ptr operation takes a pointer operand that points to a
complex value of type !cir.complex and yields a pointer to the imaginary
part of the operand.
Example:
%1 = cir.complex.imag_ptr %0 : !cir.ptr<!cir.complex<!cir.double>>
-> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
pointer to complex type |
Results:#
Result |
Description |
|---|---|
|
pointer to integer or floating point type |
cir.complex.mul (::cir::ComplexMulOp)#
Complex multiplication
Syntax:
operation ::= `cir.complex.mul` $lhs `,` $rhs `:` qualified(type($result)) attr-dict
The cir.complex.mul operation takes two complex numbers and returns
their product.
Example:
%2 = cir.complex.mul %0, %1 : !cir.complex<s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
complex of integer type |
|
complex of integer type |
Results:#
Result |
Description |
|---|---|
|
complex of integer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
complex, integer, boolean or floating point type |
Results:#
Result |
Description |
|---|---|
|
integer, boolean or floating point type |
cir.complex.real_ptr (::cir::ComplexRealPtrOp)#
Derive a pointer to the real part of a complex value
Syntax:
operation ::= `cir.complex.real_ptr` $operand `:`
qualified(type($operand)) `->` qualified(type($result)) attr-dict
cir.complex.real_ptr operation takes a pointer operand that points to a
complex value of type !cir.complex and yields a pointer to the real part
of the operand.
Example:
%1 = cir.complex.real_ptr %0 : !cir.ptr<!cir.complex<!cir.double>>
-> !cir.ptr<!cir.double>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
pointer to complex type |
Results:#
Result |
Description |
|---|---|
|
pointer to integer or floating point type |
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<s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
complex of integer type |
|
complex of integer type |
Results:#
Result |
Description |
|---|---|
|
complex of integer type |
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 `body` 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
Operands:#
Operand |
Description |
|---|---|
|
CIR bool type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
value | ::mlir::TypedAttr | TypedAttr instance |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.construct_catch_param (::cir::ConstructCatchParamOp)#
Construct a catch parameter from the in-flight exception
Syntax:
operation ::= `cir.construct_catch_param` enum($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 for the catch parameter. The optional
copy_fn attribute, present for non_trivial_copy, is a flat symbol
reference to a cir.func thunk that copies the exception object to a
local alloca value. For reference_to_pointer, the operation binds the
reference to the exception object itself.
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::InitCatchKindAttr | allowed i32 cases: 0, 1, 2, 3, 4, 5, 6, 7 |
copy_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR exception handling token type |
|
CIR pointer type |
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
cir.copy (::cir::CopyOp)#
Copies contents from a CIR pointer to another
Syntax:
operation ::= `cir.copy` $src (`align` `(` $src_alignment^ `)`)?
`to`
$dst (`align` `(` $dst_alignment^ `)`)?
(`volatile` $is_volatile^)?
(`skip_tail_padding` $skip_tail_padding^)?
attr-dict `:` custom<CopyTypes>(type($src), 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 pointers may differ in address space (e.g.
when assigning through an address-space-qualified pointer); when the two
pointer types differ, both are printed, src first.
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>
Interfaces: PromotableMemOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
dst_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
src_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
is_volatile | ::mlir::UnitAttr | unit attribute |
skip_tail_padding | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
cir.copysign (::cir::CopysignOp)#
Copies the sign of a floating-point value
Syntax:
operation ::= `cir.copysign` $lhs `,` $rhs `:` qualified(type($lhs))
(`fenv` `` $fenv^)? attr-dict
cir.copysign returns a value with the magnitude of the first operand
and the sign of the second operand.
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.coro.cleanup (::cir::CoroCleanupOp)#
Branches through the enclosing cleanups to the coroutine cleanup
Syntax:
operation ::= `cir.coro.cleanup` attr-dict
Placeholder emitted for the destroy case of a flattened cir.await.
Like cir.co_return, it leaves every enclosing cir.cleanup.scope
through its cleanup, so the destructors of locals in scope run first.
cir.coroutine flattening then rewrites it into a branch to the
destroy region, which frees the frame and continues to the exit
region. It must not survive flattening.
Traits: Terminator
cir.coro.exit (::cir::CoroExitOp)#
Branches to the enclosing cir.coroutine’s exit region
Syntax:
operation ::= `cir.coro.exit` attr-dict
Placeholder emitted while flattening cir.await. cir.coroutineflattening
rewrites it into a cir.br to the exit block.
It must not survive flattening.
Traits: Terminator
cir.coro.intrinsic.align (::cir::CoroAlignOp)#
Represents llvm.coro.align
Syntax:
operation ::= `cir.coro.intrinsic.align` `(` operands `)` `:` functional-type(operands, results) attr-dict
Returns the alignment requirement, in bytes, of the coroutine frame.
Results:#
Result |
Description |
|---|---|
|
fundamental unsigned integer type |
cir.coro.intrinsic.alloc (::cir::CoroAllocOp)#
Represents llvm.coro.alloc
Syntax:
operation ::= `cir.coro.intrinsic.alloc` `(` operands `)` `:` functional-type(operands, results) attr-dict
Queries whether the coroutine identified by id needs a dynamically
allocated frame. Returns true if the coroutine frame must be allocated,
or false otherwise.
Traits: TokenConsumerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
token |
Results:#
Result |
Description |
|---|---|
|
boolean type |
cir.coro.intrinsic.begin (::cir::CoroBeginOp)#
Represents llvm.coro.begin
Syntax:
operation ::= `cir.coro.intrinsic.begin` `(` operands `)` `:` functional-type(operands, results) attr-dict
Initializes the coroutine frame using coroframeAddr. id is the token
from coro.intrinsic.id, and coroframeAddr points to the memory used
for the coroutine frame. Returns the coroutine handle.
Traits: TokenConsumerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
token |
|
pointer to void type |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.destroy (::cir::CoroDestroyOp)#
Represents llvm.coro.destroy
Syntax:
operation ::= `cir.coro.intrinsic.destroy` `(` operands `)` `:` functional-type(operands, results) attr-dict
Destroys a suspended coroutine identified by handle. Destroying a
coroutine that is not currently suspended is undefined behavior.
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.done (::cir::CoroDoneOp)#
Represents llvm.coro.done
Syntax:
operation ::= `cir.coro.intrinsic.done` `(` operands `)` `:` functional-type(operands, results) attr-dict
Checks whether the coroutine identified by handle is currently
suspended at its final suspend point. handle must be a handle to a
suspended coroutine.
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
Results:#
Result |
Description |
|---|---|
|
CIR bool type |
cir.coro.intrinsic.end (::cir::CoroEndOp)#
Represents llvm.coro.end
Syntax:
operation ::= `cir.coro.intrinsic.end` `(` operands `)` `:` functional-type(operands, results) attr-dict
Marks a point at which a coroutine must be suspended or destroyed for the
last time, e.g. right before the coroutine returns control to its caller
for the final time, or along an exceptional unwind path. handle is the
coroutine handle produced by coro.intrinsic.begin, and unwind
indicates whether this occurrence of coro.intrinsic.end lies on the
unwind path (true) or the normal control-flow path (false).
Traits: TokenConsumerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
boolean type |
|
token |
Results:#
Result |
Description |
|---|---|
|
void type |
cir.coro.intrinsic.free (::cir::CoroFreeOp)#
Represents llvm.coro.free
Syntax:
operation ::= `cir.coro.intrinsic.free` `(` operands `)` `:` functional-type(operands, results) attr-dict
Given the coroutine identified by id and its frame pointer coroframe
(the handle from coro.intrinsic.begin), returns the pointer that must
be passed to the deallocation function to free the coroutine frame, or a
null pointer if the coroutine frame was not dynamically allocated.
Traits: TokenConsumerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
token |
|
pointer to void type |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.id (::cir::CoroIdOp)#
Represents llvm.coro.id
Syntax:
operation ::= `cir.coro.intrinsic.id` `(` operands `)` `:` functional-type(operands, results) attr-dict
Marks the beginning of a coroutine’s lifetime and identifies it to the rest of the coroutine intrinsics. Takes the required alignment of the coroutine frame, a pointer to the coroutine promise (or null if none), the address of the coroutine function itself, and an opaque pointer used by the frontend to convey additional information to the coroutine lowering passes (or null).
The result is a token that must be passed to every other
coro.intrinsic.* operation associated with this coroutine
(coro.alloc, coro.begin, coro.free, etc.), tying them all to the
same coroutine instance.
Traits: TokenProducerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
integer type |
|
pointer to void type |
|
pointer to void type |
|
pointer to void type |
Results:#
Result |
Description |
|---|---|
|
token |
cir.coro.intrinsic.noop (::cir::CoroNoopOp)#
Represents llvm.coro.noop
Syntax:
operation ::= `cir.coro.intrinsic.noop` `(` operands `)` `:` functional-type(operands, results) attr-dict
Returns a coroutine handle to a no-op coroutine.
Interfaces: InferTypeOpInterface
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.promise (::cir::CoroPromiseOp)#
Represents llvm.coro.promise
Syntax:
operation ::= `cir.coro.intrinsic.promise` `(` operands `)` `:` functional-type(operands, results) attr-dict
Given a coroutine handle (if isFromPromise is false) or a pointer to a
coroutine promise (if isFromPromise is true), obtains a pointer to the
coroutine promise or the coroutine handle, respectively. align is the
alignment requirement of the promise, and isFromPromise indicates the
direction of the transformation: true recovers the coroutine handle
from a promise pointer, false recovers the promise pointer from a
coroutine handle. Using this op on a coroutine without a coroutine
promise is undefined behavior.
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
integer type |
|
CIR bool type |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.resume (::cir::CoroResumeOp)#
Represents llvm.coro.resume
Syntax:
operation ::= `cir.coro.intrinsic.resume` `(` operands `)` `:` functional-type(operands, results) attr-dict
Resumes a suspended coroutine identified by handle. Resuming a
coroutine that is not currently suspended is undefined behavior.
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
cir.coro.intrinsic.save (::cir::CoroSaveOp)#
Represents llvm.coro.save
Syntax:
operation ::= `cir.coro.intrinsic.save` `(` operands `)` `:` functional-type(operands, results) attr-dict
cir.coro.intrinsic.save represents the llvm.coro.save intrinsic.
It marks the point where a coroutine needs to update its state to prepare for resumption, so that it is considered suspended (and thus eligible for resumption).
Traits: TokenProducerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
Results:#
Result |
Description |
|---|---|
|
token |
cir.coro.intrinsic.size (::cir::CoroSizeOp)#
Represents llvm.coro.size
Syntax:
operation ::= `cir.coro.intrinsic.size` `(` operands `)` `:` functional-type(operands, results) attr-dict
Returns the size, in bytes, of the coroutine frame.
Results:#
Result |
Description |
|---|---|
|
fundamental unsigned integer type |
cir.coro.intrinsic.suspend (::cir::CoroSuspendOp)#
Represents llvm.coro.suspend
Syntax:
operation ::= `cir.coro.intrinsic.suspend` `(` operands `)` `:` functional-type(operands, results) attr-dict
cir.coro.intrinsic.suspend represents the llvm.coro.suspend intrinsic.
It marks the point where execution of a switched-resume coroutine is suspended and control returns to the caller. The result value indicates how the coroutine should proceed: -1 if suspended, 0 if resumed, or 1 if destroyed.
The id operand is the token produced by a cir.coro.save that marks
the point when the coroutine state is prepared for suspension.
The final operand indicates whether this is a final suspend point.
If more than one suspend point is marked final, the resume and destroy
branches must lead to the same basic blocks.
Traits: TokenConsumerTrait
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
token |
|
boolean type |
Results:#
Result |
Description |
|---|---|
|
8-bit signed integer |
cir.coro.suspend_point (::cir::CoroSuspendPoint)#
Marks the point where a coroutine actually suspends
Syntax:
operation ::= `cir.coro.suspend_point` (`(` $cond^ `)`)? attr-dict
Terminates the suspend region of a cir.await. It has no explicit
successors; the destination is determined by CoroutineOp
according to how the suspended coroutine is subsequently handled:
resume: continues execution through the
cir.await’sresumeregion when the coroutine handle is resumed.exit: transfers directly to the enclosing
cir.coroutine’sexitregion when the coroutine remains suspended. The coroutine frame remains alive and no cleanups are performed.destroy: transfers through the enclosing
cir.cleanup.scopes to thecir.coroutine’sdestroyregion when the coroutine handle is destroyed.
When the optional cond operand is present, a false value vetoes the
suspension and control branches directly to the resume region of the
enclosing cir.await. A true value indicates the coroutine actually
suspends.
Traits: AlwaysSpeculatableImplTrait, HasParent<AwaitOp>, Terminator
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
boolean type |
cir.coroutine (::cir::CoroutineOp)#
Groups a coroutine’s structured suspend/resume/destroy control flow
Syntax:
operation ::= `cir.coroutine` `initialSuspend` `:` $initialSuspend `,`
`body` `:` $body `,`
`finalSuspend` `:` $finalSuspend `,`
`destroy` `:` $destroy `,`
`exit` `:` $exit
attr-dict
cir.coroutine is an op consisting of seven regions: initial_suspend,
body, final_suspend, grp (TODO),unwind (TODO), destroy, andexit.
initial_suspend: the coroutine ramp/setup region. Itscir.awaitmarkedinitis the ramp boundary: the coroutine frame and its associated state are established before this point, and crossing the await transfers execution tobody.body: the user-written coroutine body, arbitrary CFG, zero or morecir.awaits at any nesting depth, terminated bycir.co_returnor a plaincir.yieldif control simply falls off the end. This region is a structural boundary separating the coroutine’s setup and teardown logic (initial suspend, final suspend, destroy) from the user-provided statements of the original function body, includingco_awaitandco_returnexpressions. In particular,cir.co_returnoperations inside this region mark coroutine exit points and introduce structured control flow that transfers execution tofinal_suspend.final_suspend: at most onecir.await, markedfinal. Nothing else. Corresponds toco_await promise.final_suspend(). Suspending at this final suspend point is valid: the coroutine stays suspended until it is destroyed. Resuming past this point is undefined behavior in valid programs, so itsresumeedge is expected to be dead in practice, but is kept for structural symmetry with the other two suspend regions.gro: TODO.unwind: TODO.destroy: destroys the coroutine frame (coro.free+delete). Reached by an explicitdestroy()call on a suspended handle, by normal completion throughinitial_suspend,final_suspend, or by an exception escaping the coroutine. Falls through toexitexcept when reached due to an escaping exception, where it continues propagating that exception instead.exit: the shared return-to-caller path. Reached directly from any suspend point that isn’t being destroyed (the coroutine is just pausing), and fromdestroywhen it was entered via ordinary dispatch. Holdscoro.end+ the actualcir.return.
Traits: AutomaticAllocationScope, NoRegionArguments, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
cir.cos (::cir::CosOp)#
Computes the floating-point cosine value
Syntax:
operation ::= `cir.cos` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.cosh (::cir::CoshOp)#
Computes the floating-point hyperbolic cosine value
Syntax:
operation ::= `cir.cosh` $src `:` type($src) (`fenv` `` $fenv^)? attr-dict
cir.cosh computes the hyperbolic 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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)
Operands:#
Operand |
Description |
|---|---|
|
pointer to 32-bit signed integer |
|
32-bit signed integer |
|
32-bit signed integer |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
poison_zero | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
Results:#
Result |
Description |
|---|---|
|
unsigned integer type of widths 8/16/32/64/128 |
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{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector of integer type |
cir.delete_array (::cir::DeleteArrayOp)#
Delete address representing an array
Syntax:
operation ::= `cir.delete_array` $address `:` qualified(type($address))
`delete_fn` `(` $delete_fn `)`
(`delete_params` `` $delete_params^)?
(`element_dtor` `(` $element_dtor^ `)`)?
(`dtor_may_throw` $dtor_may_throw^)?
`element_align` `(` $element_align `)`
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 optional delete_params attribute describes the parameters needed by
the operator delete call. When absent, all parameters have default values.
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.
The element_align attribute gives the element type’s preferred
alignment in bytes, which should be the same value the corresponding new[]
uses to size its array cookie.
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 |
element_align | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
cir.derived_class_addr (::cir::DerivedClassAddrOp)#
Get the derived class address for a class/struct
Syntax:
operation ::= `cir.derived_class_addr` (`nonnull` $assume_not_null^)?
$src_addr ` ` `[` $offset `]`
`:` qualified(type($src_addr)) `->` qualified(type($result))
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.derived_class_addr %2 [0] : !cir.ptr<!rec_A> -> !cir.ptr<!rec_B>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
assume_not_null | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.derived_data_member (::cir::DerivedDataMemberOp)#
Cast a base class data member pointer to a derived class data member pointer
Syntax:
operation ::= `cir.derived_data_member` $src `[` $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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
Results:#
Result |
Description |
|---|---|
|
CIR type that represents a pointer-to-data-member in C++ |
cir.derived_method (::cir::DerivedMethodOp)#
Cast a base class pointer-to-member-function to a derived class pointer-to-member-function
Syntax:
operation ::= `cir.derived_method` $src `[` $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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
offset | ::mlir::IntegerAttr | index attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
Results:#
Result |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
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
or matrix-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>
%3 = cir.div %ma, %mb : !cir.matrix<3 x 3 x !s32i>
Traits: SameOperandsAndResultType
Interfaces: BinaryOpInterface, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector/matrix of integer type |
|
integer or vector/matrix of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector/matrix of integer type |
cir.do (::cir::DoWhileOp)#
C/C++ do-while loop
Syntax:
operation ::= `cir.do` $body `while` $cond (`loop_hints` $loop_hints^)? attr-dict
Represents a C/C++ do-while loop. Identical to cir.while but the
condition is evaluated after the body. Because a variable cannot be
declared in the condition of a do-while loop, this operation cannot
have a cleanup region. A cleanup scope should be created within the
body region for any variables within the loop that require cleanup.
Example:
cir.do {
cir.break
^bb2:
cir.yield
} while {
cir.condition(%cond)
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
loop_hints | ::cir::LoopHintAttr | Optimizer hints and guarantees attached to a loop |
cir.dyn_cast (::cir::DynamicCastOp)#
Perform dynamic cast on record pointers
Syntax:
operation ::= `cir.dyn_cast` enum($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
>
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 |
Operands:#
Operand |
Description |
|---|---|
|
pointer to record type |
Results:#
Result |
Description |
|---|---|
|
pointer to any of CIR void type, CIR struct/class type, CIR union type |
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.
A handler may also be a filter, which carries the list of type info
symbols permitted by the dynamic exception specification of the enclosing
function. A filter handler has the opposite polarity from a catch
handler: its destination is taken when the in-flight exception is not
one of the listed types. The polarity comes from the Itanium personality
routine, which reports a filter failure by selecting the filter clause of
the landing pad. A filter handler therefore does not take the place of
the default destination, and a dispatch that has one always also has an
unwind handler, whose destination is taken when the exception is
permitted. A dispatch has at most one filter handler.
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
]
cir.eh.dispatch %eh_token : !cir.eh_token [
filter(#cir.global_view<@_ZTIi> : !cir.ptr<!u8i>)
: ^specification_violated,
unwind : ^exception_permitted
]
Traits: Terminator
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
catch_types | ::mlir::ArrayAttr | array attribute |
default_is_catch_all | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR exception handling token type |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
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^)?
(`filter` $filter_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.
The filter_type_list attribute lists the type info symbols permitted by
the dynamic exception specification of the enclosing function. It lowers to
the filter clause of the LLVM IR landingpad instruction. An empty list is
distinct from an absent one: it represents throw() and lowers to a
zero-length filter clause, which the personality routine treats as
permitting nothing. Since the exception specification encloses the whole
function body, the filter clause always comes after any catch clauses, and
it terminates the clause list in the same way that catch_all does.
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]
%exception_ptr, %type_id = cir.eh.inflight_exception filter [@_ZTIi]
%exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi] filter []
Interfaces: InferTypeOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanup | ::mlir::UnitAttr | unit attribute |
catch_all | ::mlir::UnitAttr | unit attribute |
catch_type_list | ::mlir::ArrayAttr | flat symbol ref array attribute |
filter_type_list | ::mlir::ArrayAttr | flat symbol ref array attribute |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
|
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:
%eh_token = cir.eh.initiate : !cir.eh_token
cir.br ^dispatch(%eh_token : !cir.eh_token)
^unwind_with_cleanup:
%eh_token = cir.eh.initiate cleanup : !cir.eh_token
cir.br ^cleanup(%eh_token : !cir.eh_token)
Interfaces: InferTypeOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanup | ::mlir::UnitAttr | unit attribute |
Results:#
Result |
Description |
|---|---|
|
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 |
|---|---|
|
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:
%0 = cir.eh.setjmp %arg0 : (!cir.ptr<!cir.void>) -> !s32i
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
32-bit signed integer |
cir.eh.terminate (::cir::EhTerminateOp)#
Terminate due to an exception that must not escape
Syntax:
operation ::= `cir.eh.terminate` $eh_token `:` type($eh_token) attr-dict
cir.eh.terminate terminates program execution when an exception reaches a
point from which the C++ standard does not allow it to propagate, and
requires std::terminate() to be called instead. That happens when an
exception is thrown while executing cleanup code during unwinding, and when
an exception tries to escape a function that cannot throw.
This operation takes an !cir.eh_token and acts as a terminator. In
high-level CIR it appears as the only operation in the catch-all handler
region of the cir.try that wraps the body of a function that cannot
throw, where the token comes from the handler region’s block argument. The
handler is a catch-all because such a function terminates on any escaping
exception, and it has no cir.begin_catch because the runtime helper this
operation lowers to performs the catch. After CFG flattening the token
comes from a cir.eh.initiate operation; flattening also produces this
operation for throwing calls 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:
cir.try {
...
} catch all (%eh_token : !cir.eh_token) {
cir.eh.terminate %eh_token : !cir.eh_token
}
And after CFG flattening:
^terminate_unwind:
%eh_token = cir.eh.initiate : !cir.eh_token
cir.eh.terminate %eh_token : !cir.eh_token
Traits: Terminator
Operands:#
Operand |
Description |
|---|---|
|
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:
%type_id = cir.eh.typeid @_ZTIi
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), SymbolUserOpInterface
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
type_sym | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Results:#
Result |
Description |
|---|---|
|
32-bit unsigned integer |
cir.eh.unexpected (::cir::EhUnexpectedOp)#
Handle an exception that violates an exception specification
Syntax:
operation ::= `cir.eh.unexpected` $eh_token `:` type($eh_token) attr-dict
cir.eh.unexpected signals that the in-flight exception violated the
dynamic exception specification of the enclosing function, and that
std::unexpected() must be called. The C++ standard requires this when an
exception that the specification does not permit tries to escape the
function.
This operation takes a !cir.eh_token and acts as a terminator. In
high-level CIR it is the only operation in the unexpected handler region
of a cir.try operation, where the token comes from the handler region’s
block argument. After CFG flattening the token comes from a
cir.eh.initiate operation.
Like cir.eh.terminate, this operation is ABI-agnostic. During EH ABI
lowering it is replaced with target-specific code. For the Itanium ABI it
becomes a call to __cxa_call_unexpected with the exception pointer,
followed by an unreachable operation.
Example:
^unexpected:
%eh_token = cir.eh.initiate : !cir.eh_token
cir.eh.unexpected %eh_token : !cir.eh_token
Traits: Terminator
Operands:#
Operand |
Description |
|---|---|
|
CIR exception handling token type |
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) {
%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
}
}
// Flattened form:
^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
Operands:#
Operand |
Description |
|---|---|
|
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):
%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)
Operands:#
Operand |
Description |
|---|---|
|
CIR cleanup token type |
cir.exp (::cir::ExpOp)#
Computes the floating-point base-e exponential value
Syntax:
operation ::= `cir.exp` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.exp10 (::cir::Exp10Op)#
Computes the floating-point base-10 exponential value
Syntax:
operation ::= `cir.exp10` $src `:` type($src) (`fenv` `` $fenv^)? attr-dict
cir.exp10 computes the base-10 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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:#
| Attribute | MLIR Type | Description |
|---|---|---|
prob | ::mlir::FloatAttr | 64-bit float attribute |
Operands:#
Operand |
Description |
|---|---|
|
fundamental integer type |
|
fundamental integer type |
Results:#
Result |
Description |
|---|---|
|
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.
%0 = cir.const #cir.const_record<{#cir.int<1> : !s32i,
#cir.int<2> : !s8i}> : !record_ty
// Extract the value of the second member of the record.
%1 = cir.extract_member %0[1] : !record_ty -> !s8i
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
index | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR record type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.fadd (::cir::FAddOp)#
Floating-point addition
Syntax:
operation ::= `cir.fadd` $lhs `,` $rhs `:` type($lhs) (`fenv` `` $fenv^)? prop-dict 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,
vector-of-float or matrix-of-float type.
Example:
%0 = cir.fadd %a, %b : !cir.float
%1 = cir.fadd %a, %b : !cir.double
%2 = cir.fadd %va, %vb : !cir.vector<4 x !cir.float>
%3 = cir.fadd %ma, %mb : !cir.matrix<3 x 3 x !cir.float>
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
|
floating point or vector/matrix of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
cir.fdiv (::cir::FDivOp)#
Floating-point division
Syntax:
operation ::= `cir.fdiv` $lhs `,` $rhs `:` type($lhs) (`fenv` `` $fenv^)? prop-dict 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
ector-of-float or matrix-of-float type.
Example:
%0 = cir.fdiv %a, %b : !cir.float
%1 = cir.fdiv %a, %b : !cir.double
%2 = cir.fdiv %va, %vb : !cir.vector<4 x !cir.float>
%3 = cir.fdiv %ma, %mb : !cir.matrix<3 x 3 x !cir.float>
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
|
floating point or vector/matrix of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector/matrix 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
%0 = cir.const #cir.int<40> : !s32i
// #1 will be 4 since the 4th least significant bit is 1.
%1 = cir.ffs %0 : !s32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
signed integer type of widths 32/64 |
Results:#
Result |
Description |
|---|---|
|
signed integer type of widths 32/64 |
cir.floor (::cir::FloorOp)#
Computes the floating-point floor value
Syntax:
operation ::= `cir.floor` $src `:` type($src) (`fenv` `` $fenv^)? 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
%y = cir.floor %x : !cir.double
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.fma (::cir::FMAOp)#
Fused Multiply-Add operation
Syntax:
operation ::= `cir.fma` $a `,` $b `,` $c `:` type($a) (`fenv` `` $fenv^)? attr-dict
Computes the fused multiply-add of three floating-point values or vector.
The inputs must be either: • floating-point scalar types, or • vectors whose element type is floating-point.
The result type must match the input type exactly.
Examples: // scalar
// vector
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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))
(`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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))
(`fenv` `` $fenv^)? attr-dict
cir.fmaxnum returns the larger of its two operands. If one operand is
NaN, the other operand is returned.
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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))
(`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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))
(`fenv` `` $fenv^)? attr-dict
cir.fminnum returns the smaller of its two operands. If one operand is
NaN, the other operand is returned.
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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))
(`fenv` `` $fenv^)? attr-dict
cir.fmod computes the floating-point remainder of dividing the first
operand by the second operand.
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.fmul (::cir::FMulOp)#
Floating-point multiplication
Syntax:
operation ::= `cir.fmul` $lhs `,` $rhs `:` type($lhs) (`fenv` `` $fenv^)? prop-dict 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:
%0 = cir.fmul %a, %b : !cir.float
%1 = cir.fmul %a, %b : !cir.double
%2 = cir.fmul %va, %vb : !cir.vector<4 x !cir.float>
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
|
floating point or vector/matrix of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
cir.fmuladd (::cir::FMulAddOp)#
Contractable fused multiply-add operation
Syntax:
operation ::= `cir.fmuladd` $a `,` $b `,` $c `:` type($a) (`fenv` `` $fenv^)? attr-dict
Computes (a * b) + c, allowing the multiply and add to be fused (or not)
into a single rounding step at the target’s discretion. It lowers to the
llvm.fmuladd intrinsic (or its constrained variant when an fenv
attribute is present).
Unlike cir.fma, which maps to llvm.fma and guarantees a single
rounding, cir.fmuladd expresses the FP-contraction relaxation used for
a * b + c under -ffp-contract=on / fast, where the backend is free to
emit either a fused or an unfused sequence.
The inputs must be either: • floating-point scalar types, or • vectors whose element type is floating-point.
The result type must match the input type exactly.
Examples: // scalar
// vector
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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:
%1 = cir.fneg %0 : !cir.float
%3 = cir.fneg %2 : !cir.double
%5 = cir.fneg %4 : !cir.vector<4 x !cir.float>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface), UnaryOpInterface
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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
(`cleanup` enum($cleanupKind) $cleanup^)?
(`loop_hints` $loop_hints^)?
attr-dict
Represents a C/C++ for loop. It consists of three or four 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.step: single block region with the loop’s step.cleanup: optional region that runs on every per-iteration exit edge (condition-false exit, end-of-iteration after the step, break/continue, and EH unwinding when the cleanup kind includes EH). This is used to destroy a condition variable whose lifetime is a single iteration. When present, it carries a cleanup kind matchingcir.cleanup.scope(normalorall).
Example:
cir.for : cond {
cir.condition(%val)
} body {
cir.break
^bb2:
cir.yield
} step {
cir.yield
}
cir.for : cond {
cir.condition(%val)
} body {
cir.yield
} step {
cir.yield
} cleanup all {
cir.yield
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanupKind | ::cir::CleanupKindAttr | cleanup kind |
loop_hints | ::cir::LoopHintAttr | Optimizer hints and guarantees attached to a loop |
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:
%p = frame_address(%level) : !cir.ptr<!u8i>
Operands:#
Operand |
Description |
|---|---|
|
32-bit unsigned integer |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.freeze (::cir::FreezeOp)#
Stop propagation of undef and poison values
Syntax:
operation ::= `cir.freeze` $input `:` type($input) attr-dict
The cir.freeze operation takes a single operand and returns a value of the
same type. If the operand is a poison or undef value, cir.freeze returns
an arbitrary, but fixed, value of the operand type. Otherwise it returns
the operand unchanged.
Example:
%1 = cir.freeze %0 : !s32i
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.frem (::cir::FRemOp)#
Floating-point remainder
Syntax:
operation ::= `cir.frem` $lhs `,` $rhs `:` type($lhs) (`fenv` `` $fenv^)? prop-dict 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:
%0 = cir.frem %a, %b : !cir.float
%1 = cir.frem %a, %b : !cir.double
%2 = cir.frem %va, %vb : !cir.vector<4 x !cir.float>
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
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:
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
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 |
Results:#
Result |
Description |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
|
integer type |
cir.fshl (::cir::FshlOp)#
Funnel shift left
Syntax:
operation ::= `cir.fshl` $a `,` $b `,` $c `:` type($a) attr-dict
The cir.fshl operation concatenates a and b (with a in the high
half), shifts the concatenation left by c bit positions, and returns the
high half of the result. The shift amount is treated modulo the bitwidth
of the operands.
All operands and the result must have the same integer type or vector-of-integer type.
Example:
%r = cir.fshl %a, %b, %c : !u32i
%v = cir.fshl %va, %vb, %vc : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
|
integer or vector of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector of integer type |
cir.fshr (::cir::FshrOp)#
Funnel shift right
Syntax:
operation ::= `cir.fshr` $a `,` $b `,` $c `:` type($a) attr-dict
The cir.fshr operation concatenates a and b (with a in the high
half), shifts the concatenation right by c bit positions, and returns
the low half of the result. The shift amount is treated modulo the bitwidth
of the operands.
All operands and the result must have the same integer type or vector-of-integer type.
Example:
%r = cir.fshr %a, %b, %c : !u32i
%v = cir.fshr %va, %vb, %vc : !cir.vector<4 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
|
integer or vector of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector of integer type |
cir.fsub (::cir::FSubOp)#
Floating-point subtraction
Syntax:
operation ::= `cir.fsub` $lhs `,` $rhs `:` type($lhs) (`fenv` `` $fenv^)? prop-dict 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 vector-of-float or matrix-of-float type.
Example:
%0 = cir.fsub %a, %b : !cir.float
%1 = cir.fsub %a, %b : !cir.double
%2 = cir.fsub %va, %vb : !cir.vector<4 x !cir.float>
%3 = cir.fsub %ma, %mb : !cir.matrix<3 x 3 x !cir.float>
Traits: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector/matrix of floating point type |
|
floating point or vector/matrix of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector/matrix 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).
The ‘comdat’ attribute marks the function as belonging to a COMDAT group. This attribute includes an optional ‘group’ name, which if not provided, results in the function’s symbol name being used.
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<i8>, !cir.bool) -> !cir.bool
// Coroutine
cir.func coroutine @_Z10silly_taskv() -> !CoroTask {
...
cir.await(...)
...
}
Traits: AutomaticAllocationScope, IsolatedFromAbove, SymbolName, SymbolVisibility
Interfaces: ArgAndResultAttrsOpInterface, CIRGlobalValueInterface, CallableOpInterface, FunctionOpInterface, Symbol
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
sym_name | ::mlir::StringAttr | string attribute |
function_type | ::mlir::TypeAttr | type attribute of CIR function type |
builtin | ::mlir::UnitAttr | unit attribute |
coroutine | ::mlir::UnitAttr | unit attribute |
flattened_coroutine | ::mlir::UnitAttr | unit attribute |
inline_kind | ::cir::InlineKindAttr | inline kind |
lambda | ::mlir::UnitAttr | unit attribute |
no_proto | ::mlir::UnitAttr | unit attribute |
dso_local | ::mlir::UnitAttr | unit attribute |
linkage | ::cir::GlobalLinkageKindAttr | linkage kind |
calling_conv | ::cir::CallingConvAttr | calling convention |
sym_visibility | ::mlir::StringAttr | string attribute |
comdat | ::mlir::StringAttr | string attribute |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
preferred_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
aliasee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
memory_effects | ::cir::MemoryEffectsAttr | Describes the possible memory effects of a function or callee |
personality | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
global_ctor_priority | ::mlir::IntegerAttr | 32-bit signless integer attribute whose minimum value is 101 whose maximum value is 65535 |
global_dtor_priority | ::mlir::IntegerAttr | 32-bit signless integer attribute whose minimum value is 101 whose maximum value is 65535 |
func_info | ::mlir::Attribute | function information attribute |
annotations | ::mlir::ArrayAttr | array of cir.annotation attributes |
uwtable | ::cir::UnwindTableKindAttr | Encodes the unwind table kind for a function. |
frame_pointer | ::cir::FramePointerKindAttr | Encodes the frame pointer kind for a function or a module. |
cir.get_bitfield (::cir::GetBitfieldOp)#
Get the information for a bitfield member
Syntax:
operation ::= `cir.get_bitfield` (`align` `(` $alignment^ `)`)?
` ` `(`$bitfield_info `,` $addr
(` ` `{` `is_volatile` $is_volatile^ `}`)? 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.
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.struct<"S" packed {!u64i, !u16i,
pad !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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
integer or boolean type |
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
Operands:#
Operand |
Description |
|---|---|
|
pointer to array type |
|
fundamental integer type |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
tls | ::mlir::UnitAttr | unit attribute |
static_local | ::mlir::UnitAttr | unit attribute |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.get_member (::cir::GetMemberOp)#
Get the address of a member of a record
Syntax:
operation ::= `cir.get_member` $addr `[` $index_attr `]` `{` `name` `=` $name `}` 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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::StringAttr | string attribute |
index_attr | ::mlir::IntegerAttr | index attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.get_method (::cir::GetMethodOp)#
Resolve a method to a function pointer as callee
Syntax:
operation ::= `cir.get_method` $method `,` $object
`:` `(` qualified(type($method)) `,` qualified(type($object)) `)`
`->` `(` qualified(type($callee)) `,` qualified(type($adjusted_this)) `)`
attr-dict
The cir.get_method operation takes a 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.
Operands:#
Operand |
Description |
|---|---|
|
CIR type that represents C++ pointer-to-member-function type |
|
pointer to record type |
Results:#
Result |
Description |
|---|---|
|
pointer to function type |
|
pointer to void type |
cir.get_runtime_member (::cir::GetRuntimeMemberOp)#
Get the address of a member of a record
Syntax:
operation ::= `cir.get_runtime_member` $addr `[` $member `:` qualified(type($member)) `]` attr-dict
`:` qualified(type($addr)) `->` qualified(type($result))
The cir.get_runtime_member operation gets the address of a member from
the input record. The target member is given by a value of type
!cir.data_member (i.e. a pointer-to-data-member value).
This operation differs from cir.get_member in when the target member can
be determined. For the cir.get_member operation, the target member is
specified as a constant index so the member it returns access to is known
when the operation is constructed. For the cir.get_runtime_member
operation, the target member is given through a pointer-to-data-member
value which is unknown until the program being compiled is executed. In
other words, cir.get_member represents a normal member access through the
. operator in C/C++:
struct Foo { int x; };
Foo f;
(void)f.x; // cir.get_member
And cir.get_runtime_member represents a member access through the .* or
the ->* operator in C++:
struct Foo { int x; }
Foo f;
Foo *p;
int Foo::*member;
(void)f.*member; // cir.get_runtime_member
(void)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{}
Operands:#
Operand |
Description |
|---|---|
|
pointer to record type |
|
CIR type that represents a pointer-to-data-member in C++ |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.global (::cir::GlobalOp)#
Declare or define a global variable
Syntax:
operation ::= `cir.global` ($sym_visibility^)?
($global_visibility^)?
(`constant` $constant^)?
enum($linkage)
custom<ComdatName>($comdat)
(`tls_model` `=` enum($tls_model)^)?
(`tls_refs` `=` $tls_refs^)?
(`dso_local` $dso_local^)?
(`dynamic_init_guard` `` $dynamic_init_guard^)?
(` ` custom<GlobalMemorySpace>($addr_space)^ )?
$sym_name
(`alias` `(` $aliasee^ `)`)?
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value,
$ctorRegion, $dtorRegion)
($annotations^)?
(`align` `(` $alignment^ `)`)?
(`ast` `(` $ast^ `)`)?
(`dynamic_init_info` `` $dynamic_init_info^)?
(`section` `(` $section^ `)`)?
(`strictfp` $strictfp^)?
(`init_priority` `(` $init_priority^ `)`)?
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 dynamic_init_guard attribute indicates that this global requires
guarded dynamic initialization via the Itanium __cxa_guard_* protocol
(e.g., C++ static local variables with non-constant initializers, or
namespace-scope variables with vague linkage such as weak/linkonce_odr
inline variables). It contains the mangled name of the guard variable.
The strictfp attribute indicates that the dynamic initialization emitted
into the ctorRegion/dtorRegion runs under a constrained floating-point
environment. LoweringPrepare forwards it to the strictfp attribute of the
generated __cxx_global_var_init function.
The init_priority attribute records the priority specified by a
C++ init_priority attribute on the source variable declaration.
LoweringPrepare uses it to place the dynamic initializer emitted from
ctorRegion into a priority-specific _GLOBAL__I_<priority> function
instead of the default _GLOBAL__sub_I_* function.
Traits: NoRegionArguments, SymbolName, SymbolVisibility
Interfaces: CIRGlobalValueInterface, RegionBranchOpInterface, Symbol
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::TLSModelAttr | TLS model |
tls_refs | ::cir::ThreadLocalGlobalWrapperInitAttr | Wrapper and Init function names for thread local variables |
initial_value | ::mlir::Attribute | any attribute |
comdat | ::mlir::StringAttr | string attribute |
dynamic_init_guard | ::cir::DynamicInitGuardAttr | Guard variable name for guarded dynamic initialization |
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
ast | ::cir::ASTVarDeclInterface | ASTVarDeclInterface instance |
dynamic_init_info | ::cir::DynamicInitInfoAttr | Variable facts needed by guarded dynamic initialization lowering |
section | ::mlir::StringAttr | string attribute |
annotations | ::mlir::ArrayAttr | array of cir.annotation attributes |
aliasee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
strictfp | ::mlir::UnitAttr | unit attribute |
init_priority | ::mlir::IntegerAttr | 32-bit signless integer attribute |
cir.goto (::cir::GotoOp)#
Syntax:
operation ::= `cir.goto` $label attr-dict
Transfers control to the specified label. This requires a corresponding
cir.label to exist and is used by to represent source level gotos
that jump across region boundaries. Alternatively, cir.br is used to
construct goto’s that don’t violate such boundaries.
cir.goto is completely symbolic (i.e. it “jumps” on a label that isn’t
yet materialized) and should be taken into account by passes and analysis
when deciding if it’s safe to make some assumptions about a given region
or basic block.
Example:
int test(int x) {
if (x)
goto label;
{
x = 10;
label:
return x;
}
}
cir.scope { // REGION #1
%2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
%3 = cir.cast int_to_bool %2 : !s32i -> !cir.bool
cir.if %3 {
cir.goto "label"
}
}
cir.scope { // REGION #2
%2 = cir.const #cir.int<10> : !s32i
cir.store %2, %0 : !s32i, !cir.ptr<!s32i>
cir.br ^bb1
^bb1: // pred: ^bb0
cir.label "label"
%3 = cir.load %0 : !cir.ptr<!s32i>, !s32i
cir.store %3, %1 : !s32i, !cir.ptr<!s32i>
%4 = cir.load %1 : !cir.ptr<!s32i>, !s32i
cir.return %4 : !s32i
}
cir.unreachable
Traits: Terminator
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
label | ::mlir::StringAttr | string attribute |
cir.if (::cir::IfOp)#
The if-then-else operation
The cir.if operation represents an if-then-else construct for
conditionally executing two regions of code. The operand is a cir.bool
type.
Examples:
cir.if %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
Operands:#
Operand |
Description |
|---|---|
|
CIR bool type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector of integer type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
poison | ::mlir::UnitAttr | unit attribute |
operand_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
variadic of any non-token type |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
cir.indirect_goto (::cir::IndirectGotoOp)#
Symbolic indirect goto
Syntax:
operation ::= `cir.indirect_goto` $addr `:` qualified(type($addr)) attr-dict
Transfers control to the block whose address is held in $addr, the
void-pointer value of a goto *expr; (the GNU computed-goto extension).
Like cir.goto, it is symbolic: it references no successor block, so it is
valid inside any region even before FlattenCFG merges nested scopes.
GotoSolver runs after FlattenCFG and rewrites each cir.indirect_goto
into a cir.br to a shared block holding a cir.indirect_br over every
address-taken label.
Example:
%0 = cir.load %p : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
cir.indirect_goto %0 : !cir.ptr<!void>
Traits: Terminator
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
cir.init_catch_param (::cir::InitCatchParamOp)#
Initialize a catch parameter from the exception pointer
Syntax:
operation ::= `cir.init_catch_param` enum($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).
A catch parameter that is a reference to a pointer uses the
reference_to_record_pointer kind when the pointer’s source-level pointee
type is a record (class, struct, or union), and reference_to_pointer
otherwise. A reference to any other type uses reference.
A reference_to_pointer or non_trivial_copy operation requires its catch
handler to start with a cir.construct_catch_param of the same kind on the
same parameter. When the handler starts with a cir.construct_catch_param
on the parameter of the operation, the two must have the same kind.
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>
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::InitCatchKindAttr | allowed i32 cases: 0, 1, 2, 3, 4, 5, 6, 7 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
index | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR record type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR record type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR bool type |
cir.is_fp_class (::cir::IsFPClassOp)#
Corresponding to the __builtin_fpclassify builtin function in clang
Syntax:
operation ::= `cir.is_fp_class` $src `,` enum($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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
flags | ::cir::FPClassTestAttr | floating-point class test flags |
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 |
Results:#
Result |
Description |
|---|---|
|
CIR bool type |
cir.label (::cir::LabelOp)#
Syntax:
operation ::= `cir.label` $label attr-dict
An identifier which may be referred by cir.goto operation
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
label | ::mlir::StringAttr | string attribute |
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
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.libc.memchr (::cir::MemChrOp)#
Libc’s memchr
Syntax:
operation ::= `cir.libc.memchr` `(` $src `,` $pattern `,` $len `)` attr-dict
`:` qualified(type($src)) `,` qualified(type($pattern)) `,`
qualified(type($len))
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.
pattern has the width of the target int and len has the width of
the target size_t. The module records these widths as
cir.int_type_width and cir.size_type_width, each a signless i32
holding a fundamental integer width, and the verifier checks the
operands against them. src must be a void pointer in the default
address space and result has the same type as src.
Examples:
%p = cir.libc.memchr(%src, %pattern, %len) : !cir.ptr<!void>, !s32i, !u64i
Interfaces: InferTypeOpInterface
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
fundamental signed integer type |
|
fundamental unsigned integer type |
Results:#
Result |
Description |
|---|---|
|
pointer to void type |
cir.libc.memcpy (::cir::MemCpyOp)#
Equivalent to libc’s memcpy
Syntax:
operation ::= `cir.libc.memcpy` $len `bytes` `from` $src (`align` `(` $src_alignment^ `)`)?
`to` $dst (`align` `(` $dst_alignment^ `)`)? 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>
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
dst_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
src_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
|
fundamental unsigned integer type |
cir.libc.memmove (::cir::MemMoveOp)#
Equivalent to libc’s memmove
Syntax:
operation ::= `cir.libc.memmove` $len `bytes` `from` $src (`align` `(` $src_alignment^ `)`)?
`to` $dst (`align` `(` $dst_alignment^ `)`)? 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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
dst_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
src_alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
pointer to void type |
|
fundamental unsigned integer type |
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
alignment | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
pointer to void type |
|
8-bit unsigned integer |
|
fundamental unsigned integer type |
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
cir.llrint (::cir::LlrintOp)#
Rounds floating-point to long long integer using current rounding mode
Syntax:
operation ::= `cir.llrint` $src `:` type($src) `->` type($result)
(`fenv` `` $fenv^)? 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: CIR_FenvOpTrait
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
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 |
Results:#
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
cir.llround (::cir::LlroundOp)#
Rounds floating-point to long long integer
Syntax:
operation ::= `cir.llround` $src `:` type($src) `->` type($result)
(`fenv` `` $fenv^)? 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: CIR_FenvOpTrait
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
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 |
Results:#
Result |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
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` `(` enum($sync_scope)^ `)`)?
(`atomic` `(` enum($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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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)
(fenv `` $fenv^)? 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: `CIR_FenvOpTrait`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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)
(fenv `` $fenv^)? 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: `CIR_FenvOpTrait`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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.matrix.column_major_load` (::cir::MatrixColumnMajorLoadOp)
_Matrix column major load_
Syntax:
operation ::= cir.matrix.column_major_load $value : type($value) ,
$stride : type($stride)
(volatile $is_volatile^)?
, qualified(type($result)) attr-dict
The `cir.matrix.column_major_load` operation provides a representation for
the `__builtin_matrix_column_major_load` builtin and corresponds to the
`llvm.matrix.column.major.load` intrinsic in LLVM IR.
This operation performs a load of any matrix type with a stride to compute
the start address of the different columns.
The `stride` argument is the column stride which much be greater than or equal
to `row`, giving the following 2x3 matrix `[[1, 2, 3], [4, 5, 6]]` with a
stride of 2, the result matrix will be `[[1, 3, 5], [2, 4, 6]]`.
!cir.matrix<2 x 3 x !cir.float>
!cir.matrix<5 x 5 x !cir.double>
volatile, !cir.matrix<5 x 5 x !cir.double>
Interfaces: `PromotableMemOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>is_volatile</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `value` | CIR pointer type |
| `stride` | Integer type with arbitrary precision up to a fixed limit |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR matrix type |
### `cir.matrix.column_major_store` (::cir::MatrixColumnMajorStoreOp)
_Matrix column major store_
Syntax:
operation ::= cir.matrix.column_major_store $matrix : type($matrix) ,
$value : type($value) ,
$stride : type($stride)
(volatile $is_volatile^)?
attr-dict
The `cir.matrix.column_major_store` operation provides a representation for
the `__builtin_matrix_column_major_store` builtin and corresponds to the
`llvm.matrix.column.major.store` intrinsic in LLVM IR.
This operation performs a store of data from matrix type with a stride to
compute the start address of the different columns.
The `stride` argument is the column stride which much be greater than or equal
to `row`, giving the following 2x3 matrix `[[1, 2, 3], [4, 5, 6]]` with a
stride of 2, the stored data will be `[1, 3, 5, 2, 4, 6]`.
cir.matrix.column_major_store %matrix : <3 x 3 x !cir.float>,
Interfaces: `PromotableMemOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>is_volatile</code></td><td>::mlir::UnitAttr</td><td>unit attribute</td></tr>
</table>
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `matrix` | CIR matrix type |
| `value` | CIR pointer type |
| `stride` | Integer type with arbitrary precision up to a fixed limit |
### `cir.matrix.extract` (::cir::MatrixExtractOp)
_Extract one element from a matrix object_
Syntax:
operation ::= cir.matrix.extract $matrix
[ $rowIdx : type($rowIdx) ] [ $columnIdx : type($columnIdx) ]
attr-dict : qualified(type($matrix))
The `cir.matrix.extract` operation extracts the element at the given row
and column indices from a matrix object.
: !cir.matrix<3 x 3 x !cir.float>
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `matrix` | CIR matrix type |
| `rowIdx` | fundamental integer type |
| `columnIdx` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | any cir boolean, integer, floating point type |
### `cir.matrix.extract_row` (::cir::MatrixExtractRowOp)
_Extract a row from a matrix object_
Syntax:
operation ::= cir.matrix.extract_row $matrix
[ $rowIdx : type($rowIdx) ]
attr-dict : qualified(type($matrix))
The `cir.matrix.extract_row` operation extracts a row from from a matrix
object using a row index.
: !cir.matrix<3 x 3 x !cir.float>
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `matrix` | CIR matrix type |
| `rowIdx` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | vector type |
### `cir.matrix.insert` (::cir::MatrixInsertOp)
_Insert one element into a matrix object_
Syntax:
operation ::= cir.matrix.insert $value , $matrix
[ $rowIdx : type($rowIdx) ] [ $columnIdx : type($columnIdx) ]
attr-dict : qualified(type($matrix))
The `cir.matrix.insert` operation returns a copy of a matrix object with
the element at the given row and column indices replaced by `value`.
: !cir.matrix<3 x 3 x !cir.float>
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `value` | any cir boolean, integer, floating point type |
| `matrix` | CIR matrix type |
| `rowIdx` | fundamental integer type |
| `columnIdx` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR matrix type |
### `cir.matrix.multiply` (::cir::MatrixMultiplyOp)
_Matrix multiplication_
Syntax:
operation ::= cir.matrix.multiply $lhs , $rhs attr-dict
: ( qualified(type($lhs)) , qualified(type($rhs)) )
-> qualified(type($result))
The `cir.matrix.multiply` operation multiplies two matrices and
corresponds to the `llvm.matrix.multiply` intrinsic in LLVM IR.
The left-hand operand must have dimensions `M x K`, the right-hand operand
`K x N`, and the result `M x N`. All three must share an element type.
: (!cir.matrix<2 x 3 x !cir.float>, !cir.matrix<3 x 4 x !cir.float>)
-> !cir.matrix<2 x 4 x !cir.float>
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `lhs` | CIR matrix type |
| `rhs` | CIR matrix type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR matrix type |
### `cir.matrix.transpose` (::cir::MatrixTransposeOp)
_Matrix transpose_
Syntax:
operation ::= cir.matrix.transpose $value : type($value) , qualified(type($result)) attr-dict
The `cir.matrix.transpose` operation provides a representation for the
`__builtin_matrix_transpose` builtin and corresponds to the
`llvm.matrix.transpose` intrinsic in LLVM IR.
This operation performs transposition to switch the row and column
indices of the matrix and returns the transposed matrix,
!cir.matrix<2 x 3 x !cir.float>
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `value` | CIR matrix type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR matrix type |
### `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 bool or integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector of bool or 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
or matrix-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/matrix of integer type |
| `rhs` | integer or vector/matrix of integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer or vector/matrix 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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 bool or integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer, boolean, or vector of bool or 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.offload.printf` (::cir::OffloadPrintfOp)
_Device-side printf_
Syntax:
operation ::= cir.offload.printf ( $format (, $args^)? ) attr-dict : functional-type(operands, results)
Represents a call to `printf` in device code. The target is responsible for
the appropriate lowering.
`format` is the format string and `args` are the remaining arguments,
after the language's default argument promotions. `result` is the value
`printf` returns on the target, which follows the target's conventions
rather than C's.
Like the GPU dialect's `gpu.printf`, the op represents a device printf
independently of the target, and each target expands it when lowering.
Unlike `gpu.printf`, it must represent any call to C `printf`, so:
- `format` is a value rather than an attribute, as the format string need
not be a constant.
- `args` may also be pointers, such as strings printed with `%s`,
pointers to data members, and vectors.
- The op returns the result of `printf`.
- The op has no memory effect annotations, as printing may read memory
through `format` and `args`.
Example:
Interfaces: `InferTypeOpInterface`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `format` | pointer to 8-bit character type |
| `args` | variadic of integer type 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 pointer type or data member type or vector type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | 32-bit signed integer |
### `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 bool or integer |
| `rhs` | integer, boolean, or vector of bool or integer |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | integer, boolean, or vector of bool or 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 |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | unsigned integer type |
### `cir.pow` (::cir::PowOp)
_Computes the power of a floating-point value_
Syntax:
operation ::= cir.pow $lhs , $rhs : qualified(type($lhs))
(fenv `` $fenv^)? attr-dict
`cir.pow` computes the first operand raised to the power of the second
operand.
Traits: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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_mask` (::cir::PtrMaskOp)
_Clear bits of a pointer_
Syntax:
operation ::= cir.ptr_mask $ptr, $mask : functional-type(operands, results) attr-dict
The `cir.ptr_mask` operation clears the bits of `ptr` that are not set in
`mask`. The result stays a pointer, whereas masking it as an integer
would lose provenance.
`mask` must be exactly the target's pointer index width.
Traits: `AlwaysSpeculatableImplTrait`
Interfaces: `ConditionallySpeculatable`, `InferTypeOpInterface`, `NoMemoryEffect (MemoryEffectOpInterface)`
Effects: `MemoryEffects::Effect{}`
#### Operands:
| Operand | Description |
| :-----: | ----------- |
| `ptr` | CIR pointer type |
| `mask` | fundamental integer type |
#### Results:
| Result | Description |
| :----: | ----------- |
| `result` | CIR pointer 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.register_exit_dtor` (::cir::RegisterExitDtorOp)
_Register the destruction of a global at program or thread exit_
Syntax:
operation ::= cir.register_exit_dtor $object $body attr-dict
The `cir.register_exit_dtor` operation registers its body to run when the
storage duration of the global `object` ends: at program exit, or at
thread exit when `object` is thread local. The registration happens when
the operation executes, so objects registered later are destroyed earlier.
It must be nested in the ctor region of a `cir.global` or
`cir.local_init`, but not inside another `cir.register_exit_dtor`,
typically right after the construction of a temporary whose lifetime that
variable extends. `object` must have no ctor or dtor region of its own.
The body destroys `object`, which it reaches through `cir.get_global`.
Example:
cir.global external @r = #cir.zero : !rec_Refs ctor {
cir.call @_ZN3TmpC1Ei(%0, %1) : (!cir.ptr<!rec_Tmp>, !s32i) -> () cir.register_exit_dtor @ZGR1r { %2 = cir.get_global @ZGR1r : !cir.ptr<!rec_Tmp> cir.call @_ZN3TmpD1Ev(%2) : (!cir.ptr<!rec_Tmp>) -> () } … }
Traits: `IsolatedFromAbove`, `NoRegionArguments`, `SingleBlockImplicitTerminator<cir::YieldOp>`, `SingleBlock`
Interfaces: `SymbolUserOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>object</code></td><td>::mlir::FlatSymbolRefAttr</td><td>flat symbol reference attribute</td></tr>
</table>
### `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, CoroutineOp, 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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) (fenv `` $fenv^)? 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: `CIR_FenvOpTrait`, `SameOperandsAndResultType`
Interfaces: `CIR_FPEnvConstrainedOpInterface`, `ConditionallySpeculatable`, `InferTypeOpInterface`, `MemoryEffectsOpInterface`
#### Attributes:
<table>
<tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr>
<tr><td><code>fenv</code></td><td>::cir::FenvAttr</td><td>Describes floating-point environment constraints</td></tr>
</table>
#### 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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) )
({ is_volatile $is_volatile^ })? 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.struct<"S" packed {!u64i, !u16i,
pad !cir.array<!u8i x 2>}>
#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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
integer or boolean type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
isShiftleft | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
integer or vector of integer type |
|
integer or vector of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector of integer type |
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{}
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 |
Results:#
Result |
Description |
|---|---|
|
CIR bool type |
cir.sin (::cir::SinOp)#
Computes the floating-point sine
Syntax:
operation ::= `cir.sin` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.sinh (::cir::SinhOp)#
Computes the floating-point hyperbolic sine
Syntax:
operation ::= `cir.sinh` $src `:` type($src) (`fenv` `` $fenv^)? attr-dict
cir.sinh computes the hyperbolic 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.sqrt (::cir::SqrtOp)#
Floating-point square root operation
Syntax:
operation ::= `cir.sqrt` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
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>
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
cir.std.find (::cir::StdFindOp)#
Std::find()
Syntax:
operation ::= `cir.std.find` `(` $first `:` qualified(type($first)) `,`
$last `:` qualified(type($last)) `,`
$pattern `:` qualified(type($pattern)) `,`
$original_fn `)` `->` qualified(type($result)) attr-dict
Interfaces: CIR_StdOpInterface, InferTypeOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
original_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.std.strlen (::cir::StrLenOp)#
C standard library strlen()
Syntax:
operation ::= `cir.std.strlen` `(` $string `:` qualified(type($string)) `,` $original_fn `)`
`->` qualified(type($result)) attr-dict
Interfaces: CIR_StdOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
original_fn | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operands:#
Operand |
Description |
|---|---|
|
pointer to 8-bit character type |
Results:#
Result |
Description |
|---|---|
|
fundamental unsigned integer type |
cir.store (::cir::StoreOp)#
Store value to memory address
Syntax:
operation ::= `cir.store` (`volatile` $is_volatile^)?
(`nontemporal` $is_nontemporal^)?
(`align` `(` $alignment^ `)`)?
(`syncscope` `(` enum($sync_scope)^ `)`)?
(`atomic` `(` enum($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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
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, vector-of-integer or
matrix-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>
%4 = cir.sub %ma, %mb : !cir.matrix<3 x 3 x !s32i>
Traits: AlwaysSpeculatableImplTrait, SameOperandsAndResultType
Interfaces: BinaryOpInterface, ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
integer or vector/matrix of integer type |
|
integer or vector/matrix of integer type |
Results:#
Result |
Description |
|---|---|
|
integer or vector/matrix of integer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
|
Integer type with arbitrary precision up to a fixed limit |
Results:#
Result |
Description |
|---|---|
|
integer or boolean type |
|
CIR bool type |
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
all_enum_cases_covered | ::mlir::UnitAttr | unit attribute |
Operands:#
Operand |
Description |
|---|---|
|
Integer type with arbitrary precision up to a fixed limit |
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
Interfaces: BranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
caseValues | ::mlir::ArrayAttr | array attribute |
case_operand_segments | ::mlir::DenseI32ArrayAttr | i32 dense array attribute |
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 |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
cir.tan (::cir::TanOp)#
Computes the floating-point tangent
Syntax:
operation ::= `cir.tan` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
cir.tanh (::cir::TanhOp)#
Computes the floating-point hyperbolic tangent
Syntax:
operation ::= `cir.tanh` $src `:` type($src) (`fenv` `` $fenv^)? attr-dict
cir.tanh computes the hyperbolic 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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
Operands:#
Operand |
Description |
|---|---|
|
CIR bool type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
type_info | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
cir.token.none (::cir::TokenNoneOp)#
Produces an empty token value.
Syntax:
operation ::= `cir.token.none` attr-dict
Produces a none token value, mirroring LLVM IR’s none token
literal. Lowers to llvm::ConstantTokenNone.
Traits: AlwaysSpeculatableImplTrait, TokenProducerTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Results:#
Result |
Description |
|---|---|
|
token |
cir.trap (::cir::TrapOp)#
Exit the program abnormally
Syntax:
operation ::= `cir.trap` attr-dict
The cir.trap operation causes the program to exit abnormally. The implementations may implement this operation with different mechanisms. For example, an implementation may implement this operation by calling abort, while another implementation may implement this operation by executing an illegal instruction.
Traits: Terminator
cir.trunc (::cir::TruncOp)#
Truncates floating-point value to integer
Syntax:
operation ::= `cir.trunc` $src `:` type($src) (`fenv` `` $fenv^)? 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: CIR_FenvOpTrait, SameOperandsAndResultType
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, InferTypeOpInterface, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
floating point or vector of floating point type |
Results:#
Result |
Description |
|---|---|
|
floating point or vector of floating point type |
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.
A cir.try operation may instead have a filter handler paired with an
unexpected handler, which together implement the dynamic exception
specification of the enclosing function. The filter handler lists the
permitted type info symbols and holds the path taken when the in-flight
exception is permitted, which is a cir.resume that continues unwinding
to the caller. The unexpected handler holds the path taken when the
specification is violated, which is a cir.eh.unexpected. An empty
permitted type list represents throw(), which permits nothing, so the
filter handler region holds a cir.unreachable instead. Like unwind,
and unlike a catch handler, neither region begins with cir.begin_catch.
The two handlers must appear together, with the filter first, and must be
the only handlers on the operation. The try operation created for an
exception specification wraps the entire function body, and each try
statement written in the source becomes a separate cir.try operation
nested inside it.
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
}
Example of a void f() throw(int) exception specification:
cir.try {
cir.call exception @function() : () -> ()
cir.yield
} filter [#cir.global_view<@_ZTIi> : !cir.ptr<!u8i>]
(%eh_token : !cir.eh_token) {
cir.resume %eh_token : !cir.eh_token
} unexpected (%eh_token.1 : !cir.eh_token) {
cir.eh.unexpected %eh_token.1 : !cir.eh_token
}
Traits: AutomaticAllocationScope, RecursivelySpeculatableImplTrait
Interfaces: ConditionallySpeculatable, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanup | ::mlir::UnitAttr | unit attribute |
handler_types | ::mlir::ArrayAttr | catch all, unwind, eh filter, eh unexpected or global view array attribute |
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
callee | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
nothrow | ::mlir::UnitAttr | unit attribute |
nounwind | ::mlir::UnitAttr | unit attribute |
willreturn | ::mlir::UnitAttr | unit attribute |
inline_kind | ::cir::InlineKindAttr | inline kind |
musttail | ::mlir::UnitAttr | unit attribute |
memory_effects | ::cir::MemoryEffectsAttr | Describes the possible memory effects of a function or callee |
arg_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
res_attrs | ::mlir::ArrayAttr | Array of dictionary attributes |
calling_conv | ::cir::CallingConvAttr | calling convention |
Operands:#
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
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
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
type_info | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
dtor | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Successors:#
Successor |
Description |
|---|---|
|
any successor |
|
any successor |
cir.unreachable (::cir::UnreachableOp)#
Invoke immediate undefined behavior
Syntax:
operation ::= `cir.unreachable` attr-dict
If the program control flow reaches a cir.unreachable operation, the
program exhibits undefined behavior immediately. This operation is useful
in cases where the unreachability of a program point needs to be explicitly
marked.
Traits: Terminator
cir.va_arg (::cir::VAArgOp)#
Fetches next variadic element as a given type
Syntax:
operation ::= `cir.va_arg` $arg_list attr-dict `:` functional-type(operands, $result)
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.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>)
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR pointer type |
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
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>
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
cir.vec.cmp (::cir::VecCmpOp)#
Compare two vectors
Syntax:
operation ::= `cir.vec.cmp` `(` enum($kind) `,` $lhs `,` $rhs `)` `:` qualified(type($lhs)) `,`
qualified(type($result)) (`fenv` `` $fenv^)? 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.
The optional fenv attribute describes constraints on the floating-point
handling of the operation. It is only valid for floating-point vector
comparisons.
%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>
%gt = cir.vec.cmp(gt, %va, %vb) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> fenv<>
Traits: CIR_FenvOpTrait, SameTypeOperands
Interfaces: CIR_FPEnvConstrainedOpInterface, ConditionallySpeculatable, MemoryEffectsOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
kind | ::cir::CmpOpKindAttr | compare operation kind |
fenv | ::cir::FenvAttr | Describes floating-point environment constraints |
Operands:#
Operand |
Description |
|---|---|
|
CIR vector type |
|
CIR vector type |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
cir.vec.create (::cir::VecCreateOp)#
Create a vector value
Syntax:
operation ::= `cir.vec.create` `(` ($elements^ `:` type($elements))? `)` `:` qualified(type($result))
attr-dict
The cir.vec.create operation creates a vector value with the given element
values. The number of element arguments must match the number of elements
in the vector type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
variadic of any cir boolean, integer, floating point |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
cir.vec.extract (::cir::VecExtractOp)#
Extract one element from a vector object
Syntax:
operation ::= `cir.vec.extract` $vec `[` $index `:` type($index) `]` attr-dict `:` qualified(type($vec))
The cir.vec.extract operation extracts the element at the given index
from a vector object.
%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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR vector type |
|
fundamental integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR vector type |
|
any cir boolean, integer, floating point |
|
fundamental integer type |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
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
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 |
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
|
CIR vector type |
|
CIR vector type |
Results:#
Result |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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.vec.reduce.add (::cir::VecReduceAddOp)#
Reduce a vector using add
Syntax:
operation ::= `cir.vec.reduce.add` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.and (::cir::VecReduceAndOp)#
Reduce a vector using and
Syntax:
operation ::= `cir.vec.reduce.and` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.fadd (::cir::VecReduceFAddOp)#
Reduce a floating-point vector using fadd
Syntax:
operation ::= `cir.vec.reduce.fadd` `(` $accumulator `,` $input `)` `:` functional-type(operands, results)
prop-dict attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
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 |
|
vector of 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 |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.vec.reduce.fmax (::cir::VecReduceFMaxOp)#
Reduce a floating-point vector using fmax
Syntax:
operation ::= `cir.vec.reduce.fmax` `(` $input `)` `:` functional-type(operands, results)
prop-dict attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
vector of 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 |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.vec.reduce.fmin (::cir::VecReduceFMinOp)#
Reduce a floating-point vector using fmin
Syntax:
operation ::= `cir.vec.reduce.fmin` `(` $input `)` `:` functional-type(operands, results)
prop-dict attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
Operands:#
Operand |
Description |
|---|---|
|
vector of 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 |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.vec.reduce.fmul (::cir::VecReduceFMulOp)#
Reduce a floating-point vector using fmul
Syntax:
operation ::= `cir.vec.reduce.fmul` `(` $accumulator `,` $input `)` `:` functional-type(operands, results)
prop-dict attr-dict
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
fastmath_flags | ::cir::FastMathFlagsAttr | fast-math flags |
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 |
|
vector of 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 |
|---|---|
|
single float type or double float type or f16 type or bf16 type or f80 type or f128 type or long double type |
cir.vec.reduce.mul (::cir::VecReduceMulOp)#
Reduce a vector using mul
Syntax:
operation ::= `cir.vec.reduce.mul` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.or (::cir::VecReduceOrOp)#
Reduce a vector using or
Syntax:
operation ::= `cir.vec.reduce.or` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.smax (::cir::VecReduceSMaxOp)#
Reduce a vector using smax
Syntax:
operation ::= `cir.vec.reduce.smax` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of signed integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.smin (::cir::VecReduceSMinOp)#
Reduce a vector using smin
Syntax:
operation ::= `cir.vec.reduce.smin` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of signed integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.umax (::cir::VecReduceUMaxOp)#
Reduce a vector using umax
Syntax:
operation ::= `cir.vec.reduce.umax` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of unsigned integer type, boolean type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.umin (::cir::VecReduceUMinOp)#
Reduce a vector using umin
Syntax:
operation ::= `cir.vec.reduce.umin` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of unsigned integer type, boolean type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
cir.vec.reduce.xor (::cir::VecReduceXorOp)#
Reduce a vector using xor
Syntax:
operation ::= `cir.vec.reduce.xor` `(` $input `)` `:` functional-type(operands, results) attr-dict
Reduces the elements of a vector to a scalar of the vector element type.
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, InferTypeOpInterface, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
Results:#
Result |
Description |
|---|---|
|
any cir boolean, integer, floating point |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
indices | ::mlir::ArrayAttr | integer array attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR vector type |
|
CIR vector type |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
cir.vec.shuffle.dynamic (::cir::VecShuffleDynamicOp)#
Shuffle a vector using indices in another vector
Syntax:
operation ::= `cir.vec.shuffle.dynamic` $vec `:` qualified(type($vec)) `,` $indices `:` qualified(type($indices))
attr-dict
The cir.vec.shuffle.dynamic operation implements the undocumented form of
Clang’s __builtin_shufflevector, where the indices of the shuffled result
can be runtime values.
There are two input vectors, which must have the same number of elements. The second input vector must have an integral element type. The elements of the second vector are interpreted as indices into the first vector. The result vector is constructed by taking the elements from the first input vector from the indices indicated by the elements of the second vector.
%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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR vector type |
|
vector of integer type |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
cir.vec.splat (::cir::VecSplatOp)#
Convert a scalar into a vector or matrix
Syntax:
operation ::= `cir.vec.splat` $value `:` type($value) `,` qualified(type($result)) attr-dict
The cir.vec.splat operation creates a vector or matrix value from a
scalar value. All elements of the result 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>
%value_mat = cir.vec.splat %value : !s32i, !cir.matrix<2 x 2 x !s32i>
Traits: AlwaysSpeculatableImplTrait
Interfaces: ConditionallySpeculatable, NoMemoryEffect (MemoryEffectOpInterface)
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
any cir boolean, integer, floating point |
Results:#
Result |
Description |
|---|---|
|
vector or matrix type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
vector of any of boolean type, integer type |
|
CIR vector type |
|
CIR vector type |
Results:#
Result |
Description |
|---|---|
|
CIR vector type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
address_point | ::cir::AddressPointAttr | Address point attribute |
Results:#
Result |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
index | ::mlir::IntegerAttr | 64-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR type that is used for the vptr member of C++ objects |
Results:#
Result |
Description |
|---|---|
|
CIR pointer type |
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{}
Operands:#
Operand |
Description |
|---|---|
|
CIR pointer type |
Results:#
Result |
Description |
|---|---|
|
pointer to vptr type |
cir.vtt.address_point (::cir::VTTAddrPointOp)#
Get the VTT address point
Syntax:
operation ::= `cir.vtt.address_point` ($name^)?
($sym_addr^ `:` type($sym_addr))?
`,`
`offset` `=` $offset
`->` qualified(type($addr)) attr-dict
The vtt.address_point operation retrieves an element from the 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{}
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
name | ::mlir::FlatSymbolRefAttr | flat symbol reference attribute |
offset | ::mlir::IntegerAttr | 32-bit signless integer attribute |
Operands:#
Operand |
Description |
|---|---|
|
CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
|---|---|
|
CIR pointer type |
cir.while (::cir::WhileOp)#
C/C++ while loop
Syntax:
operation ::= `cir.while` $cond `do` $body (`cleanup` enum($cleanupKind) $cleanup^)?
(`loop_hints` $loop_hints^)? attr-dict
Represents a C/C++ while loop. It consists of two or three 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.cleanup: optional region that runs on every per-iteration exit edge (condition-false exit, end-of-iteration, break/continue, and EH unwinding when the cleanup kind includes EH). This is used to destroy a condition variable whose lifetime is a single iteration. When present, it carries a cleanup kind matchingcir.cleanup.scope(normalorall). Note that aDoWhileOpcannot contain acleanupregion.
Example:
cir.while {
cir.condition(%cond)
} do {
cir.yield
}
cir.while {
cir.condition(%cond)
} do {
cir.yield
} cleanup all {
cir.yield
}
Traits: NoRegionArguments
Interfaces: LoopLikeOpInterface, LoopOpInterface, RegionBranchOpInterface
Attributes:#
| Attribute | MLIR Type | Description |
|---|---|---|
cleanupKind | ::cir::CleanupKindAttr | cleanup kind |
loop_hints | ::cir::LoopHintAttr | Optimizer hints and guarantees attached to a loop |
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{}
Operands:#
Operand |
Description |
|---|---|
|
integer, boolean, or vector of bool or integer |
|
integer, boolean, or vector of bool or integer |
Results:#
Result |
Description |
|---|---|
|
integer, boolean, or vector of bool or integer |
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, CoroutineOp, DoWhileOp, ForOp, GlobalOp, IfOp, LocalInitOp, RegisterExitDtorOp, ScopeOp, SwitchOp, TernaryOp, TryOp, WhileOp>, ReturnLike, Terminator
Interfaces: NoMemoryEffect (MemoryEffectOpInterface), RegionBranchTerminatorOpInterface
Effects: MemoryEffects::Effect{}
Operands:#
Operand |
Description |
|---|---|
|
variadic of CIR void type or CIR bool type or CIR array type or CIR vector type or CIR matrix 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 bit-field access unit member type or CIR complex type or CIR type that is used for the vptr member of C++ objects or CUDA device surface reference type or CUDA device texture reference type 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 |
Attributes#
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
ast |
|
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
index |
|
|
offset |
|
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]>]
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
args |
|
AsmFlavorAttr#
ATT or Intel
Syntax:
#cir.asm_flavor<
`x86_att` | `x86_intel` # value
>
Enum cases:
x86_att (
x86_att)x86_intel (
x86_intel)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type AsmFlavor |
AssumeBundleKindAttr#
Kind of cir.assume operand bundle
Syntax:
#cir.assume_bundle<
`None` | `align` | `separate_storage` | `dereferenceable` # value
>
Enum cases:
None (
None)align (
Align)separate_storage (
SeparateStorage)dereferenceable (
Dereferenceable)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type AssumeBundleKind |
AtomicFetchKindAttr#
Binary opcode for atomic fetch-and-update operations
Syntax:
#cir.atomic_fetch<
`add` | `sub` | `and` | `xor` | `or` | `nand` | `max` | `min` | `uinc_wrap` | `udec_wrap` | `maximum` | `minimum` | `maximum_num` | `minimum_num` # value
>
Enum cases:
add (
Add)sub (
Sub)and (
And)xor (
Xor)or (
Or)nand (
Nand)max (
Max)min (
Min)uinc_wrap (
UIncWrap)udec_wrap (
UDecWrap)maximum (
Maximum)minimum (
Minimum)maximum_num (
MaximumNum)minimum_num (
MinimumNum)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type AtomicFetchKind |
AwaitKindAttr#
Await kind
Syntax:
#cir.await<
`init` | `user` | `yield` | `final` # value
>
Enum cases:
init (
Init)user (
User)yield (
Yield)final (
Final)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type AwaitKind |
BitFieldDeclAttr#
How the source declared one bit-field
Syntax:
#cir.bitfield_decl<
::mlir::Type, # declared_type
uint64_t, # width
bool # is_unnamed
>
Records a single bit-field as its declaration wrote it: the declared type, the number of bits the field holds, and whether the declaration named it.
A run of bit-fields shares one access unit whose width the compiler picks,
so none of this can be recovered from the unit. The fields in a run need
not even agree on a declared type: struct { int a : 2; long long b : 30; }
packs an int and a long long into a single 32-bit unit. This attribute
is therefore per field, and !cir.bitfield carries one of them for every
bit-field in the unit.
A width of zero is a zero-width bit-field, int : 0, which holds no bits
and exists only to end the run before it.
unnamed marks a bit-field the source cannot read, int : 3. It still
occupies bits of the unit, and the x86-64 classifier reads it, but it is
not a field any expression names. Every zero-width bit-field is unnamed.
Example:
#cir.bitfield_decl<!s32i, 4>
#cir.bitfield_decl<!s64i, 30>
#cir.bitfield_decl<!s32i, 3, unnamed>
#cir.bitfield_decl<!u32i, 0, unnamed>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
declared_type |
|
integer or boolean type |
width |
|
|
is_unnamed |
|
unnamed bit-field flag |
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.struct<"S" packed {!u64i, !u16i,
pad !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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
storage_type |
|
|
size |
|
|
offset |
|
|
is_signed |
|
BlockAddrDiffAttr#
Difference between two block addresses
Syntax:
#cir.block_addr_diff<
cir::IntType, # type
mlir::FlatSymbolRefAttr, # func
mlir::StringAttr, # lhs_label
mlir::StringAttr # rhs_label
>
This attribute represents the constant difference between the addresses of
two basic blocks within the same function. It is produced for GCC’s “labels
as values” extension when the difference of two label addresses appears in a
constant context, e.g. &&lhs - &&rhs.
Both labels belong to the function referenced by func. The value is the
address of lhs_label minus the address of rhs_label, truncated to the
attribute’s integer type.
Example:
cir.global "private" internal @b.ar =
#cir.block_addr_diff<@b, "l2", "l1"> : !s32i
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
func |
|
|
lhs_label |
|
|
rhs_label |
|
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
func |
|
|
label |
|
BoolAttr#
Represent true/false for !cir.bool types
Syntax:
#cir.bool<
cir::BoolType, # type
bool # value
>
The BoolAttr represents a ‘true’ or ‘false’ value.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
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.
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
kernel_name |
|
CUDAVarRegistrationInfoAttr#
Device variable registration flags.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
device_side_name |
|
|
kind |
|
|
isExtern |
|
|
isConstant |
|
|
isManaged |
|
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
assign_kind |
|
an enum of type AssignKind |
is_trivial |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
ctor_kind |
|
an enum of type CtorKind |
is_trivial |
|
CXXDtorAttr#
Marks a function as a CXX destructor
Syntax:
#cir.cxx_dtor<
mlir::Type, # type
bool # is_trivial
>
This attribute identifies a C++ destructor.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
is_trivial |
|
CXXModuleInitAttr#
Initializer function of an imported C++20 named module
Syntax:
#cir.cxx_module_init<
mlir::StringAttr, # name
mlir::LocationAttr # loc
>
The Itanium-mangled name of the initializer function of a C++20 named
module the translation unit imports, with the location of the import
declaration. CIRGen lists one per module whose initializer the unit’s
global init function must call, in call order, in the
cir.cxx_module_imported_inits module attribute; LoweringPrepare declares
each function at that location and calls it before the unit’s own
initializers.
Example:
cir.cxx_module_imported_inits = [#cir.cxx_module_init<"_ZGIW1a", loc("use.cpp":1:1)>]
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
loc |
|
CallingConvAttr#
Calling convention
Syntax:
#cir.calling_conv<
`c` | `ptx_kernel` | `spir_function` | `spir_kernel` | `amdgpu_kernel` # value
>
Enum cases:
c (
C)ptx_kernel (
PTXKernel)spir_function (
SpirFunction)spir_kernel (
SpirKernel)amdgpu_kernel (
AMDGPUKernel)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CallingConv |
CaseOpKindAttr#
Case kind
Syntax:
#cir.case<
`default` | `equal` | `anyof` | `range` # value
>
Enum cases:
default (
Default)equal (
Equal)anyof (
Anyof)range (
Range)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CaseOpKind |
CastKindAttr#
Cast kind
Syntax:
#cir.cast<
`bitcast` | `array_to_ptrdecay` | `member_ptr_to_bool` | `int_to_ptr` | `ptr_to_int` | `ptr_to_bool` | `integral` | `int_to_bool` | `int_to_float` | `float_to_int` | `float_to_bool` | `bool_to_int` | `floating` | `float_to_complex` | `float_complex_to_real` | `float_complex_to_bool` | `float_complex` | `float_complex_to_int_complex` | `int_to_complex` | `int_complex_to_real` | `int_complex_to_bool` | `int_complex` | `int_complex_to_float_complex` | `address_space` | `bool_to_float` # value
>
Enum cases:
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)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CastKind |
CatchAllAttr#
Syntax: #cir.all
CleanupKindAttr#
Cleanup kind
Syntax:
#cir.cleanup<
`normal` | `eh` | `all` # value
>
Enum cases:
normal (
Normal)eh (
EH)all (
All)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CleanupKind |
CmpOpKindAttr#
Compare operation kind
Syntax:
#cir.cmp<
`lt` | `le` | `gt` | `ge` | `eq` | `ne` | `one` | `uno` # value
>
Enum cases:
lt (
lt)le (
le)gt (
gt)ge (
ge)eq (
eq)ne (
ne)one (
one)uno (
uno)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type CmpOpKind |
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
ordering |
|
an enum of type CmpOrdering |
lt |
|
|
eq |
|
|
gt |
|
|
unordered |
|
ComplexRangeKindAttr#
Complex multiplication and division implementation
Syntax:
#cir.complex_range<
`full` | `improved` | `promoted` | `basic` # value
>
Enum cases:
full (
Full)improved (
Improved)promoted (
Promoted)basic (
Basic)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type ComplexRangeKind |
ConstArrayAttr#
A constant array from ArrayAttr or StringRefAttr
An CIR array attribute is an array of literals of the specified attr types.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
elts |
|
|
trailingZerosNum |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
real |
|
integer or floating point type |
imag |
|
integer or floating point type |
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
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).
These must be initialized with a set of types that exactly match the type of
the attribute, with one exception: flexible array members. If the last
member of a struct type or a member of a union type is a zero-length array,
the ConstRecordAttr may initialize it with a larger array of the same
element type. This is necessary to support global and static storage
duration variables that use the flexible array member functionality.
Example:
cir.global external @rgb2 = #cir.const_record<{0 : i8,
5 : i64, #cir.null : !cir.ptr<i8>
}> : !cir.record<"", i8, i64, !cir.ptr<i8>>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
members |
|
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
elts |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
member_path |
|
DataMemberOffsetAttr#
Constant pointer-to-data-member given by a byte offset
Syntax:
#cir.data_member_offset<
cir::DataMemberType, # type
uint64_t # offset
>
Like #cir.data_member, this is a literal attribute representing a constant
(non-null) pointer-to-data-member value. It is used for members that are
not laid out in the CIR record and therefore have no field-index path – in
particular [[no_unique_address]] empty fields. The concrete byte offset
of the member within the class is stored directly.
Example:
// Empty S::*p = &S::e (e is a no_unique_address empty field at byte 1)
#cir.data_member_offset<1> : !cir.data_member<!rec_Empty in !rec_S>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
offset |
|
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.
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 |
DynamicCastKindAttr#
Dynamic cast kind
Syntax:
#cir.dynamic_cast<
`ptr` | `ref` # value
>
Enum cases:
ptr (
Ptr)ref (
Ref)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type DynamicCastKind |
DynamicInitGuardAttr#
Guard variable name for guarded dynamic initialization
Syntax:
#cir.dynamic_init_guard<
mlir::StringAttr # name
>
Contains the mangled guard variable name for guarded dynamic
initialization. This covers both function-local static variables and
namespace-scope variables with vague linkage (e.g. weak/linkonce_odr
inline variables), which both use the Itanium __cxa_guard_* protocol.
See DynamicInitInfoAttr for the facts that distinguish the two.
Example:
cir.global internal dynamic_init_guard<"_ZGVZ3foovE1x"> @_ZZ3foovE1x = ...
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
DynamicInitInfoAttr#
Variable facts needed by guarded dynamic initialization lowering
Syntax:
#cir.dynamic_init_info<
bool, # local
`none` | `static` | `dynamic`, # tls
bool, # is_inline
`undeclared` | `implicit_instantiation` | `explicit_specialization` | `explicit_instantiation_declaration` | `explicit_instantiation_definition` # tsk
>
Holds the subset of a guarded-dynamic-initialization variable’s
declaration facts that post-CIRGen lowering needs, as plain data (no
clang::VarDecl pointer). Always accompanies a DynamicInitGuardAttr,
and applies equally to function-local statics and to namespace-scope
variables with vague linkage (e.g. weak/linkonce_odr inline variables).
local: whether the variable is a block-scope (local) declaration. Mirrorsclang::VarDecl::isLocalVarDecl(). The namespace-scope inline variables that also reach guarded initialization are not local.tls: the thread-local storage kind (none,static, ordynamic).is_inline: whether the variable is inline. Mirrorsclang::VarDecl::isInline().tsk: the template-specialization kind (undeclared,implicit_instantiation,explicit_specialization,explicit_instantiation_declaration, orexplicit_instantiation_definition).
Example:
cir.global ... @x = ...
dynamic_init_info<local = true, tls = none, is_inline = false,
tsk = undeclared>
Because it stores plain data rather than a clang::VarDecl pointer, it
round-trips through textual CIR and stays valid once the AST is gone.
This is what lets LoweringPrepare consume these facts without a live
clang::ASTContext; the $ast ASTVarDeclAttr remains a separate,
live-AST handle for consumers that need arbitrary AST properties.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
local |
|
|
tls |
|
an enum of type TLSKind |
is_inline |
|
|
tsk |
|
an enum of type TemplateSpecializationKind |
EhFilterAttr#
Dynamic exception specification filter handler
Syntax:
#cir.eh_filter<
mlir::ArrayAttr # permitted_types
>
Identifies the handler of a cir.try operation that is reached when the
in-flight exception is permitted by the dynamic exception specification of
the enclosing function. The attribute carries the list of type info symbols
naming the permitted types. An empty list represents throw(), which
permits nothing.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
permitted_types |
|
EhUnexpectedAttr#
Dynamic exception specification unexpected exception handler
Syntax: #cir.eh_unexpected
Identifies the handler of a cir.try operation that is reached when the
in-flight exception is not permitted by the dynamic exception specification
of the enclosing function.
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
FPClassTestAttr#
Floating-point class test flags
Syntax:
#cir.fp_class<
`fcNone` | `fcSNan` | `fcQNan` | `fcNegInf` | `fcNegNormal` | `fcNegSubnormal` | `fcNegZero` | `fcPosZero` | `fcPosSubnormal` | `fcPosNormal` | `fcPosInf` | `fcNan` | `fcInf` | `fcNormal` | `fcSubnormal` | `fcZero` | `fcPosFinite` | `fcNegFinite` | `fcFinite` | `fcPositive` | `fcNegative` | `fcAllFlags` # value
>
Enum cases:
fcNone (
None)fcSNan (
SignalingNaN)fcQNan (
QuietNaN)fcNegInf (
NegativeInfinity)fcNegNormal (
NegativeNormal)fcNegSubnormal (
NegativeSubnormal)fcNegZero (
NegativeZero)fcPosZero (
PositiveZero)fcPosSubnormal (
PositiveSubnormal)fcPosNormal (
PositiveNormal)fcPosInf (
PositiveInfinity)fcNan (
Nan)fcInf (
Infinity)fcNormal (
Normal)fcSubnormal (
Subnormal)fcZero (
Zero)fcPosFinite (
PositiveFinite)fcNegFinite (
NegativeFinite)fcFinite (
Finite)fcPositive (
Positive)fcNegative (
Negative)fcAllFlags (
All)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type FPClassTest |
FastMathFlagsAttr#
Fast-math flags
Syntax:
#cir.fastmath<
`none` | `nnan` | `ninf` | `nsz` | `arcp` | `contract` | `afn` | `reassoc` | `fast` # value
>
Describes fast-math flags for CIR operations. This attribute is shared by operations with floating-point semantics and is not specific to LLVM intrinsic calls.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type FastMathFlags |
FenvAttr#
Describes floating-point environment constraints
Syntax:
#cir.fenv<
std::optional<cir::FPDynamicRoundingMode>, # dynamic_rounding_mode
std::optional<cir::FPExceptionMode>, # except_mode
mlir::BoolAttr # strict_except
>
The #cir.fenv attribute describes constraints on the floating-point
handling of a floating-point operation. It is attached to floating-point
operations to capture rounding and exception behavior. All of its
parameters are optional.
dynamic_rounding_mode: the known dynamic rounding mode at the point the instruction is executed. Otherwise the behavior is undefined.except_mode: the known exception mode at the point the instruction is executed. Otherwise the behavior is undefined.strict_except: iffalse, any case that would produce an FP exception produces it non-deterministically instead (i.e. it may or may not occur). This means the FP status is written non-deterministically, and, if exceptions are unmasked, the instruction traps non-deterministically.
An absent dynamic_rounding_mode defaults to unknown, an absent
except_mode defaults to masked, and an absent strict_except defaults
to false.
Example:
#cir.fenv<dynamic_rounding_mode = tonearest, except_mode = unknown,
strict_except = true>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
dynamic_rounding_mode |
|
|
except_mode |
|
|
strict_except |
|
FramePointerKindAttr#
Encodes the frame pointer kind for a function or a module.
Syntax:
#cir.frame_pointer<
`none` | `non_leaf` | `all` | `reserved` | `non_leaf_no_reserve` # value
>
Mirrors the frame-pointer function attribute and module flag of LLVM
IR (https://llvm.org/docs/LangRef.html#function-attributes), which tell
the code generator whether a function should keep its frame pointer. The
code generator may keep a frame pointer even when the kind says it can
be eliminated.
none: the frame pointer can be eliminated, and its register can be used for other purposes.reserved: the frame pointer register must either be updated to point to a valid frame record for the current function, or not be modified.non_leaf: the frame pointer should be kept if the function calls other functions.non_leaf_no_reserve: likenon_leaf, but a leaf function may use the frame pointer register for other purposes.all: the frame pointer should be kept.
On a function, the attribute applies to that function. On the module,
it becomes the frame-pointer module flag, which LLVM applies to the
functions it creates after CIR is lowered, such as sanitizer
constructors. Without the attribute, the kind is none.
Example:
module attributes {cir.frame_pointer = #cir.frame_pointer<all>} {
cir.func private @f() attributes {frame_pointer = #cir.frame_pointer<all>}
}
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type FramePointerKind |
FuncIdentityAttr#
Identifies a function as a known standard library entity
Syntax:
#cir.func_identity<
`std::find` # kind
>
Names the standard library entity a function represents, so that transformations can recognize calls to well known library functions without decoding mangled symbol names.
The tag names the whole entity. For std::find that is the free
function named find in the std namespace, so a member function, a
static member, or an operator can never carry the tag. Inline
namespaces, such as the versioning namespace of libc++, count as part
of std. The tag never encodes signatures, and a function that
matches no known entity carries no attribute.
Example:
#cir.func_identity<"std::find">
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
kind |
|
an enum of type KnownFuncKind |
GlobalCtorAttr#
Marks a function as a global constructor
Syntax:
#cir.global_ctor<
mlir::StringAttr, # name
int, # priority
mlir::FlatSymbolRefAttr # associated
>
Marks the function as a global constructor in the module’s constructor list. It will be executed before main() is called.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
priority |
|
|
associated |
|
GlobalDtorAttr#
Marks a function as a global destructor
Syntax:
#cir.global_dtor<
mlir::StringAttr, # name
int, # priority
mlir::FlatSymbolRefAttr # associated
>
Marks a function as a global destructor in the module dtors list. The function will be executed before the module unloading.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
name |
|
|
priority |
|
|
associated |
|
GlobalLinkageKindAttr#
Linkage kind
Syntax:
#cir.linkage<
`external` | `available_externally` | `linkonce` | `linkonce_odr` | `weak` | `weak_odr` | `appending` | `internal` | `cir_private` | `extern_weak` | `common` # value
>
Enum cases:
external (
ExternalLinkage)available_externally (
AvailableExternallyLinkage)linkonce (
LinkOnceAnyLinkage)linkonce_odr (
LinkOnceODRLinkage)weak (
WeakAnyLinkage)weak_odr (
WeakODRLinkage)appending (
AppendingLinkage)internal (
InternalLinkage)cir_private (
PrivateLinkage)extern_weak (
ExternalWeakLinkage)common (
CommonLinkage)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type GlobalLinkageKind |
GlobalOffsetAttr#
Provides constant access to a byte offset from a global
Syntax:
#cir.global_offset<
::mlir::Type, # type
mlir::FlatSymbolRefAttr, # symbol
int64_t # offset
>
Get the constant address that is offset bytes away from the address of
global symbol. Like #cir.global_view, it provides a way to access
globals from other globals and always produces a pointer, and the type of
the referenced symbol may differ from the type of the attribute.
Whereas #cir.global_view navigates the type of the symbol using
subelement indices, this attribute describes a flat displacement in bytes.
It is used for the addresses that cannot be described by subelement
indices, namely addresses outside of the referenced object, such as the
one-past-the-end address of a record, and addresses that do not fall on a
subelement boundary. This mirrors the byte offset that classic codegen
applies to every constant lvalue.
Example:
struct S { int x; };
S s;
S *p = &s + 1;
produces
cir.global external @p = #cir.global_offset<@s, 4> : !cir.ptr<!rec_S>
which lowers to
@p = global ptr getelementptr (i8, ptr @s, i64 4)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
symbol |
|
|
offset |
|
GlobalViewAttr#
Provides constant access to a global address
Syntax:
#cir.global_view<
::mlir::Type, # type
mlir::FlatSymbolRefAttr, # symbol
mlir::ArrayAttr, # indices
bool # address_point
>
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;
};
address_point marks a vtable address point: symbol is a vtable and
indices are the vtable within the group and the address point within
it. As in classic codegen, it lowers to an inbounds GEP whose inrange
spans that one vtable.
VTT for B in CIR:
cir.global linkonce_odr @_ZTT1B = #cir.const_array<[
#cir.global_view<@_ZTV1B, [0 : i32, 3 : i32], address_point>
: !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
inrange(-24, 0) (i8, ptr @_ZTV1B, i64 24)], align 8
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
symbol |
|
|
indices |
|
|
address_point |
|
InitCatchKindAttr#
Allowed i32 cases: 0, 1, 2, 3, 4, 5, 6, 7
Syntax:
#cir.init_catch<
`reference` | `pointer` | `scalar` | `objc` | `trivial_copy` | `non_trivial_copy` | `reference_to_pointer` | `reference_to_record_pointer` # value
>
Enum cases:
reference (
Reference)pointer (
Pointer)scalar (
Scalar)objc (
Objc)trivial_copy (
TrivialCopy)non_trivial_copy (
NonTrivialCopy)reference_to_pointer (
ReferenceToPointer)reference_to_record_pointer (
ReferenceToRecordPointer)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type InitCatchKind |
InlineKindAttr#
Inline kind
Syntax:
#cir.inline<
`no_inline` | `always_inline` | `inline_hint` # value
>
Inline Kind attributes. no_inline and always_inline
spellings correspond to the attributes of the same name, and inline_hint
is the inline keyword in the language.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type InlineKind |
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
value |
|
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)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type LangAddressSpace |
LoopHintAttr#
Optimizer hints and guarantees attached to a loop
Syntax:
#cir.loop_hint<
mlir::UnitAttr, # must_progress
mlir::UnitAttr, # vectorize_enable
uint32_t, # vectorize_width
mlir::BoolAttr, # vectorize_scalable
mlir::BoolAttr, # vectorize_predicate
uint32_t, # interleave_count
std::optional<cir::LoopUnrollMode>, # unroll
uint32_t, # unroll_count
std::optional<cir::LoopUnrollMode>, # unroll_and_jam
uint32_t, # unroll_and_jam_count
mlir::BoolAttr, # distribute
mlir::UnitAttr, # pipeline_disabled
uint32_t, # pipeline_initiation_interval
mlir::UnitAttr, # licm_disabled
mlir::UnitAttr, # parallel
uint32_t # code_align
>
The #cir.loop_hint attribute carries per-loop information for the
optimizer: the forward-progress guarantee and the hints from
#pragma clang loop, #pragma unroll, [[clang::code_align]] and their
OpenCL and HLSL spellings. It is attached to the loop operations
(cir.for, cir.while, cir.do).
must_progress: the loop must eventually terminate or have an observable side effect (the forward-progress guarantee of C++11 and later, and C11 loops with a non-constant condition).vectorize_enable: force vectorization on.vectorize_width: the vectorization factor. A width of 1 disables vectorization.vectorize_scalable: whether the vectorization factor is scalable, or explicitly fixed.vectorize_predicate: enable or disable predicated vectorization.interleave_count: the interleave count. A count of 1 disables interleaving.unroll: The unrolling mode: enable, disable, or full.unroll_count: the unroll factor.unroll_and_jam: the unroll-and-jam mode: enable, disable, or full.distribute: enable or disable loop distribution.pipeline_disabled: disable software pipelining.pipeline_initiation_interval: the pipelining initiation interval.licm_disabled: disable loop-invariant code motion.parallel: the loop’s iterations are independent, so its memory accesses are parallel accesses.code_align: the alignment of the loop, in bytes.
Example:
#cir.loop_hint<>
#cir.loop_hint< must_progress>
#cir.loop_hint< must_progress vectorize_enable interleave_count = 2
unroll_count = 4>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
must_progress |
|
|
vectorize_enable |
|
|
vectorize_width |
|
|
vectorize_scalable |
|
|
vectorize_predicate |
|
|
interleave_count |
|
|
unroll |
|
|
unroll_count |
|
|
unroll_and_jam |
|
|
unroll_and_jam_count |
|
|
distribute |
|
|
pipeline_disabled |
|
|
pipeline_initiation_interval |
|
|
licm_disabled |
|
|
parallel |
|
|
code_align |
|
LoweringLangOptionsAttr#
LangOptions facts that post-CIRGen lowering consumes
Syntax:
#cir.lowering_lang_options<
bool, # exceptions
bool, # threadsafe_statics
bool, # cuda
bool, # cuda_is_device
bool, # hip
bool, # hlsl
bool, # gpu_rdc
bool, # openmp
bool, # openmp_is_target_device
int32_t # clang_abi_compat
>
Serializes the subset of clang::LangOptions that post-CIRGen lowering
reads, as plain data, so a reloaded .cir module lowers the same way it
was compiled without a live clang::LangOptions. Only LangOpts flags with
no triple/module representation live here; target-derived facts (size_t
width, CXXABI, fp formats, etc.) are rebuilt from cir.triple instead.
Each bool field mirrors the like-named LangOptions member: exceptions,
threadsafe_statics, cuda, cuda_is_device, hip, hlsl, gpu_rdc,
openmp (LangOpts.OpenMP != 0; only its on/off state matters), and
openmp_is_target_device. clang_abi_compat is an i32 mirroring
LangOptions::ClangABI; it is an i32 rather than a CIR enum because
ClangABI gains an enumerator every Clang release (see
clang/Basic/ABIVersions.def), and the ordinal round-trips fine within a
single toolchain.
Example:
module attributes {cir.lowering_lang_options = #cir.lowering_lang_options<
exceptions = false, threadsafe_statics = true, cuda = false,
cuda_is_device = false, hip = false, gpu_rdc = false, openmp = false,
openmp_is_target_device = false, clang_abi_compat = 17>} { }
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
exceptions |
|
|
threadsafe_statics |
|
|
cuda |
|
|
cuda_is_device |
|
|
hip |
|
|
hlsl |
|
|
gpu_rdc |
|
|
openmp |
|
|
openmp_is_target_device |
|
|
clang_abi_compat |
|
MaxWorkGroupSizeAttr#
Maximum kernel work-group size
Syntax:
#cir.max_work_group_size<
uint32_t, # x
uint32_t, # y
uint32_t # z
>
Stores the maximum work-group size of a kernel, emitted to LLVM IR as
max_work_group_size function metadata.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
x |
|
|
y |
|
|
z |
|
MemOrderAttr#
Memory order according to C++11 memory model
Syntax:
#cir.mem_order<
`relaxed` | `consume` | `acquire` | `release` | `acq_rel` | `seq_cst` # value
>
Enum cases:
relaxed (
Relaxed)consume (
Consume)acquire (
Acquire)release (
Release)acq_rel (
AcquireRelease)seq_cst (
SequentiallyConsistent)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type MemOrder |
MemoryEffectsAttr#
Describes the possible memory effects of a function or callee
Syntax:
#cir.memory_effects<
ModRefInfo, # other
ModRefInfo, # arg_mem
ModRefInfo, # inaccessible_mem
ModRefInfo, # errno_mem
ModRefInfo, # target_mem0
ModRefInfo # target_mem1
>
Specifies the possible memory effects of a function or callee. Memory is divided into classes, each carrying its own access, so that a promise about one class need not be a promise about all of them:
other: the access for every location not named by one of the other parameters, including locations with no class of their own such as globals and captured pointers.arg_mem: accesses based on the function’s pointer arguments.inaccessible_mem: accesses to memory the current module cannot reach, often used to model the control dependencies of intrinsics.errno_mem: accesses to theerrnovariable.target_mem0,target_mem1: target-specific state.
The classes and their meanings match the LLVM dialect’s
#llvm.memory_effects, which lowering converts this attribute to.
An absent attribute means the effects are unknown, which is the conservative default and what a function with no memory annotation gets. Lowering leaves such a function with no memory attribute at all.
Example:
#cir.memory_effects<other = read, arg_mem = readwrite,
inaccessible_mem = none, errno_mem = none,
target_mem0 = none, target_mem1 = none>
The attribute has no keyword syntax, so on an operation it is written in the attribute dictionary:
cir.func private @f() attributes {memory_effects = #cir.memory_effects<...>}
%0 = cir.call @f() {memory_effects = #cir.memory_effects<...>} : () -> !s32i
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
other |
|
|
arg_mem |
|
|
inaccessible_mem |
|
|
errno_mem |
|
|
target_mem0 |
|
|
target_mem1 |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
symbol |
|
|
vtable_offset |
|
OffloadKindAttr#
Offload kind of a module in an offload container
Syntax:
#cir.offload<
`host` | `device` # value
>
Marks a module nested inside an offload container - identified by the
cir.offload.container unit attribute - as either the host module (carrying
cir.offload.kind = #cir.offload<host>) or one of the device modules
(carrying cir.offload.kind = #cir.offload<device>) of the offload
container. This creates a tiered module layout, where a singular offload
container contains a single host module and one or more device modules,
granting the offload merge/split pipeline passes the cross-boundary view.
Example:
module attributes {cir.offload.container} {
module @host attributes {cir.offload.kind = #cir.offload<host>} {}
module @device1 attributes {cir.offload.kind = #cir.offload<device>} {}
module @device2 attributes {cir.offload.kind = #cir.offload<device>} {}
}
Note: In order to simplify offload passes, the offload container module requires that the first module inside it is the host module and the rest of the modules are device modules.
The nested modules are plain builtin.module ops rather than a dedicated
container op, so that the existing module infrastructure applies to them
unchanged; the layout above is enforced by the CIR dialect attribute
verifier, following the gpu.container_module precedent.
The attribute names cir.offload.container and cir.offload.kind are
defined by the getOffloadContainerAttrName and getOffloadKindAttrName
methods in the CIRDialect class.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type OffloadKind |
OffsetPairAttr#
Offset Pair attribute
Syntax:
#cir.offset_pair<
uint64_t, # start
uint64_t # end
>
An attribute that specifies a pair of positive integral values that represent a bit-offset range in an existing structure. The range represented by this is [start, end).
Example:
cir.clear_padding(align(1) %1,
[#cir.offset_pair<0, 2>, #cir.offset_pair<6, 8>])
: <rec_Type> -> ()
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
start |
|
|
end |
|
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.
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 |
OpenCLVersionAttr#
OpenCL version
Syntax:
#cir.cl.version<
int32_t, # majorVersion
int32_t # minorVersion
>
Represents an OpenCL language version preserved as module metadata.
The cir.cl.cxx.version module attribute requires a companion
cir.cl.version attribute specifying the compatible OpenCL version.
Example:
// Module compiled from OpenCL C 1.2.
module attributes {cir.cl.version = #cir.cl.version<1, 2>} {}
// Module compiled from C++ for OpenCL 2021.
module attributes {
cir.cl.cxx.version = #cir.cl.version<2021, 0>,
cir.cl.version = #cir.cl.version<3, 0>
} {}
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
majorVersion |
|
|
minorVersion |
|
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
level |
|
|
size |
|
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
PtrSpecAttr#
!cir.ptr data layout spec
Syntax:
#cir.ptr_spec<
uint32_t, # size
uint32_t, # abi
uint32_t, # preferred
uint32_t # index
>
Pointer data layout for !cir.ptr: size, abi and preferred are
required bitwidths; index is the optional bitwidth for index
computations, defaulting to size. All present values must be divisible
by 8, with preferred >= abi.
This is the CIR-native analogue of the ptr dialect’s #ptr.spec; a
native attribute keeps CIR’s data-layout queries free of any ptr-dialect
dependency.
Used as the value of the !cir.ptr<!cir.void>-keyed data-layout entry:
#dlti.dl_spec<!cir.ptr<!cir.void> =
#cir.ptr_spec<size = 64, abi = 64, preferred = 64>>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
size |
|
|
abi |
|
|
preferred |
|
|
index |
|
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>
}
}
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
arg_passing_kind |
|
an enum of type ArgPassingKind |
has_trivial_dtor |
|
|
record_align |
|
SourceLanguageAttr#
Module source language
Syntax:
#cir.lang<
`c` | `cxx` | `opencl_c` | `opencl_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 compiled from OpenCL C.
module attributes {cir.lang = cir.lang<opencl_c>} {}
// Module compiled from C++ for OpenCL.
module attributes {cir.lang = cir.lang<opencl_cxx>} {}
Module source language attribute name is cir.lang is defined by
getSourceLanguageAttrName method in CIRDialect class.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type SourceLanguage |
SyncScopeKindAttr#
Sync scope kind
Syntax:
#cir.sync_scope<
`single_thread` | `system` | `device` | `workgroup` | `wavefront` | `cluster` | `hip_single_thread` | `hip_system` | `hip_agent` | `hip_workgroup` | `hip_wavefront` | `hip_cluster` | `opencl_work_group` | `opencl_device` | `opencl_all_svm_devices` | `opencl_sub_group` # value
>
Enum cases:
single_thread (
SingleThread)system (
System)device (
Device)workgroup (
Workgroup)wavefront (
Wavefront)cluster (
Cluster)hip_single_thread (
HIPSingleThread)hip_system (
HIPSystem)hip_agent (
HIPAgent)hip_workgroup (
HIPWorkgroup)hip_wavefront (
HIPWavefront)hip_cluster (
HIPCluster)opencl_work_group (
OpenCLWorkGroup)opencl_device (
OpenCLDevice)opencl_all_svm_devices (
OpenCLAllSVMDevices)opencl_sub_group (
OpenCLSubGroup)
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type SyncScopeKind |
TLSModelAttr#
TLS model
Syntax:
#cir.tls_model<
`tls_dyn` | `tls_local_dyn` | `tls_init_exec` | `tls_local_exec` # value
>
The TLS mode for the global, which comes from either the
tls_model attribute, or -ftls-model flag.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type TLSModel |
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>)>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
wrapper_name |
|
|
init_name |
|
|
guard_name |
|
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
data |
|
integer or global view array attribute |
UndefAttr#
Represent an undef constant
Syntax:
#cir.undef<
::mlir::Type # type
>
The UndefAttr represents an undef constant, corresponding to LLVM’s notion of undef.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
UnwindAttr#
Syntax: #cir.unwind
UnwindTableKindAttr#
Encodes the unwind table kind for a function.
Syntax:
#cir.uwtable<
`none` | `sync` | `async` # value
>
This mirrors the UWTableKindEnum in The LLVM dialect, and is passed through to the llvm dialect. According to the LLVM documentation: The ‘uwtable’ attribute is about the ABI or the user mandating an / entry in the unwind table.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
value |
|
an enum of type UnwindTableKind |
UsualDeleteParamsAttr#
Parameters describing the usual operator delete signature
Syntax:
#cir.usual_delete_params<
bool, # size
std::optional<uint64_t>, # 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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
size |
|
|
alignment |
|
|
type_aware_delete |
|
|
destroying_delete |
|
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
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
|
data |
|
ZeroAttr#
Attribute to represent zero initialization
Syntax:
#cir.zero<
::mlir::Type # type
>
The ZeroAttr is used to indicate zero initialization on structs.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
type |
|
Types#
ArrayType#
CIR array type
Syntax:
!cir.array<
::mlir::Type, # elementType
uint64_t # size
>
!cir.array represents C/C++ constant arrays.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
elementType |
|
any type except void |
size |
|
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.
BitFieldType#
CIR bit-field access unit member type
Syntax:
!cir.bitfield<
mlir::Type, # storage_type
::llvm::ArrayRef<cir::BitFieldDeclAttr> # fields
>
A run of bit-fields shares one access unit. A record has one member per
access unit, and that member has this type. The storage_type is the unit
the record stores, and fields says which bit-fields the source packed into
it, in declaration order.
The unit answers where the bits live, and fields answers how the fields
were declared in the user’s source code. The storage type can be narrower
than the declared type of a bit-field within it, and the fields in it need
not agree on a declared type.
A zero-width bit-field belongs to no unit. It is spelled as a member with
no storage_type and a single zero-width field, which occupies no bytes of
the record and becomes no field of the lowered LLVM struct. Every other
member of this type owns the bytes of its unit.
Examples:
// struct S { int a : 4; int b : 27; };
!rec_S = !cir.struct<"S"
{bitfield !cir.bitfield<!u32i, [#cir.bitfield_decl<!s32i, 4>,
#cir.bitfield_decl<!s32i, 27>]>}>
// struct M { int a : 2; long long b : 30; };
!rec_M = !cir.struct<"M"
{bitfield !cir.bitfield<!u32i, [#cir.bitfield_decl<!s32i, 2>,
#cir.bitfield_decl<!s64i, 30>]>,
pad !cir.array<!u8i x 4>}>
// struct Tail { int x; unsigned : 0; };
!rec_Tail = !cir.struct<"Tail"
{data !s32i,
empty !cir.bitfield<[#cir.bitfield_decl<!u32i, 0, unnamed>]>}>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
storage_type |
|
|
fields |
|
BoolType#
CIR bool type
Syntax: !cir.bool
!cir.bool represents C++ bool type.
CUDADeviceSurfaceType#
CUDA device surface reference type
Syntax: !cir.cuda_surface
!cir.cuda_surface represents a CUDA built-in surface reference in CIR.
The type preserves surface semantics at the CIR level and lowers to the NVPTX
device-side handle representation (i64) during lowering to LLVM IR.
CUDADeviceTextureType#
CUDA device texture reference type
Syntax: !cir.cuda_texture
!cir.cuda_texture represents a CUDA built-in texture reference in CIR.
The type preserves texture semantics at the CIR level and is lowered to
the target device representation during lowering to LLVM IR.
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.
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.
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
elementType |
|
integer or floating point type |
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
member_ty |
|
|
class_ty |
|
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.
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.
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++.
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.
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.
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
inputs |
|
|
optionalReturnType |
|
|
varArg |
|
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>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
width |
|
|
is_signed |
|
|
is_bit_int |
|
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
underlying |
|
expects !cir.double, !cir.fp80 or !cir.fp128 |
MatrixType#
CIR matrix type
Syntax:
!cir.matrix<
::mlir::Type, # element_type
uint64_t, # num_rows
uint64_t # num_columns
>
The !cir.matrix type represents a fixed-size 2-dimensional matrix.
It takes three parameters: the element type, the number of rows,
and columns.
Syntax:
matrix-type ::= !cir.matrix<row x colum x element-type>
size ::= (decimal-literal | `[` decimal-literal `]`)
element-type ::= float-type | integer-type | bool-type
The element-type must be a scalar CIR type. Zero-sized matrices are not
allowed. The row and column count must be a positive integer.
Examples:
!cir.matrix<3 x 3 x !cir.int<u, 8>>
!cir.matrix<2 x 4 x !cir.float>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
element_type |
|
any cir boolean, integer, floating point type |
num_rows |
|
|
num_columns |
|
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.
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
member_func_ty |
|
|
class_ty |
|
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)>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
pointee |
|
|
addrSpace |
|
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++.
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.
Typically, the full data size of a struct object is that which is calculated by adding the aligned sizes of all the members. However, note that there is one exception to this Flexible Array Members. When the last element is an array type of size zero(in CIR), this represents the C/C++ concept of ‘flexible array member’, where as long as the type is allocated properly (or a global constant), an access through the array member may access outside of its bounds. This is necessary to represent C/C++ semantics.
The optional class keyword distinguishes C++ class declarations from
plain struct declarations. Both are semantically identical; the keyword
preserves the original source spelling.
Every member has a kind, described by CIR_RecordMemberKind, saying what
it holds, and every member is spelled with its mark.
Examples:
!rec_complete = !cir.struct<"complete" {data !u8i}>
!rec_class = !cir.struct<class "MyClass" {data !s32i}>
!rec_incomplete = !cir.struct<"incomplete" incomplete>
!anonymous = !cir.struct<{data !u8i}>
!rec_packed = !cir.struct<"p1" packed {data !u8i, data !u8i}>
!rec_pad = !cir.struct<"p3" {data !u8i, pad !cir.array<!u8i x 3>}>
!rec_empty = !cir.struct<"e" {empty !u8i}>
!rec_bits = !cir.struct<"b"
{bitfield !cir.bitfield<!u8i, [#cir.bitfield_decl<!s32i, 4>]>,
empty !cir.bitfield<[#cir.bitfield_decl<!s32i, 0, unnamed>]>}>
!recursive = !cir.struct<"Node" {data !cir.ptr<!cir.struct<"Node">>}>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
members |
|
|
name |
|
|
incomplete |
|
|
packed |
|
|
member_kinds |
|
|
is_class |
|
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. That slot is separate
from the per-member kinds described by CIR_RecordMemberKind, which say
what each variant holds. The parser rejects a mark on that slot.
Examples:
!u_complete = !cir.union<"U" {data !s32i, data !u8i}>
!u_incomplete = !cir.union<"U" incomplete>
!u_anonymous = !cir.union<{data !s32i, data !u8i}>
!u_padded = !cir.union<"U" {data !s32i, data !u8i}, padding = {!u8i}>
!u_empty = !cir.union<"U" {empty !u8i}>
!u_bits = !cir.union<"U"
{bitfield !cir.bitfield<!u8i, [#cir.bitfield_decl<!s32i, 4>]>,
empty !cir.bitfield<!u8i, [#cir.bitfield_decl<!s32i, 3, unnamed>]>}>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
members |
|
|
name |
|
|
incomplete |
|
|
packed |
|
|
padding |
|
|
member_kinds |
|
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.
VectorType#
CIR vector type
The !cir.vector type represents a one-dimensional vector.
It takes two parameters: the element type and an element count, which
records both the known minimum number of elements and whether the vector is
scalable.
Syntax:
vector-type ::= !cir.vector<size x element-type>
size ::= (decimal-literal | `[` decimal-literal `]`)
element-type ::= float-type | integer-type | bool-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>
A fixed-length vector of !cir.bool is packed one bit per element, and its
size is rounded up to a power of two of at least one byte, so
!cir.vector<4 x !cir.bool> occupies one byte and
!cir.vector<17 x !cir.bool> occupies four.
Scalable vectors are indicated by enclosing size in square brackets.
Example:
!cir.vector<[4] x !cir.int<u, 8>>
Parameters:#
Parameter |
C++ type |
Description |
|---|---|---|
element_type |
|
any cir boolean, integer, floating point |
size |
|
VoidType#
CIR void type
Syntax: !cir.void
The !cir.void type represents the C and C++ void type.
Enums#
ArgPassingKind#
Record argument passing eligibility
Cases:#
Symbol |
Value |
String |
|---|---|---|
CanPassInRegs |
|
can_pass_in_regs |
CannotPassInRegs |
|
cannot_pass_in_regs |
CanNeverPassInRegs |
|
can_never_pass_in_regs |
AsmFlavor#
ATT or Intel
Cases:#
Symbol |
Value |
String |
|---|---|---|
x86_att |
|
x86_att |
x86_intel |
|
x86_intel |
AssignKind#
CXX Assignment Operator Kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Copy |
|
copy |
Move |
|
move |
AssumeBundleKind#
Kind of cir.assume operand bundle
Cases:#
Symbol |
Value |
String |
|---|---|---|
None |
|
None |
Align |
|
align |
SeparateStorage |
|
separate_storage |
Dereferenceable |
|
dereferenceable |
AtomicFetchKind#
Binary opcode for atomic fetch-and-update operations
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 |
Maximum |
|
maximum |
Minimum |
|
minimum |
MaximumNum |
|
maximum_num |
MinimumNum |
|
minimum_num |
AwaitKind#
Await kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Init |
|
init |
User |
|
user |
Yield |
|
yield |
Final |
|
final |
CUDADeviceVarKind#
CUDA device variable kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Variable |
|
Variable |
Surface |
|
Surface |
Texture |
|
Texture |
CallingConv#
Calling convention
Cases:#
Symbol |
Value |
String |
|---|---|---|
C |
|
c |
PTXKernel |
|
ptx_kernel |
SpirFunction |
|
spir_function |
SpirKernel |
|
spir_kernel |
AMDGPUKernel |
|
amdgpu_kernel |
CaseOpKind#
Case kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Default |
|
default |
Equal |
|
equal |
Anyof |
|
anyof |
Range |
|
range |
CastKind#
Cast kind
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 |
CleanupKind#
Cleanup kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Normal |
|
normal |
EH |
|
eh |
All |
|
all |
CmpOpKind#
Compare operation kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
lt |
|
lt |
le |
|
le |
gt |
|
gt |
ge |
|
ge |
eq |
|
eq |
ne |
|
ne |
one |
|
one |
uno |
|
uno |
CmpOrdering#
Three-way comparison ordering kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Strong |
|
strong |
Weak |
|
weak |
Partial |
|
partial |
ComplexRangeKind#
Complex multiplication and division implementation
Cases:#
Symbol |
Value |
String |
|---|---|---|
Full |
|
full |
Improved |
|
improved |
Promoted |
|
promoted |
Basic |
|
basic |
CtorKind#
CXX Constructor Kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Custom |
|
custom |
Default |
|
default |
Copy |
|
copy |
Move |
|
move |
DynamicCastKind#
Dynamic cast kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Ptr |
|
ptr |
Ref |
|
ref |
FPDynamicRoundingMode#
Floating-point dynamic rounding mode
Cases:#
Symbol |
Value |
String |
|---|---|---|
ToNearest |
|
tonearest |
Downward |
|
downward |
Upward |
|
upward |
UpwardZero |
|
upwardzero |
ToNearestAway |
|
tonearestaway |
Unknown |
|
unknown |
FPExceptionMode#
Floating-point exception mode
Cases:#
Symbol |
Value |
String |
|---|---|---|
Unknown |
|
unknown |
Masked |
|
masked |
Unmasked |
|
unmasked |
FastMathFlags#
Fast-math flags
Cases:#
Symbol |
Value |
String |
|---|---|---|
none |
|
none |
nnan |
|
nnan |
ninf |
|
ninf |
nsz |
|
nsz |
arcp |
|
arcp |
contract |
|
contract |
afn |
|
afn |
reassoc |
|
reassoc |
fast |
|
fast |
FramePointerKind#
Frame pointer kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
None |
|
none |
NonLeaf |
|
non_leaf |
All |
|
all |
Reserved |
|
reserved |
NonLeafNoReserve |
|
non_leaf_no_reserve |
GlobalLinkageKind#
Linkage kind
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 |
InitCatchKind#
Allowed i32 cases: 0, 1, 2, 3, 4, 5, 6, 7
Cases:#
Symbol |
Value |
String |
|---|---|---|
Reference |
|
reference |
Pointer |
|
pointer |
Scalar |
|
scalar |
Objc |
|
objc |
TrivialCopy |
|
trivial_copy |
NonTrivialCopy |
|
non_trivial_copy |
ReferenceToPointer |
|
reference_to_pointer |
ReferenceToRecordPointer |
|
reference_to_record_pointer |
InlineKind#
Inline kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
NoInline |
|
no_inline |
AlwaysInline |
|
always_inline |
InlineHint |
|
inline_hint |
KnownFuncKind#
Known standard library entity
Cases:#
Symbol |
Value |
String |
|---|---|---|
StdFind |
|
std::find |
LangAddressSpace#
Language address space kind
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 |
LoopUnrollMode#
Loop unrolling mode
Cases:#
Symbol |
Value |
String |
|---|---|---|
Enable |
|
enable |
Disable |
|
disable |
Full |
|
full |
MemOrder#
Memory order according to C++11 memory model
Cases:#
Symbol |
Value |
String |
|---|---|---|
Relaxed |
|
relaxed |
Consume |
|
consume |
Acquire |
|
acquire |
Release |
|
release |
AcquireRelease |
|
acq_rel |
SequentiallyConsistent |
|
seq_cst |
ModRefInfo#
Whether memory may be read and/or written
Cases:#
Symbol |
Value |
String |
|---|---|---|
NoModRef |
|
none |
Ref |
|
read |
Mod |
|
write |
ModRef |
|
readwrite |
OffloadKind#
Offload kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Host |
|
host |
Device |
|
device |
RecordMemberKind#
What a record member holds
Cases:#
Symbol |
Value |
String |
|---|---|---|
Data |
|
data |
Pad |
|
pad |
Empty |
|
empty |
BitField |
|
bitfield |
SourceLanguage#
Source language
Cases:#
Symbol |
Value |
String |
|---|---|---|
C |
|
c |
CXX |
|
cxx |
OpenCLC |
|
opencl_c |
OpenCLCXX |
|
opencl_cxx |
SyncScopeKind#
Sync scope kind
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 |
TLSKind#
Thread-local storage kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
None |
|
none |
Static |
|
static |
Dynamic |
|
dynamic |
TLSModel#
TLS model
Cases:#
Symbol |
Value |
String |
|---|---|---|
GeneralDynamic |
|
tls_dyn |
LocalDynamic |
|
tls_local_dyn |
InitialExec |
|
tls_init_exec |
LocalExec |
|
tls_local_exec |
TemplateSpecializationKind#
Template specialization kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
Undeclared |
|
undeclared |
ImplicitInstantiation |
|
implicit_instantiation |
ExplicitSpecialization |
|
explicit_specialization |
ExplicitInstantiationDeclaration |
|
explicit_instantiation_declaration |
ExplicitInstantiationDefinition |
|
explicit_instantiation_definition |
UnwindTableKind#
Unwind Table Kind
Cases:#
Symbol |
Value |
String |
|---|---|---|
None |
|
none |
Sync |
|
sync |
Async |
|
async |
VisibilityKind#
C/C++ visibility
Cases:#
Symbol |
Value |
String |
|---|---|---|
Default |
|
default |
Hidden |
|
hidden |
Protected |
|
protected |
FPClassTest#
Floating-point class test flags
Cases:#
Symbol |
Value |
String |
|---|---|---|
None |
|
fcNone |
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 |