Abstract¶This document is a reference manual for the LLVM assembly language. LLVM is a Static Single Assignment (SSA) based representation that provides type safety, low-level operations, flexibility, and the capability of representing ‘all’ high-level languages cleanly. It is the common code representation used throughout all phases of the LLVM compilation strategy. Show
Introduction¶The LLVM code representation is designed to be used in three different forms: as an in-memory compiler IR, as an on-disk bitcode representation (suitable for fast loading by a Just-In-Time compiler), and as a human readable assembly language representation. This allows LLVM to provide a powerful intermediate representation for efficient compiler transformations and analysis, while providing a natural means to debug and visualize the transformations. The three different forms of LLVM are all equivalent. This document describes the human readable representation and notation. The LLVM representation aims to be light-weight and low-level while being expressive, typed, and extensible at the same time. It aims to be a “universal IR” of sorts, by being at a low enough level that high-level ideas may be cleanly mapped to it (similar to how microprocessors are “universal IR’s”, allowing many source languages to be mapped to them). By providing type information, LLVM can be used as the target of optimizations: for example, through pointer analysis, it can be proven that a C automatic variable is never accessed outside of the current function, allowing it to be promoted to a simple SSA value instead of a memory location. Well-Formedness¶It is important to note that this document describes ‘well formed’ LLVM assembly language. There is a difference between what the parser accepts and what is considered ‘well formed’. For example, the following instruction is syntactically okay, but not well formed: because the definition of Identifiers¶LLVM identifiers come in two basic types: global and local. Global identifiers (functions, global variables) begin with the
LLVM requires that values start with a prefix for two reasons: Compilers don’t need to worry about name clashes with reserved words, and the set of reserved words may be expanded in the future without penalty. Additionally, unnamed identifiers allow a compiler to quickly come up with a temporary variable without having to avoid symbol table conflicts. Reserved words in LLVM are very similar to reserved words in other languages. There are keywords for different opcodes (‘ Here is an example of LLVM code to multiply the integer variable ‘ The easy way: After strength reduction: And the hard way: %0 = add i32 %X, %X ; yields i32:%0 %1 = add i32 %0, %0 ; yields i32:%1 %result = add i32 %1, %1 This last way of multiplying
It also shows a convention that we follow in this document. When demonstrating instructions, we will follow an instruction with a comment that defines the type and name of value produced. High Level Structure¶Module Structure¶LLVM programs are composed of ; Declare the string constant as a global constant. @.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00" ; External declaration of the puts function declare i32 @puts(ptr nocapture) nounwind ; Definition of main function define i32 @main() { ; Call puts function to write out the string to stdout. call i32 @puts(ptr @.str) ret i32 0 } ; Named metadata !0 = !{i32 42, null, !"string"} !foo = !{!0} This example is made up of a global variable named “ In general, a module is made up of a list of global values (where both functions and global variables are global values). Global values are represented by a pointer to a memory location (in this case, a pointer to an array of char, and a pointer to a function), and have one of the following linkage types. Linkage Types¶All Global Variables and Functions have one of the following types of linkage: private Global values with “private ” linkage are only
directly accessible by objects in the current module. In particular, linking code into a module with a private global value may cause the private to be renamed as necessary to avoid collisions. Because the symbol is private to the module, all references can be updated. This doesn’t show up in any symbol table in the object file.internal Similar to private, but the value shows as a local symbol (STB_LOCAL in the case of ELF) in the object file. This corresponds to the notion of
the ‘static ’ keyword in C.available_externally Globals with “available_externally ” linkage are never emitted into the object file corresponding to the LLVM module. From the linker’s perspective, an available_externally global is equivalent to an external declaration. They exist to allow inlining and other optimizations to take place given knowledge of the definition of the global, which is known to be somewhere outside the module. Globals with available_externally linkage are allowed to be discarded at will, and allow
inlining and other optimizations. This linkage type is only allowed on definitions, not declarations.linkonce Globals with “linkonce ” linkage are merged with other globals of the same name when linkage occurs. This can be used to implement some forms of inline functions, templates, or other code which must be generated in each translation unit that uses it, but where the body may be overridden with a more definitive definition later. Unreferenced linkonce globals are allowed to
be discarded. Note that linkonce linkage does not actually allow the optimizer to inline the body of this function into callers because it doesn’t know if this definition of the function is the definitive definition within the program or whether it will be overridden by a stronger definition. To enable inlining and other optimizations, use “linkonce_odr ” linkage.weak “weak ” linkage has the same merging semantics as linkonce linkage, except that unreferenced globals with
weak linkage may not be discarded. This is used for globals that are declared “weak” in C source code.common “common ” linkage is most similar to “weak ” linkage, but they are used for tentative definitions in C, such as “int X; ” at global scope. Symbols with “common ” linkage are merged in the same way as weak symbols , and they may not be deleted if unreferenced. common symbols may not have an explicit section, must have a zero initializer, and
may not be marked ‘constant’. Functions and aliases may not have common linkage.appending “ Unfortunately this doesn’t correspond to any feature in .o files, so it can only be used for variables like extern_weak The semantics of this linkage follow the ELF object file model: the symbol is weak until linked, if not linked, the symbol becomes null instead of being an undefined reference.linkonce_odr , weak_odr Some languages allow
differing globals to be merged, such as two functions with different semantics. Other languages, such as C++ , ensure that only equivalent globals are ever merged (the “one definition rule” — “ODR”). Such languages can use the linkonce_odr and weak_odr linkage types to indicate that the global will only be merged with equivalent globals. These linkage types are otherwise the same as their non-odr versions.external If none of the above identifiers are used, the global is
externally visible, meaning that it participates in linkage and can be used to resolve external symbol references.It is illegal for a global variable or function declaration to have any linkage type other than Calling Conventions¶LLVM functions, calls and invokes can all have an optional calling convention specified for the call. The calling convention of any pair of dynamic caller/callee must match, or the behavior of the program is undefined. The following calling conventions are supported by LLVM, and more may be added in the future: “ccc ” - The C calling conventionThis calling convention (the default if no other calling convention is specified) matches the target C calling conventions. This calling convention supports varargs function calls and tolerates some mismatch in the
declared prototype and implemented declaration of the function (as does normal C).“fastcc ” - The fast calling conventionThis calling convention attempts to make calls as fast as possible (e.g. by passing things in registers). This calling convention allows the target to use whatever tricks it wants to produce fast code for the target, without having to conform to an externally specified ABI (Application Binary Interface).
Tail calls can only be optimized when this, the tailcc, the GHC or the HiPE convention is used. This calling convention does not support varargs and requires the prototype of all callees to exactly match the prototype of the function definition.“coldcc ” - The cold calling conventionThis calling convention attempts to make code in the caller as efficient as possible under the
assumption that the call is not commonly executed. As such, these calls often preserve all registers so that the call does not break any live ranges in the caller side. This calling convention does not support varargs and requires the prototype of all callees to exactly match the prototype of the function definition. Furthermore the inliner doesn’t consider such function calls for inlining.“cc 10 ” - GHC conventionThis calling convention has been implemented specifically for use by the Glasgow Haskell Compiler (GHC). It passes everything in registers, going to extremes to achieve this by disabling callee save registers. This calling convention should not be used lightly but only for specific situations such as an alternative to the register pinning performance technique often used when implementing functional programming languages. At the moment only X86 supports this convention and it has the following limitations:
This calling convention supports tail call optimization but requires both the caller and callee are using it. “cc 11 ” - The HiPE calling
conventionThis calling convention has been implemented specifically for use by the High-Performance Erlang (HiPE) compiler, the native code compiler of the Ericsson’s Open Source Erlang/OTP system. It uses more registers for argument passing than the ordinary C calling convention and defines no callee-saved registers. The calling convention
properly supports tail call optimization but requires that both the caller and the callee use it. It uses a register pinning mechanism, similar to GHC’s convention, for keeping frequently accessed runtime components pinned to specific hardware registers. At the moment only X86 supports this convention (both 32 and 64 bit).“webkit_jscc ” - WebKit’s JavaScript calling conventionThis
calling convention has been implemented for WebKit FTL JIT. It passes arguments on the stack right to left (as cdecl does), and returns a value in the platform’s customary return register.“anyregcc ” - Dynamic calling convention for code patchingThis is a special convention that supports patching an arbitrary code sequence in place of a call site. This convention forces the call arguments into registers but allows
them to be dynamically allocated. This can currently only be used with calls to llvm.experimental.patchpoint because only this intrinsic records the location of its arguments in a side table. See Stack maps and patch points in LLVM.“preserve_mostcc ” - The PreserveMost calling conventionThis calling convention attempts to make the code in the caller as unintrusive as possible. This convention behaves identically to the C calling convention on how arguments and return values are passed, but it uses a different set of caller/callee-saved registers. This alleviates the burden of saving and recovering a large register set before and after the call in the caller. If the arguments are passed in callee-saved registers, then they will be preserved by the callee across the call. This doesn’t apply for values returned in callee-saved registers.
The idea behind this convention is to support calls to runtime functions that have a hot path and a cold path. The hot path is usually a small piece of code that doesn’t use many registers. The cold path might need to call out to another function and therefore only needs to preserve the caller-saved registers, which haven’t already been saved by the caller. The PreserveMost calling convention is very similar to the cold calling convention in terms of caller/callee-saved registers, but they are used for different types of function calls. coldcc is for function calls that are rarely executed, whereas preserve_mostcc function calls are intended to be on the hot path and definitely executed a lot. Furthermore preserve_mostcc doesn’t prevent the inliner from inlining the function call. This calling convention will be used by a future version of the ObjectiveC runtime and should therefore still be considered experimental at this time. Although this convention was created to optimize certain runtime calls to the ObjectiveC runtime, it is not limited to this runtime and might be used by other runtimes in the future too. The current implementation only supports X86-64, but the intention is to support more architectures in the future. “preserve_allcc ” - The PreserveAll calling conventionThis calling convention attempts to make the code in the caller even less intrusive than the PreserveMost calling convention. This calling convention also behaves identical to the C calling convention on how arguments and return values are passed, but it uses a different set of caller/callee-saved registers. This removes the burden of saving and recovering a large register set before and after the call in the caller. If the arguments are passed in callee-saved registers, then they will be preserved by the callee across the call. This doesn’t apply for values returned in callee-saved registers.
The idea behind this convention is to support calls to runtime functions that don’t need to call out to any other functions. This calling convention, like the PreserveMost calling convention, will be used by a future version of the ObjectiveC runtime and should be considered experimental at this time. “cxx_fast_tlscc ” - The CXX_FAST_TLS calling convention for access functionsClang generates an access function to access C++-style TLS. The access function generally has an entry block, an exit block and an initialization block that is run at the first time. The entry and exit blocks can access a few TLS IR variables, each access will be lowered to a platform-specific sequence. This calling convention aims to minimize overhead in the caller by preserving as many registers as possible (all the registers that are preserved on the fast path, composed of the entry and exit blocks). This calling convention behaves identical to the C calling convention on how arguments and return values are passed, but it uses a different set of caller/callee-saved registers. Given that each platform has its own lowering sequence, hence its own set of preserved registers, we can’t use the existing PreserveMost.
tailcc ” - Tail callable calling conventionThis calling convention ensures that calls in tail
position will always be tail call optimized. This calling convention is equivalent to fastcc, except for an additional guarantee that tail calls will be produced whenever possible. Tail calls can only be optimized when this, the fastcc, the GHC or the HiPE convention is used. This calling convention does not support varargs and requires the prototype of all callees to exactly match the prototype of the
function definition.“swiftcc ” - This calling convention is used for Swift language.
swifttailcc ”This calling convention is like swiftcc in most respects, but also the callee pops the argument area of the stack so that mandatory tail calls are possible
as in tailcc .“cfguard_checkcc ” - Windows Control Flow Guard (Check mechanism)This calling convention is used for the Control Flow Guard check function, calls to which can be inserted before indirect calls to check that the call target is a valid function address. The check function has no return value, but it will trigger an OS-level error if the address is not a valid target. The set of registers preserved by the check function, and the register containing the target address are architecture-specific.
cc <n> ” - Numbered conventionAny calling convention may be specified by number, allowing target-specific calling conventions to be used. Target specific calling conventions start at 64.More calling conventions can be added/defined on an as-needed basis, to support Pascal conventions or any other well-known target-independent convention. Visibility Styles¶All Global Variables and Functions have one of the following visibility styles: “default ” - Default styleOn targets that use the ELF object file format,
default visibility means that the declaration is visible to other modules and, in shared libraries, means that the declared entity may be overridden. On Darwin, default visibility means that the declaration is visible to other modules. On XCOFF, default visibility means no explicit visibility bit will be set and whether the symbol is visible (i.e “exported”) to other modules depends primarily on export lists provided to the linker. Default visibility corresponds to “external linkage” in the
language.“hidden ” - Hidden styleTwo declarations of an object with hidden visibility refer to the same object if they are in the same shared object. Usually, hidden visibility indicates that the symbol will not be placed into the dynamic symbol table, so no other module (executable or shared library) can reference it directly.“protected ” - Protected styleOn ELF, protected visibility indicates that the symbol will be placed in the dynamic symbol table, but
that references within the defining module will bind to the local symbol. That is, the symbol cannot be overridden by another module.A symbol with DLL Storage Classes¶All Global Variables, Functions and Aliases can have one of the following DLL storage class: dllimport “dllimport ” causes the compiler to reference a function or variable via a global pointer to a pointer that is set up by the DLL exporting the symbol. On Microsoft Windows targets, the pointer name is formed by combining __imp_ and the function or variable name.dllexport On Microsoft Windows targets, “dllexport ” causes the compiler to provide a global pointer to a pointer
in a DLL, so that it can be referenced with the dllimport attribute. the pointer name is formed by combining __imp_ and the function or variable name. On XCOFF targets, dllexport indicates that the symbol will be made visible to other modules using “exported” visibility and thus placed by the linker in the loader section symbol table. Since this storage class exists for defining a dll interface, the compiler, assembler and linker know it is externally referenced and must refrain from deleting
the symbol.A symbol with Thread Local Storage Models¶A variable may be defined as localdynamic For variables that are only used within the current shared library.initialexec For variables in modules that will not be loaded dynamically.localexec For variables defined in the executable and only used within it.If no explicit model is given, the “general dynamic” model is used. The models correspond to the ELF TLS models; see ELF Handling For Thread-Local Storage for more information on under which circumstances the different models may be used. The target may choose a different TLS model if the specified model is not supported, or if a better choice of model can be made. A model can also be specified in an alias, but then it only governs how the alias is accessed. It will not have any effect in the aliasee. For platforms without linker support of ELF TLS model, the -femulated-tls flag can be used to generate GCC compatible emulated TLS code. Runtime Preemption Specifiers¶Global variables, functions and aliases may have an
optional runtime preemption specifier. If a preemption specifier isn’t given explicitly, then a symbol is assumed to be dso_preemptable Indicates that the function or variable may be replaced by a symbol from outside the linkage unit at runtime.dso_local The compiler may assume that a function or variable marked as dso_local will resolve to a symbol within the same linkage unit. Direct access will be generated even if the definition is not within this
compilation unit.Structure Types¶LLVM IR allows you to specify both “identified” and “literal” structure types. Literal types are uniqued structurally, but identified types are never uniqued. An opaque structural type can also be used to forward declare a type that is not yet available. An example of an identified structure specification is: %mytype = type { %mytype*, i32 } Prior to the LLVM 3.0 release, identified types were structurally uniqued. Only literal types are uniqued in recent versions of LLVM. Non-Integral Pointer Type¶Note: non-integral pointer types are a work in progress, and they should be considered experimental at this time. LLVM IR optionally allows the frontend to denote pointers in certain address spaces as “non-integral” via the datalayout string. Non-integral pointer types represent pointers that have an unspecified bitwise representation; that is, the integral representation may be target dependent or unstable (not backed by a fixed integer).
If the frontend wishes to observe a particular value following a cast, the generated IR must fence with the underlying environment in an
implementation defined manner. (In practice, this tends to require From the perspective of the optimizer, Global Variables¶Global variables define regions of memory allocated at compilation time instead of run-time. Global variable definitions must be initialized. Global variables in other translation units can also be declared, in which case they don’t have an initializer. Global variables can optionally specify a linkage type. Either global variable definitions or declarations may have an explicit section to be placed in and may have an optional explicit alignment specified. If there is a mismatch between the explicit or inferred section information for the variable declaration and its definition the resulting behavior is undefined. A variable may be defined as a global LLVM explicitly allows declarations of global variables to be marked constant, even if the final definition of the global is not. This capability can be used to enable slightly better optimization of the program, but requires the language definition to guarantee that optimizations based on the ‘constantness’ are valid for the translation units that do not include the definition. As SSA values, global variables define pointer values that are in scope (i.e. they dominate) all basic blocks in the program. Global variables always define a pointer to their “content” type because they describe a region of memory, and all memory objects in LLVM are accessed through pointers. Global variables can be marked with If the A global variable may be declared to reside in a target-specific numbered address space. For targets that support them, address spaces may affect how optimizations are performed and/or what target instructions are used to access the variable. The default address space is zero. The address space qualifier must precede any other attributes. LLVM allows an explicit section to be specified for globals. If the target supports it, it will emit globals to the section specified. Additionally, the global can placed in a comdat if the target has the necessary support. External declarations may have an explicit section specified. Section information is retained in LLVM IR for targets that make use of this information. Attaching section information to an external declaration is an assertion that its definition is located in the specified section. If the definition is located in a different section, the behavior is undefined. By default, global initializers are optimized by assuming that global variables defined within the module are not modified from their initial values before the start of the global initializer. This is true even for variables potentially accessible from outside the module, including
those with external linkage or appearing in An explicit alignment may be specified for a global, which must be a power of 2. If not present, or if the alignment is set to zero, the alignment of the global is set by the target to whatever it feels convenient. If an explicit alignment is specified, the global is forced to have exactly that alignment. Targets and optimizers are not
allowed to over-align the global if the global has an assigned section. In this case, the extra alignment could be observable: for example, code could assume that the globals are densely packed in their section and try to iterate over them as an array, alignment padding would break this iteration. The maximum alignment is For global variables declarations, as well as definitions that may be replaced at link time ( Globals can also have a DLL storage class, an optional runtime preemption specifier, an optional global attributes and an optional list of attached metadata. Variables and aliases can have a Thread Local Storage Model. Scalable vectors cannot be global variables or members of arrays because their size is unknown at compile time. They are allowed in structs to facilitate intrinsics returning multiple values. Structs containing scalable vectors cannot be used in loads, stores, allocas, or GEPs. Syntax: @<GlobalVarName> = [Linkage] [PreemptionSpecifier] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized] <global | constant> <Type> [<InitializerConstant>] [, section "name"] [, partition "name"] [, comdat [($name)]] [, align <Alignment>] [, no_sanitize_address] [, no_sanitize_hwaddress] [, sanitize_address_dyninit] [, sanitize_memtag] (, !name !N)* For example, the following defines a global in a numbered address space with an initializer, section, and alignment: @G = addrspace(5) constant float 1.0, section "foo", align 4 The following example just declares a global variable The following example defines a thread-local global with the @G = thread_local(initialexec) global i32 0, align 4 Functions¶LLVM function definitions consist of the “ Syntax: define [linkage] [PreemptionSpecifier] [visibility] [DLLStorageClass] [cconv] [ret attrs] <ResultType> @<FunctionName> ([argument list]) [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [fn Attrs] [section "name"] [partition "name"] [comdat [($name)]] [align N] [gc] [prefix Constant] [prologue Constant] [personality Constant] (!name !N)* { ... } The argument list is a comma separated sequence of arguments where each argument is of the following form: Syntax: <type> [parameter Attrs] [name] LLVM function declarations consist of the “ Syntax: declare [linkage] [visibility] [DLLStorageClass] [cconv] [ret attrs] <ResultType> @<FunctionName> ([argument list]) [(unnamed_addr|local_unnamed_addr)] [align N] [gc] [prefix Constant] [prologue Constant] A function definition contains a list of basic blocks, forming the CFG (Control Flow Graph) for the function. Each basic block may optionally start with a label (giving the basic block a symbol table entry), contains a list of instructions, and ends with a terminator instruction (such as a branch or function return). If an explicit label name is not provided, a block is assigned an implicit numbered label, using the next value from the same counter as used for unnamed temporaries (see above). For example, if a function entry block does not have an explicit label, it will be assigned label “%0”, then the first unnamed temporary in that block will be “%1”, etc. If a numeric label is explicitly specified, it must match the numeric label that would be used implicitly. The first basic block in a function is special in two ways: it is immediately executed on entrance to the function, and it is not allowed to have predecessor basic blocks (i.e. there can not be any branches to the entry block of a function). Because the block can have no predecessors, it also cannot have any PHI nodes. LLVM allows an explicit section to be specified for functions. If the target supports it, it will emit functions to the section specified. Additionally, the function can be placed in a COMDAT. An explicit alignment may be specified for a function. If not present, or if the alignment is set to zero, the alignment of the function is set by the target to whatever it feels convenient. If an explicit alignment is specified, the function is forced to have at least that much alignment. All alignments must be a power of 2. If the If the If an explicit address space is not given, it will default to the program address space from the datalayout string. Aliases¶Aliases, unlike function or variables, don’t create any new data. They are just a new symbol and metadata for an existing position. Aliases have a name and an aliasee that is either a global value or a constant expression. Aliases may have an optional linkage type, an optional runtime preemption specifier, an optional visibility style, an optional DLL storage class and an optional tls model. Syntax: @<Name> = [Linkage] [PreemptionSpecifier] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] alias <AliaseeTy>, <AliaseeTy>* @<Aliasee> [, partition "name"] The linkage must be one of Aliases that are not If the Since aliases are only a second name, some restrictions apply, of which some can only be checked when producing an object file:
IFuncs¶IFuncs, like as aliases, don’t create any new data or func. They are just a new symbol that dynamic linker resolves at runtime by calling a resolver function. IFuncs have a name and a resolver that is a function called by dynamic linker that returns address of another function associated with the name. IFunc may have an optional linkage type and an optional visibility style. Syntax: @<Name> = [Linkage] [PreemptionSpecifier] [Visibility] ifunc <IFuncTy>, <ResolverTy>* @<Resolver> [, partition "name"] Comdats¶Comdat IR provides access to object file COMDAT/section group functionality which represents interrelated sections. Comdats have a name which represents the COMDAT key and a selection kind to provide input on how the linker deduplicates comdats with the same key in two different object files. A comdat must be included or omitted as a unit. Discarding the whole comdat is allowed but discarding a subset is not. A global object may be a member of at most one comdat. Aliases are placed in the same COMDAT that their aliasee computes to, if any. Syntax: $<Name> = comdat SelectionKind For selection kinds other than any The linker may choose any COMDAT key, the choice is arbitrary.exactmatch The linker may choose any COMDAT key but the sections must contain the same data.largest The linker will choose the section containing the largest COMDAT key.nodeduplicate No deduplication is performed.samesize The linker may choose any COMDAT key but the sections must contain the same amount of data.
Here is an example of a COFF COMDAT where a function will only be selected if the COMDAT key’s section is the largest: $foo = comdat largest @foo = global i32 2, comdat($foo) define void @bar() comdat($foo) { ret void } In a COFF object file, this will create a COMDAT section with selection kind As a syntactic sugar the $foo = comdat any @foo = global i32 2, comdat @bar = global i32 3, comdat($foo) There are some restrictions on the properties of the global object. It, or an alias to it, must have the same name as the COMDAT group when targeting COFF. The contents and size of this object may be used during link-time to determine which COMDAT groups get selected depending on the selection kind. Because the name of the object must match the name of the COMDAT group, the linkage of the global object must not be local; local symbols can get renamed if a collision occurs in the symbol table. The combined use of COMDATS and section attributes may yield surprising results. For example: $foo = comdat any $bar = comdat any @g1 = global i32 42, section "sec", comdat($foo) @g2 = global i32 42, section "sec", comdat($bar) From the object file perspective, this requires the creation of two sections with the same name. This is necessary because both globals belong to different COMDAT groups and COMDATs, at the object file level, are represented by sections. Note that certain IR constructs like global variables and functions may create COMDATs in the object file in addition to any which are specified using COMDAT IR. This arises when the code generator is configured to emit globals in individual sections (e.g. when -data-sections or -function-sections is supplied to llc). Parameter Attributes¶The return type and each parameter of a function type may have a set of parameter attributes associated with them. Parameter attributes are used to communicate additional information about the result or parameters of a function. Parameter attributes are considered to be part of the function, not of the function type, so functions with different parameter attributes can have the same function type. Parameter attributes are simple keywords that follow the type specified. If multiple parameter attributes are needed, they are space separated. For example: declare i32 @printf(ptr noalias nocapture, ...) declare i32 @atoi(i8 zeroext) declare signext i8 @returns_signed_char() Note that any attributes for the function result ( Currently, only the following parameter attributes are defined: zeroext This indicates to the code generator that the parameter or return value should be zero-extended to the extent required by the target’s ABI by the caller (for a parameter) or the callee (for a return value).signext This indicates to the code generator that the parameter or return value should be sign-extended to the extent required by the target’s ABI (which is
usually 32-bits) by the caller (for a parameter) or the callee (for a return value).inreg This indicates that this parameter or return value should be treated in a special target-dependent fashion while emitting code for a function call or return (usually, by putting it in a register as opposed to memory, though some targets use it to distinguish between two different kinds of registers). Use of this attribute is target-specific.byval(<ty>) This indicates
that the pointer parameter should really be passed by value to the function. The attribute implies that a hidden copy of the pointee is made between the caller and the callee, so the callee is unable to modify the value in the caller. This attribute is only valid on LLVM pointer arguments. It is generally used to pass structs and arrays by value, but is also valid on pointers to scalars. The copy is considered to belong to the caller not the callee (for example, The byval type argument indicates the in-memory value type, and must be the same as the pointee type of the argument. The byval attribute also supports specifying an alignment with the align attribute. It indicates the alignment of the stack slot to form and the known alignment of the pointer specified to the call site. If the alignment is not specified, then the code generator makes a target-specific assumption.
preallocated(<ty>) This
indicates that the pointer parameter should really be passed by value to the function, and that the pointer parameter’s pointee has already been initialized before the call instruction. This attribute is only valid on LLVM pointer arguments. The argument must be the value returned by the appropriate llvm.call.preallocated.arg on non A non The preallocated attribute requires a type argument, which must be the same as the pointee type of the argument. The preallocated attribute also supports specifying an alignment with the align attribute. It indicates the alignment of the stack slot to form and the known alignment of the pointer specified to the call site. If the alignment is not specified, then the code generator makes a target-specific assumption.
sret(<ty>) This indicates that the pointer parameter specifies the address of a structure that is the return value of the function in the source program. This pointer must be guaranteed by the caller to be valid: loads and stores to the structure may be assumed by the callee not to trap and to be properly aligned. This is not a valid attribute for return values. The sret type argument specifies the in memory type, which must be the same as the pointee type of the argument.
align <n> or align(<n>) This indicates that the pointer value or vector of pointers has the specified alignment. If applied to a vector of pointers, all pointers (elements) have the specified alignment. If the pointer value does not have the specified alignment,
poison value is returned or passed instead. The Note that this attribute has additional semantics when combined with the noalias This indicates that memory locations accessed via pointer values based on the argument or return value are not also accessed, during the execution of the function, via pointer values not based on the argument or return value. This guarantee only holds for memory locations that are modified, by any means, during the execution of the function. The attribute on a return value also has additional semantics described below. The caller shares the responsibility with the callee for ensuring that these requirements are met. For further details, please see the discussion of the NoAlias response in alias analysis. Note that this definition of For function return values, C99’s nocapture This indicates that the callee does not capture the pointer. This is not a valid attribute for return values. This attribute applies only to the particular copy of the pointer passed in this argument. A caller could pass two copies of the same pointer with one being annotated nocapture and the other not, and the callee could validly capture through the
non annotated parameter.define void @f(ptr nocapture %a, ptr %b) { ; (capture %b) } call void @f(ptr @glb, ptr @glb) ; well-defined nofree This indicates that callee does not free the pointer argument. This is not a valid attribute for return values.nest This indicates that the pointer parameter can be excised using the trampoline intrinsics. This is not a valid attribute for return values and can only be applied to one
parameter.returned This indicates that the function always returns the argument as its return value. This is a hint to the optimizer and code generator used when generating the caller, allowing value propagation, tail call optimization, and omission of register saves and restores in some cases; it is not checked or enforced when generating the callee. The parameter and the function return type must be valid operands for the
bitcast instruction. This is not a valid attribute for return values and can only be applied to one parameter.nonnull This indicates that the parameter or return pointer is not null. This attribute may only be applied to pointer typed parameters. This is not checked or enforced by LLVM; if the parameter or return pointer is null,
poison value is returned or passed instead. The nonnull attribute should be combined with the noundef attribute to ensure a pointer is not null or otherwise the behavior is undefined.dereferenceable(<n>) This indicates that the parameter or return pointer is dereferenceable. This attribute may only be applied to pointer typed parameters. A pointer that is dereferenceable can be loaded from
speculatively without a risk of trapping. The number of bytes known to be dereferenceable must be provided in parentheses. It is legal for the number of bytes to be less than the size of the pointee type. The nonnull attribute does not imply dereferenceability (consider a pointer to one element past the end of an array), however dereferenceable(<n>) does imply nonnull in addrspace(0) (which is the default address space), except if the null_pointer_is_valid function attribute is present. n should be a positive
number. The pointer should be well defined, otherwise it is undefined behavior. This means dereferenceable(<n>) implies noundef .dereferenceable_or_null(<n>) This indicates that the parameter or return value isn’t both non-null and non-dereferenceable (up to <n> bytes) at the same time. All non-null pointers tagged with dereferenceable_or_null(<n>) are dereferenceable(<n>) . For address space 0 dereferenceable_or_null(<n>) implies that a pointer is exactly one of dereferenceable(<n>) or null , and in other address spaces dereferenceable_or_null(<n>) implies that a pointer is at least
one of dereferenceable(<n>) or null (i.e. it may be both null and dereferenceable(<n>) ). This attribute may only be applied to pointer typed parameters.swiftself This indicates that the parameter is the self/context parameter. This is not a valid attribute for return values and can only be applied to one parameter.swiftasync This indicates that the parameter is the asynchronous context parameter and triggers the creation of a target-specific extended frame record to store this
pointer. This is not a valid attribute for return values and can only be applied to one parameter.swifterror This attribute is motivated to model and optimize Swift error handling. It can be applied to a parameter with pointer to pointer type or a pointer-sized alloca. At the call site, the actual argument that corresponds to a These constraints allow the calling convention to optimize access to These constraints also allow LLVM to assume that a immarg This indicates the parameter is required to be an immediate value. This must be a trivial immediate integer or floating-point constant. Undef or constant expressions are not valid. This is only valid on intrinsic declarations and cannot be applied to a call site or
arbitrary function.noundef This attribute applies to parameters and return values. If the value representation contains any undefined or poison bits, the behavior is undefined. Note that this does not refer to padding introduced by the type’s storage representation.alignstack(<n>) This indicates the alignment that should be considered by the backend when assigning this parameter to a stack slot during calling convention lowering. The enforcement of the specified
alignment is target-dependent, as target-specific calling convention rules may override this value. This attribute serves the purpose of carrying language specific alignment information that is not mapped to base types in the backend (for example, over-alignment specification through language attributes).allocalign The function parameter marked with this attribute is is the alignment in bytes of the newly allocated block returned by this function. The returned value must either
have the specified alignment or be the null pointer. The return value MAY be more aligned than the requested alignment, but not less aligned. Invalid (e.g. non-power-of-2) alignments are permitted for the allocalign parameter, so long as the returned pointer is null. This attribute may only be applied to integer parameters.allocptr The function parameter marked with this attribute is the pointer that will be manipulated by the allocator. For a realloc-like function the pointer
will be invalidated upon success (but the same address may be returned), for a free-like function the pointer will always be invalidated.readnone This attribute indicates that the function does not dereference that pointer argument, even though it may read or write the memory that the pointer points to if accessed through other pointers. If a function reads from or writes to a readnone pointer argument, the behavior is undefined. readonly This attribute indicates that the function does not write through this pointer argument, even though it may write to the memory that the pointer points to. If a function writes to a readonly pointer argument, the behavior is undefined. writeonly This attribute indicates that the function may write to, but does not read through this pointer argument (even though it may read from the memory that the pointer points to). If a function reads from a writeonly pointer argument, the behavior is undefined. Garbage Collector Strategy Names¶Each function may specify a garbage collector strategy name, which is simply a string: define void @f() gc "name" { ... } The supported values of name includes those built in to LLVM and any provided by loaded plugins. Specifying a GC strategy will cause the compiler to alter its output in order to support the named garbage collection algorithm. Note that LLVM itself does not contain a garbage collector, this functionality is restricted to generating machine code which can interoperate with a collector provided externally. Prefix Data¶Prefix data is data associated with a function which the code generator will emit immediately before the function’s entrypoint. The purpose of this feature is to allow frontends to associate language-specific runtime metadata with specific functions and make it available through the function pointer while still allowing the function pointer to be called. To access the data for a given function, a program may bitcast the function pointer to a pointer to the constant’s type and dereference index -1. This implies that the IR symbol points just past the end of the prefix data. For instance, take the example of a function annotated with a single define void @f() prefix i32 123 { ... } The prefix data can be referenced as, %a = getelementptr inbounds i32, ptr @f, i32 -1 %b = load i32, ptr %a Prefix data is laid out as if it were an initializer for a global variable of the prefix data’s type. The function will be placed such that the beginning of the prefix data is aligned. This means that if the size of the prefix data is not a multiple of the alignment size, the function’s entrypoint will not be aligned. If alignment of the function’s entrypoint is desired, padding must be added to the prefix data. A function may have prefix data but no body. This has similar semantics to the Prologue Data¶The To maintain the semantics of ordinary function calls, the prologue data must have a particular format. Specifically, it must begin with a sequence of bytes which decode to a sequence of machine instructions, valid for the module’s target, which transfer control to the point immediately succeeding the prologue data, without performing any other visible action. This allows the inliner and other passes to reason about the semantics of the function definition without needing to reason about the prologue data. Obviously this makes the format of the prologue data highly target dependent. A trivial example of valid prologue data for the x86 architecture is define void @f() prologue i8 144 { ... } Generally prologue data can be formed by encoding a relative branch instruction which skips the metadata, as in this example of valid prologue data for the x86_64 architecture, where the first two bytes encode %0 = type <{ i8, i8, ptr }> define void @f() prologue %0 <{ i8 235, i8 8, ptr @md}> { ... } A function may have prologue data but no body. This has similar semantics to the Personality Function¶The Attribute Groups¶Attribute groups are groups of attributes that are referenced by objects within the IR. They are important for keeping An attribute group is a module-level object. To use an attribute group, an object references the attribute group’s ID (e.g. Here is an example of attribute groups for a function that should always be inlined, has a stack alignment of 4, and which shouldn’t use SSE instructions: ; Target-independent attributes: attributes #0 = { alwaysinline alignstack=4 } ; Target-dependent attributes: attributes #1 = { "no-sse" } ; Function @f has attributes: alwaysinline, alignstack=4, and "no-sse". define void @f() #0 #1 { ... } Function Attributes¶Function attributes are set to communicate additional information about a function. Function attributes are considered to be part of the function, not of the function type, so functions with different function attributes can have the same function type. Function attributes are simple keywords that follow the type specified. If multiple attributes are needed, they are space separated. For example: define void @f() noinline { ... } define void @f() alwaysinline { ... } define void @f() alwaysinline optsize { ... } define void @f() optsize { ... } alignstack(<n>) This attribute indicates that, when emitting the prologue and epilogue, the backend should forcibly align the
stack pointer. Specify the desired alignment, which must be a power of two, in parentheses."alloc-family"="FAMILY" This indicates which “family” an allocator function is part of. To avoid collisions, the family name should match the mangled name of the primary allocator function, that is “malloc” for malloc/calloc/realloc/free, “_Znwm” for ::operator::new and ::operator::delete , and “_ZnwmSt11align_val_t” for aligned ::operator::new and ::operator::delete . Matching malloc/realloc/free calls within a family can be optimized,
but mismatched ones will be left alone.allockind("KIND") Describes the behavior of an allocation function. The KIND string contains comma separated entries from the following options:
The first three options are mutually exclusive, and the remaining options describe more details of how the function behaves. The remaining options are invalid for “free”-type functions. allocsize(<EltSizeParam>[, <NumEltsParam>]) This attribute indicates that the annotated function will always return at least a given number
of bytes (or null). Its arguments are zero-indexed parameter numbers; if one argument is provided, then it’s assumed that at least CallSite.Args[EltSizeParam] bytes will be available at the returned pointer. If two are provided, then it’s assumed that CallSite.Args[EltSizeParam] * CallSite.Args[NumEltsParam] bytes are available. The referenced parameters must be integer types. No assumptions are made about the contents of the returned block of memory.alwaysinline This attribute indicates that the inliner should attempt to inline this function into
callers whenever possible, ignoring any active inlining size threshold for this caller.builtin This indicates that the callee function at a call site should be recognized as a built-in function, even though the function’s declaration uses the nobuiltin attribute. This is only valid at call sites for direct calls to functions that are declared with the nobuiltin attribute.cold This attribute indicates that this function is rarely called. When computing edge
weights, basic blocks post-dominated by a cold function call are also considered to be cold; and, thus, given low weight.convergent In some parallel execution models, there exist operations that cannot be made control-dependent on any additional values. We call such operations The When it appears on a call/invoke, the The optimizer may remove the
disable_sanitizer_instrumentation When instrumenting code with sanitizers, it can be important to skip certain functions to ensure no instrumentation is applied to them. This attribute is not always similar to absent
"dontcall-error" This attribute denotes that an error diagnostic should be emitted when a call of a function with this attribute is not eliminated via optimization. Front ends can provide optional srcloc metadata nodes on
call sites of such callees to attach information about where in the source language such a call came from. A string value can be provided as a note."dontcall-warn" This attribute denotes that a warning diagnostic should be emitted when a call of a function with this attribute is not eliminated via optimization. Front ends can provide optional srcloc metadata nodes on call sites of such callees to attach information about where in the source language such a call came from. A string
value can be provided as a note.fn_ret_thunk_extern This attribute tells the code generator that returns from functions should be replaced with jumps to externally-defined architecture-specific symbols. For X86, this symbol’s identifier is __x86_return_thunk ."frame-pointer" This attribute tells the code generator whether the function should keep the frame pointer. The code generator may emit the frame pointer even if this attribute says the frame pointer can be eliminated. The allowed string values are:
hot This attribute indicates that this function is a hot spot of the program execution. The function will be optimized more aggressively and will be placed into special subsection of the text section to improving locality. When profile feedback is enabled, this attribute has the precedence over the profile information. By marking a function inlinehint This attribute indicates that the source code contained a hint that inlining this function is desirable (such as the “inline” keyword in C/C++). It is just a hint; it imposes no requirements on
the inliner.jumptable This attribute indicates that the function should be added to a jump-instruction table at code-generation time, and that all address-taken references to this function should be replaced with a reference to the appropriate jump-instruction-table function pointer. Note that this creates a new pointer for the original function, which means that code that depends on function-pointer identity can break. So, any function annotated with jumptable must also be
unnamed_addr .memory(...) This attribute specifies the possible memory effects of the call-site or function. It allows specifying the possible access kinds (
The supported memory location kinds are:
If the The memory effects of a call can be computed as minsize This attribute suggests that optimization passes and code generator
passes make choices that keep the code size of this function as small as possible and perform optimizations that may sacrifice runtime performance in order to minimize the size of the generated code.naked This attribute disables prologue / epilogue emission for the function. This can have very system-specific consequences."no-inline-line-tables" When this attribute is set to true, the inliner discards source locations when inlining code and instead uses the source location
of the call site. Breakpoints set on code that was inlined into the current function will not fire during the execution of the inlined call sites. If the debugger stops inside an inlined call site, it will appear to be stopped at the outermost inlined call site.no-jump-tables When this attribute is set to true, the jump tables and lookup tables that can be generated from a switch case lowering are disabled.nobuiltin This indicates that the callee function at a call
site is not recognized as a built-in function. LLVM will retain the original call and not replace it with equivalent code based on the semantics of the built-in function, unless the call site uses the builtin attribute. This is valid at call sites and on function declarations and definitions.noduplicate This attribute indicates that calls to the function cannot be duplicated. A call to a A function containing a nofree This function attribute indicates that the function does not, directly or transitively, call a memory-deallocation function ( As a result, uncaptured pointers that are known to be dereferenceable prior to a call to a function with the A
noimplicitfloat Disallows implicit floating-point code. This inhibits optimizations that use floating-point code and floating-point registers for operations that are not nominally floating-point. LLVM instructions that perform floating-point operations or require access to floating-point registers may still cause floating-point code to be generated. Also inhibits optimizations that create SIMD/vector code and registers from scalar code such as vectorization or memcpy/memset optimization. This includes integer vectors. Vector instructions present in IR may still cause vector code to be generated. noinline This attribute indicates that the inliner
should never inline this function in any situation. This attribute may not be used together with the alwaysinline attribute.nomerge This attribute indicates that calls to this function should never be merged during optimization. For example, it will prevent tail merging otherwise identical code sequences that raise an exception or terminate the program. Tail merging normally reduces the precision of source location information, making stack traces less useful for debugging. This
attribute gives the user control over the tradeoff between code size and debug information precision.nonlazybind This attribute suppresses lazy symbol binding for the function. This may make calls to the function faster, at the cost of extra program startup time if the function is not called during program startup.noprofile This function attribute prevents instrumentation based profiling, used for coverage or profile based optimization, from being added to a
function. It also blocks inlining if the caller and callee have different values of this attribute.skipprofile This function attribute prevents instrumentation based profiling, used for coverage or profile based optimization, from being added to a function. This attribute does not restrict inlining, so instrumented instruction could end up in this function.noredzone This attribute indicates that the code generator should not use a red zone, even if the
target-specific ABI normally permits it.indirect-tls-seg-refs This attribute indicates that the code generator should not use direct TLS access through segment registers, even if the target-specific ABI normally permits it.noreturn This function attribute indicates that the function never returns normally, hence through a return instruction. This produces undefined behavior at runtime if the function ever does dynamically return. Annotated functions may still raise an
exception, i.a., nounwind is not implied.norecurse This function attribute indicates that the function does not call itself either directly or indirectly down any possible call path. This produces undefined behavior at runtime if the function ever does recurse.willreturn This function attribute indicates that a call of this function will either exhibit undefined behavior or comes back and continues execution at a point in the
existing call stack that includes the current invocation. Annotated functions may still raise an exception, i.a., nounwind is not implied. If an invocation of an annotated function does not return control back to a point in the call stack, the behavior is undefined.nosync This function attribute indicates that the function does not communicate (synchronize) with another thread through memory or other well-defined means. Synchronization is considered possible in the presence of
atomic accesses that enforce an order, thus not “unordered” and “monotonic”, volatile accesses, as well as convergent function calls. Note that through convergent function calls non-memory communication, e.g., cross-lane operations, are possible and are also considered synchronization. However convergent does not contradict nosync. If an annotated function does ever synchronize with another thread, the behavior is
undefined.nounwind This function attribute indicates that the function never raises an exception. If the function does raise an exception, its runtime behavior is undefined. However, functions marked nounwind may still trap or generate asynchronous exceptions. Exception handling schemes that are recognized by LLVM to handle asynchronous exceptions, such as SEH, will still provide their implementation defined semantics.nosanitize_bounds This attribute indicates that
bounds checking sanitizer instrumentation is disabled for this function.nosanitize_coverage This attribute indicates that SanitizerCoverage instrumentation is disabled for this function.null_pointer_is_valid If null_pointer_is_valid is set, then the null address in address-space 0 is considered to be a valid address for memory loads and stores. Any analysis or optimization should not treat dereferencing a pointer to null as undefined behavior in this function. Note: Comparing address of a
global variable to null may still evaluate to false because of a limitation in querying this attribute inside constant expressions.optforfuzzing This attribute indicates that this function should be optimized for maximum fuzzing signal.optnone This function attribute indicates that most optimization passes will skip this function, with the exception of interprocedural optimization passes. Code generation defaults to the “fast” instruction selector. This
attribute cannot be used together with the This attribute requires the optsize This attribute suggests that optimization passes and code
generator passes make choices that keep the code size of this function low, and otherwise do optimizations specifically to reduce code size as long as they do not significantly impact runtime performance."patchable-function" This attribute tells the code generator that the code generated for this function needs to follow certain conventions that make it possible for a runtime function to patch over it later. The exact effect of this attribute depends on its string value, for which there currently is one legal possibility:
This attribute by itself does not imply restrictions on inter-procedural optimizations. All of the semantic effects the patching may have to be separately conveyed via the linkage type. "probe-stack"
This attribute indicates that the function will trigger a guard region in the end of the stack. It ensures that accesses to the stack must be no further apart than the size of the guard region to a previous access of the stack. It takes one required string value, the name of the stack probing function that will be called. If a function that has a "stack-probe-size" This attribute controls the behavior of stack probes: either the If a function that has a "no-stack-arg-probe" This attribute disables
ABI-required stack probes, if any.returns_twice This attribute indicates that this function can return twice. The C setjmp is an example of such a function. The compiler disables some optimizations (like tail calls) in the caller of these functions.safestack This attribute indicates that SafeStack protection is enabled for this function. If a function that has a sanitize_address This attribute indicates that AddressSanitizer checks (dynamic address safety analysis) are enabled for this function.sanitize_memory This attribute indicates that MemorySanitizer checks (dynamic detection of accesses to uninitialized memory) are enabled for this function.
sanitize_thread This attribute indicates that ThreadSanitizer checks (dynamic thread safety analysis) are enabled for this function.sanitize_hwaddress This attribute indicates that HWAddressSanitizer checks (dynamic address safety analysis based on tagged pointers) are enabled for this function.sanitize_memtag This attribute indicates that MemTagSanitizer checks (dynamic address safety analysis based on Armv8 MTE) are enabled for this function.speculative_load_hardening This attribute indicates that Speculative Load Hardening should be enabled for the function body. Speculative Load Hardening is a best-effort mitigation against information leak attacks that make use of control flow miss-speculation - specifically miss-speculation of whether a branch is taken or not. Typically vulnerabilities enabling such attacks are classified as “Spectre variant #1”. Notably, this does not attempt to mitigate against miss-speculation of branch target, classified as “Spectre variant #2” vulnerabilities. When inlining, the attribute is sticky. Inlining a function that carries this attribute will cause the caller to gain the attribute. This is intended to provide a maximally conservative model where the code in a function annotated with this attribute will always (even after inlining) end up hardened. speculatable This function attribute indicates that the
function does not have any effects besides calculating its result and does not have undefined behavior. Note that speculatable is not enough to conclude that along any particular execution path the number of calls to this function will not be externally observable. This attribute is only valid on functions and declarations, not on individual call sites. If a function is incorrectly marked as speculatable and really does exhibit undefined behavior, the undefined behavior may be observed even if the
call site is dead code.ssp This attribute indicates that the function should emit a stack smashing protector. It is in the form of a “canary” — a random value placed on the stack before the local variables that’s checked upon return from the function to see if it has been overwritten. A heuristic is used to determine if a function needs stack protectors or not. The heuristic used will enable protectors for functions with:
Variables that are identified as requiring a protector will be arranged on the stack such that they are adjacent to the stack protector guard. If a function with an sspstrong This attribute indicates that the function should emit a stack smashing protector. This attribute causes a strong heuristic to be used when determining if a function needs stack protectors. The strong heuristic will enable protectors for functions with:
Variables that are identified as requiring a protector will be arranged on the stack such that they are adjacent to the stack protector guard. The specific layout rules are:
This overrides the If a
function with an sspreq This attribute indicates that the function should always emit a stack smashing protector. This overrides the Variables that are identified as requiring a protector will be arranged on the stack such that they are adjacent to the stack protector guard. The specific layout rules are:
If a function with an strictfp This attribute indicates that the function was called from a scope that requires strict floating-point semantics. LLVM will not attempt any optimizations that require assumptions about the floating-point rounding mode or that might alter the state of floating-point status flags that might otherwise be set or cleared by calling this function. LLVM will not introduce any new floating-point instructions that may trap.
"denormal-fp-math"
If the input mode is "denormal-fp-math-f32" Same as
"denormal-fp-math" , but only controls the behavior of the 32-bit float type (or vectors of 32-bit floats). If both are are present, this overrides "denormal-fp-math" . Not all targets support separately setting the denormal mode per type, and no attempt is made to diagnose unsupported uses. Currently this attribute is respected by the AMDGPU and NVPTX backends."thunk" This attribute indicates that the function will delegate to some other function with a tail
call. The prototype of a thunk should not be used for optimization purposes. The caller is expected to cast the thunk prototype to match the thunk target prototype."tls-load-hoist" This attribute indicates that the function will try to reduce redundant tls address calculation by hoisting tls variable.uwtable[(sync|async)] This attribute indicates that the ABI being targeted requires that an unwind table entry be produced for this function even if we can show that no exceptions
passes by it. This is normally the case for the ELF x86-64 abi, but it can be disabled for some compilation units. The optional parameter describes what kind of unwind tables to generate: sync for normal unwind tables, async for asynchronous (instruction precise) unwind tables. Without the parameter, the attribute uwtable is equivalent to uwtable(async) .nocf_check This attribute indicates that no control-flow check will be performed on the attributed entity. It disables
-fcf-protection=<> for a specific entity to fine grain the HW control flow protection mechanism. The flag is target independent and currently appertains to a function or function pointer.shadowcallstack This attribute indicates that the ShadowCallStack checks are enabled for the function. The instrumentation checks that the return address for the function has not changed between the function prolog and epilog. It is currently x86_64-specific.mustprogress This attribute indicates that the function is required to return, unwind, or interact with the environment in an observable way e.g. via a volatile memory access, I/O, or other synchronization. The mustprogress attribute is intended to model the requirements of the first section of [intro.progress] of the C++ Standard. As a consequence, a loop in a function with the mustprogress attribute can be assumed to terminate if it does not interact
with the environment in an observable way, and terminating loops without side-effects can be removed. If a mustprogress function does not satisfy this contract, the behavior is undefined. This attribute does not apply transitively to callees, but does apply to call sites within the function. Note that willreturn implies mustprogress."warn-stack-size"="<threshold>" This attribute sets a threshold to emit diagnostics once the frame size is known should the frame
size exceed the specified value. It takes one required integer value, which should be a non-negative integer, and less than UINT_MAX. It’s unspecified which threshold will be used when duplicate definitions are linked together with differing values.vscale_range(<min>[, <max>]) This attribute indicates the minimum and maximum vscale value for the given function. The min must be greater than 0. A maximum value of 0 means unbounded. If the optional max value is omitted then max is set to
the value of min. If the attribute is not present, no assumptions are made about the range of vscale."min-legal-vector-width"="<size>" This attribute indicates the minimum legal vector width required by the calling convension. It is the maximum width of vector arguments and returnings in the function and functions called by this function. Because all the vectors are supposed to be legal type for compatibility. Backends are free to ignore the attribute if they don’t need to support different maximum
legal vector types or such information can be inferred by other attributes.Call Site Attributes¶In addition to function attributes the following call site only attributes are supported: vector-function-abi-variant This attribute can be attached to a call to list the vector functions associated to the function. Notice that the attribute cannot be attached to a invoke or a callbr instruction. The attribute consists of a comma separated list of mangled names. The order of the list does not imply preference (it is logically a set). The compiler is free to pick any listed vector function of its choosing. The syntax for the mangled names is as follows:: _ZGV<isa><mask><vlen><parameters>_<scalar_name>[(<vector_redirection>)] When present, the attribute informs the compiler that the function For X86 and Arm targets, the values of the tokens in the standard name are those that are defined in the VFABI. LLVM has an internal <isa>:= b | c | d | e -> X86 SSE, AVX, AVX2, AVX512 | n | s -> Armv8 Advanced SIMD, SVE | __LLVM__ -> Internal LLVM Vector ISA For all targets currently supported (x86, Arm and Internal LLVM), the remaining tokens can have the following values:: <mask>:= M | N -> mask | no mask <vlen>:= number -> number of lanes | x -> VLA (Vector Length Agnostic) <parameters>:= v -> vector | l | l <number> -> linear | R | R <number> -> linear with ref modifier | L | L <number> -> linear with val modifier | U | U <number> -> linear with uval modifier | ls <pos> -> runtime linear | Rs <pos> -> runtime linear with ref modifier | Ls <pos> -> runtime linear with val modifier | Us <pos> -> runtime linear with uval modifier | u -> uniform <scalar_name>:= name of the scalar function <vector_redirection>:= optional, custom name of the vector function preallocated(<ty>) This attribute is required on calls to llvm.call.preallocated.arg and cannot be used
on any other call. See llvm.call.preallocated.arg for more details.Global Attributes¶Attributes may be set to communicate additional information about a global variable. Unlike function attributes, attributes on a global variable are grouped into a single attribute group. no_sanitize_address This attribute indicates that the global variable should not have AddressSanitizer instrumentation applied to it, because it was annotated with
__attribute__((no_sanitize(“address”))), __attribute__((disable_sanitizer_instrumentation)), or included in the -fsanitize-ignorelist file.no_sanitize_hwaddress This attribute indicates that the global variable should not have HWAddressSanitizer instrumentation applied to it, because it was annotated with __attribute__((no_sanitize(“hwaddress”))), __attribute__((disable_sanitizer_instrumentation)), or included in the
-fsanitize-ignorelist file.sanitize_memtag This attribute indicates that the global variable should have AArch64 memory tags (MTE) instrumentation applied to it. This attribute causes the suppression of certain optimisations, like GlobalMerge, as well as ensuring extra directives are emitted in the assembly and extra bits of metadata are placed in the object file so that the linker can ensure the accesses are protected by MTE. This attribute is added by clang when
-fsanitize=memtag-globals is provided, as long as the global is not marked with __attribute__((no_sanitize(“memtag”))), __attribute__((disable_sanitizer_instrumentation)), or included in the -fsanitize-ignorelist file. The AArch64 Globals Tagging pass may remove this attribute when it’s not possible to tag the global (e.g. it’s a TLS variable).sanitize_address_dyninit This attribute indicates that the global variable, when instrumented with
AddressSanitizer, should be checked for ODR violations. This attribute is applied to global variables that are dynamically initialized according to C++ rules.Operand Bundles¶Operand bundles are tagged sets of SSA values that can be associated with certain
LLVM instructions (currently only Syntax: operand bundle set ::= '[' operand bundle (, operand bundle )* ']' operand bundle ::= tag '(' [ bundle operand ] (, bundle operand )* ')' bundle operand ::= SSA value tag ::= string constant Operand bundles are not part of a function’s signature, and a given function may be called from multiple places with different kinds of operand bundles. This reflects the fact that the operand bundles are conceptually a part of the Operand bundles are a generic mechanism intended to support runtime-introspection-like functionality for managed languages. While the exact semantics of an operand bundle depend on the bundle tag, there are certain limitations to how much the presence of an operand bundle can influence the semantics of a program. These restrictions are described as the semantics of an “unknown” operand bundle. As long as the behavior of an operand bundle is describable within these restrictions, LLVM does not need to have special knowledge of the operand bundle to not miscompile programs containing it.
More specific types of operand bundles are described below. Deoptimization Operand Bundles¶Deoptimization operand bundles are characterized by the From the compiler’s perspective, deoptimization operand bundles make the call sites they’re attached to at least The inliner knows how to inline through calls that have deoptimization operand bundles. Just like inlining through a normal call site involves composing the normal and exceptional continuations, inlining through a call site with a deoptimization operand bundle needs to appropriately compose the “safe” deoptimization continuation. The inliner does this by prepending the parent’s deoptimization continuation to
every deoptimization continuation in the inlined body. E.g. inlining define void @f() { call void @x() ;; no deopt state call void @y() [ "deopt"(i32 10) ] call void @y() [ "deopt"(i32 10), "unknown"(ptr null) ] ret void } define void @g() { call void @f() [ "deopt"(i32 20) ] ret void } will result in define void @g() { call void @x() ;; still no deopt state call void @y() [ "deopt"(i32 20, i32 10) ] call void @y() [ "deopt"(i32 20, i32 10), "unknown"(ptr null) ] ret void } It is the frontend’s responsibility to structure or encode the deoptimization state in a way that syntactically prepending the caller’s deoptimization state to the callee’s deoptimization state is semantically equivalent to composing the caller’s deoptimization continuation after the callee’s deoptimization continuation. Funclet Operand Bundles¶Funclet operand bundles are characterized by the If any funclet EH pads have been “entered” but not “exited” (per the description in the EH doc), it is undefined behavior to execute a
Similarly, if no funclet EH pads have been entered-but-not-yet-exited, executing a GC Transition Operand Bundles¶GC transition
operand bundles are characterized by the The bundle contain an arbitrary list of Values which need to be passed to GC transition code. They will be lowered and passed as operands to the appropriate GC_TRANSITION nodes in the selection DAG. It is assumed that these arguments must be available before and after (but not necessarily during) the execution of the callee. Assume Operand Bundles¶Operand bundles on an llvm.assume allows representing assumptions that a parameter attribute or a function attribute holds for a certain value at a certain location. Operand bundles enable assumptions that are either hard or impossible to represent as a boolean argument of an llvm.assume. An assume operand bundle has the form: "<tag>"([ <holds for value> [, <attribute argument>] ])
If there are no arguments the attribute is a property of the call location. For example: call void @llvm.assume(i1 true) ["align"(ptr %val, i32 8)] allows the optimizer to assume that at location of call to
llvm.assume call void @llvm.assume(i1 %cond) ["cold"(), "nonnull"(ptr %val)] allows the optimizer to assume that the llvm.assume call location is cold and that Just like for the argument of llvm.assume, if any of the provided guarantees are violated at runtime the behavior is undefined. While attributes expect constant arguments, assume operand bundles may be provided a dynamic value, for example: call void @llvm.assume(i1 true) ["align"(ptr %val, i32 %align)] If the operand bundle value violates any requirements on the attribute value, the behavior is undefined, unless one of the following exceptions applies:
Even if the assumed property can be encoded as a boolean value, like
Preallocated Operand Bundles¶Preallocated operand bundles are characterized by the %foo = type { i64, i32 } ... %t = call token @llvm.call.preallocated.setup(i32 1) %a = call ptr @llvm.call.preallocated.arg(token %t, i32 0) preallocated(%foo) ; initialize %b call void @bar(i32 42, ptr preallocated(%foo) %a) ["preallocated"(token %t)] GC Live Operand Bundles¶A “gc-live” operand bundle is only valid on a gc.statepoint intrinsic. The operand bundle must contain every pointer to a garbage collected object which potentially needs to be updated by the garbage collector. When lowered, any relocated value will be recorded in the corresponding stackmap entry. See the intrinsic description for further details. ObjC ARC Attached Call Operand Bundles¶A ; The marker instruction and a runtime function call are inserted after the call ; to @foo. call ptr @foo() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ] call ptr @foo() [ "clang.arc.attachedcall"(ptr @objc_unsafeClaimAutoreleasedReturnValue) ] The operand bundle is needed to ensure the call is immediately followed by the marker instruction and the ObjC runtime call in the final output. KCFI Operand Bundles¶A call void %0() ["kcfi"(i32 1234)] Clang
emits KCFI operand bundles and the necessary metadata with Module-Level Inline Assembly¶Modules may contain “module-level inline asm” blocks, which corresponds to the GCC “file scope inline asm” blocks. These blocks are
internally concatenated by LLVM and treated as a single unit, but may be separated in the module asm "inline asm code goes here" module asm "more can go here" The strings can contain any character by escaping non-printable characters. The escape sequence used is simply “\xx” where “xx” is the two digit hex code for the number. Note that the assembly string must be parseable by LLVM’s integrated assembler (unless it is disabled), even when emitting a Data Layout¶A module may specify a target specific data layout string that specifies how data is to be laid out in memory. The syntax for the data layout is simply: target datalayout = "layout specification" The layout specification consists of a list of specifications separated by the minus sign character (‘-‘). Each specification starts with a letter and may include other information after the letter to define some aspect of the data layout. The specifications accepted are as follows: E Specifies that the target lays out data in big-endian form. That is, the bits with the most significance have the lowest address location.e Specifies that the target lays out data in little-endian form. That is, the bits with the least
significance have the lowest address location.S<size> Specifies the natural alignment of the stack in bits. Alignment promotion of stack variables is limited to the natural stack alignment to avoid dynamic stack realignment. The stack alignment must be a multiple of 8-bits. If omitted, the natural stack alignment defaults to “unspecified”, which does not prevent any alignment promotions.P<address space> Specifies the address space that corresponds to program memory.
Harvard architectures can use this to specify what space LLVM should place things such as functions into. If omitted, the program memory space defaults to the default address space of 0, which corresponds to a Von Neumann architecture that has code and data in the same space.G<address space> Specifies the address space to be used by default when creating global variables. If omitted, the globals address space defaults to the default address space 0. Note: variable declarations without
an address space are always created in address space 0, this property only affects the default value to be used when creating globals without additional contextual information (e.g. in LLVM passes).A<address space> Specifies the address space of objects created by ‘alloca ’. Defaults to the default address space of 0.p[n]:<size>:<abi>[:<pref>][:<idx>] This specifies the size of a pointer and its <abi> and <pref> erred alignments for address space n . <pref> is optional and
defaults to <abi> . The fourth parameter <idx> is the size of the index that used for address calculation. If not specified, the default index size is equal to the pointer size. All sizes are in bits. The address space, n , is optional, and if not specified, denotes the default address space 0. The value of n must be in the range [1,2^23).i<size>:<abi>[:<pref>] This specifies the alignment for an integer type of a given bit <size> . The value of <size> must be in the
range [1,2^23). <pref> is optional and defaults to <abi> .v<size>:<abi>[:<pref>] This specifies the alignment for a vector type of a given bit <size> . The value of <size> must be in the range [1,2^23). <pref> is optional and defaults to <abi> .f<size>:<abi>[:<pref>] This specifies the alignment for a floating-point type of a given bit <size> . Only values of <size> that are supported by the target will work. 32 (float) and 64 (double) are supported on all targets; 80 or 128
(different flavors of long double) are also supported on some targets. The value of <size> must be in the range [1,2^23). <pref> is optional and defaults to <abi> .a:<abi>[:<pref>] This specifies the alignment for an object of aggregate type. <pref> is optional and defaults to <abi> .F<type><abi> This specifies the alignment for function pointers. The options for
m:<mangling> If present, specifies that llvm names are mangled in the output. Symbols prefixed with the mangling escape character
n<size1>:<size2>:<size3>... This specifies a set of native integer widths for the target CPU in bits. For example, it might contain n32 for 32-bit
PowerPC, n32:64 for PowerPC 64, or n8:16:32:64 for X86-64. Elements of this set are considered to support most general arithmetic operations efficiently.ni:<address space0>:<address space1>:<address space2>... This specifies pointer types with the specified address spaces as Non-Integral Pointer Type s. The 0 address space cannot be specified as non-integral.On every specification that takes a When constructing the data layout for a given target, LLVM starts with a default set of specifications which are then (possibly) overridden by the specifications in the
When LLVM is determining the alignment for a given type, it uses the following rules:
The function of the data layout string may not be what you expect. Notably, this is not a specification from the frontend of what alignment the code generator should use. Instead, if specified, the target data layout is required to match what the ultimate code generator expects. This string is used by the mid-level optimizers to improve code, and this only works if it matches what the ultimate code generator uses. There is no way to generate IR that does not embed this target-specific detail into the IR. If you don’t specify the string, the default specifications will be used to generate a Data Layout and the optimization phases will operate accordingly and introduce target specificity into the IR with respect to these default specifications. Target Triple¶A module may specify a target triple string that describes the target host. The syntax for the target triple is simply: target triple = "x86_64-apple-macosx10.7.0" The target triple string consists of a series of identifiers delimited by the minus sign character (‘-‘). The canonical forms are: ARCHITECTURE-VENDOR-OPERATING_SYSTEM ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT This information is passed along to the backend so that it generates code for the proper architecture. It’s possible to override this on the command line with the Object Lifetime¶A memory object, or simply object, is a region of a memory space that is reserved by a memory allocation such as alloca, heap allocation calls, and global variable definitions. Once it is allocated, the bytes stored in the region can only be read or written through a pointer that is based on the allocation value. If a pointer that is not based on the object tries to read or write to the object, it is undefined behavior. A lifetime of a memory object is a property that decides its accessibility. Unless stated otherwise, a memory object is alive since its allocation, and dead after its deallocation. It is undefined behavior to access a memory object that isn’t alive, but operations that don’t dereference it such as getelementptr, ptrtoint and icmp return a valid result. This explains code motion of these instructions across operations that impact the object’s lifetime. A stack object’s lifetime can be explicitly specified using llvm.lifetime.start and llvm.lifetime.end intrinsic function calls. Pointer Aliasing Rules¶Any memory access must be done through a pointer value associated with an address range of the memory access, otherwise the behavior is undefined. Pointer values are associated with address ranges according to the following rules:
A pointer value is based on another pointer value according to the following rules:
Note that this definition of “based” is intentionally similar to the definition of “based” in C99, though it is slightly weaker. LLVM IR does not associate types with memory. The result type of a Consequently,
type-based alias analysis, aka TBAA, aka Pointer Capture¶Given a function call and a pointer that is passed as an argument or stored in the memory before the call, a pointer is captured by the call if it makes a copy of any part of the pointer that outlives the call. To be precise, a pointer is captured if one or more of the following conditions hold:
@glb = global ptr null @glb2 = global ptr null @glb3 = global ptr null @glbi = global i32 0 define ptr @f(ptr %a, ptr %b, ptr %c, ptr %d, ptr %e) { store ptr %a, ptr @glb ; %a is captured by this call store ptr %b, ptr @glb2 ; %b isn't captured because the stored value is overwritten by the store below store ptr null, ptr @glb2 store ptr %c, ptr @glb3 call void @g() ; If @g makes a copy of %c that outlives this call (@f), %c is captured store ptr null, ptr @glb3 %i = ptrtoint ptr %d to i64 %j = trunc i64 %i to i32 store i32 %j, ptr @glbi ; %d is captured ret ptr %e ; %e is captured }
@lock = global i1 true define void @f(ptr %a) { store ptr %a, ptr* @glb store atomic i1 false, ptr @lock release ; %a is captured because another thread can safely read @glb store ptr null, ptr @glb ret void }
@glb = global i8 0 define void @f(ptr %a) { %c = icmp eq ptr %a, @glb br i1 %c, label %BB_EXIT, label %BB_CONTINUE ; escapes %a BB_EXIT: call void @exit() unreachable BB_CONTINUE: ret void }
Volatile Memory Accesses¶Certain memory accesses, such as load’s,
store’s, and llvm.memcpy’s may be marked A volatile load or store may have additional target-specific semantics. Any volatile operation can have side effects, and any volatile operation can read and/or modify state which is not accessible via a regular load or store in this module. Volatile operations may use addresses which do not point to memory (like MMIO registers). This means the compiler may not use a volatile operation to prove a non-volatile access to that address has defined behavior. The allowed side-effects for volatile accesses are limited. If a non-volatile store to a given address would be legal, a volatile operation may modify the memory at that address. A volatile operation may not modify any other memory accessible by the module being compiled. A volatile operation may not call any code in the current module. In general (without target specific context), the address space of a volatile operation may not be changed. Different address spaces may have different trapping behavior when dereferencing an invalid pointer. The compiler may assume execution will continue after a volatile operation, so operations which modify memory or may have undefined behavior can be hoisted past a volatile operation. As an exception to the preceding rule, the compiler may not assume execution will continue after a volatile store operation. This restriction is necessary to support the somewhat common pattern in C of intentionally storing to an invalid pointer to crash the program. In the future, it might make sense to allow frontends to control this behavior. IR-level volatile loads and stores cannot safely be optimized into llvm.memcpy or llvm.memmove intrinsics even when those intrinsics are flagged volatile. Likewise, the backend should never split or merge target-legal volatile load/store instructions. Similarly, IR-level volatile loads and stores cannot change from integer to floating-point or vice versa. Rationale Platforms may rely on volatile loads and stores of natively supported data width to be executed as single instruction. For example, in C this holds for an l-value of volatile primitive type with native hardware support, but not necessarily for aggregate types. The frontend upholds these expectations, which are intentionally unspecified in the IR. The rules above ensure that IR transformations do not violate the frontend’s contract with the language. Memory Model for Concurrent Operations¶The LLVM IR does not define any way to start parallel threads of execution or to register signal handlers. Nonetheless, there are platform-specific ways to create them, and we define LLVM IR’s behavior in their presence. This model is inspired by the C++0x memory model. For a more informal introduction to this model, see the LLVM Atomic Instructions and Concurrency Guide. We define a happens-before partial order as the least partial order that
Note that program order does not introduce happens-before edges between a thread and signals executing inside that thread. Every (defined) read operation (load instructions, memcpy, atomic loads/read-modify-writes, etc.) R reads a series of bytes written by (defined) write operations (store instructions, atomic stores/read-modify-writes, memcpy, etc.). For the purposes of this section, initialized globals are considered to have a write of the initializer which is atomic and happens before any other read or write of the memory in question. For each byte of a read R, Rbyte may see any write to the same byte, except:
Given that definition, Rbyte is defined as follows:
R returns the value composed of the series of bytes it read. This implies that some bytes within the value may be Note that in cases where none of the atomic intrinsics are used, this model places only one restriction on IR transformations on top of what is required for single-threaded execution: introducing a store to a byte which might not otherwise be stored is not allowed in general. (Specifically, in the case where another thread might write to and read from an address, introducing a store can change a load that may see exactly one write into a load that may see multiple writes.) Atomic Memory Ordering Constraints¶Atomic instructions (cmpxchg, atomicrmw, fence, atomic load, and atomic store) take ordering parameters that determine which other atomic instructions on the same address they synchronize with. These semantics are borrowed from Java and C++0x, but are somewhat more colloquial. If these descriptions aren’t precise enough, check those specs (see spec references in the atomics guide). fence instructions treat these orderings somewhat differently since they don’t take an address. See that instruction’s documentation for details. For a simpler introduction to the ordering constraints, see the LLVM Atomic Instructions and Concurrency Guide. unordered The set of values that can be read is governed by the happens-before partial order. A value cannot be read unless some operation wrote it. This is intended
to provide a guarantee strong enough to model Java’s non-volatile shared variables. This ordering cannot be specified for read-modify-write operations; it is not strong enough to make them atomic in any interesting way.monotonic In addition to the guarantees of unordered , there is a single total order for modifications by monotonic operations on each address. All modification orders must be compatible with the happens-before order. There is no guarantee that the modification orders
can be combined to a global total order for the whole program (and this often will not be possible). The read in an atomic read-modify-write operation (cmpxchg and atomicrmw) reads the value in the modification order immediately before the value it writes. If one atomic read happens before another atomic read of the same
address, the later read must see the same value or a later value in the address’s modification order. This disallows reordering of monotonic (or stronger) operations on the same address. If an address is written monotonic -ally by one thread, and other threads monotonic -ally read that address repeatedly, the other threads must eventually see the write. This corresponds to the C++0x/C1x memory_order_relaxed .acquire In addition to the guarantees of monotonic , a synchronizes-with edge may
be formed with a release operation. This is intended to model C++’s memory_order_acquire .release In addition to the guarantees of monotonic , if this operation writes a value which is subsequently read by an acquire operation, it synchronizes-with that operation. (This isn’t a complete description; see the C++0x definition of a release sequence.) This corresponds to the C++0x/C1x memory_order_release .acq_rel (acquire+release)Acts as both an acquire and release operation
on its address. This corresponds to the C++0x/C1x memory_order_acq_rel .seq_cst (sequentially consistent)In addition to the guarantees of acq_rel (acquire for an operation that only reads, release for an operation that only writes), there is a global total order on all sequentially-consistent operations on all addresses, which is consistent with the happens-before partial order and with the modification orders of all the affected addresses. Each sequentially-consistent read
sees the last preceding write to the same address in this global order. This corresponds to the C++0x/C1x memory_order_seq_cst and Java volatile.If an atomic operation is marked If an atomic operation is marked Otherwise, an atomic operation that is not marked Floating-Point Environment¶The default LLVM floating-point environment assumes that floating-point instructions do not have side effects. Results assume the round-to-nearest rounding mode. No floating-point exception state is maintained in this environment. Therefore, there is no attempt to create or preserve invalid operation (SNaN) or division-by-zero exceptions. The benefit of this exception-free assumption is that floating-point operations may be speculated freely without any other fast-math relaxations to the floating-point model. Code that requires different behavior than this should use the Constrained Floating-Point Intrinsics. Fast-Math Flags¶LLVM IR floating-point operations (fneg, fadd, fsub, fmul, fdiv, frem, fcmp), phi, select and call may use the following flags to enable otherwise unsafe floating-point transformations. nnan No NaNs - Allow optimizations to assume the arguments and result are not NaN. If an argument is a nan, or the result would be a nan, it produces a
poison value instead.ninf No Infs - Allow optimizations to assume the arguments and result are not +/-Inf. If an argument is +/-Inf, or the result would be +/-Inf, it produces a poison value instead.nsz No Signed Zeros - Allow optimizations to treat the sign of a zero
argument or zero result as insignificant. This does not imply that -0.0 is poison and/or guaranteed to not exist in the operation.arcp Allow Reciprocal - Allow optimizations to use the reciprocal of an argument rather than perform division.contract Allow floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). This does not enable reassociating to form arbitrary contractions. For example, (a*b) + (c*d) + e can not be
transformed into (a*b) + ((c*d) + e) to create two fma operations.afn Approximate functions - Allow substitution of approximate calculations for functions (sin, log, sqrt, etc). See floating-point intrinsic definitions for places where this can apply to LLVM’s intrinsic math functions.reassoc Allow reassociation transformations for floating-point instructions. This may dramatically change results in floating-point.fast This flag implies all of
the others.Use-list Order Directives¶Use-list directives encode the in-memory order of each use-list, allowing the order to be recreated. Use-list directives may appear at function scope or global scope. They are not instructions, and have no effect on the semantics of the IR. When they’re at function scope, they must appear after the terminator of the final basic block. If basic blocks have their address taken via
uselistorder <ty> <value>, { <order-indexes> } uselistorder_bb @function, %block { <order-indexes> }
define void @foo(i32 %arg1, i32 %arg2) { entry: ; ... instructions ... bb: ; ... instructions ... ; At function scope. uselistorder i32 %arg1, { 1, 0, 2 } uselistorder label %bb, { 1, 0 } } ; At global scope. uselistorder ptr @global, { 1, 2, 0 } uselistorder i32 7, { 1, 0 } uselistorder i32 (i32) @bar, { 1, 0 } uselistorder_bb @foo, %bb, { 5, 1, 3, 2, 0, 4 } Source Filename¶The source filename string is set to the original module identifier, which will be the name of the compiled source file when compiling from source through the clang front end, for example. It is then preserved through the IR and bitcode. This is currently necessary to generate a consistent unique global identifier for local functions used in profile data, which prepends the source file name to the local function name. The syntax for the source file name is simply: source_filename = "/path/to/source.c" Type System¶The LLVM type system is one of the most important features of the intermediate representation. Being typed enables a number of optimizations to be performed on the intermediate representation directly, without having to do extra analyses on the side before the transformation. A strong type system makes it easier to read the generated code and enables novel analyses and transformations that are not feasible to perform on normal three address code representations. Void Type¶
The void type does not represent any value and has no size.
Function Type¶
The function type can be thought of as a function signature. It consists of a return type and a list of formal parameter types. The return type of a function type is a void type or first class type — except for label and metadata types.
<returntype> (<parameter list>) …where ‘
First Class Types¶The first class types are perhaps the most important. Values of these types are the only ones which can be produced by instructions. Single Value Types¶These are the types that are valid in registers from CodeGen’s perspective. Integer Type¶
The integer type is a very simple type that simply specifies an arbitrary bit width for the integer type desired. Any bit width from 1 bit to 223(about 8 million) can be specified.
The number of bits the integer will occupy is specified by the Examples:¶
Floating-Point Types¶
The binary format of half, float, double, and fp128 correspond to the IEEE-754-2008 specifications for binary16, binary32, binary64, and binary128 respectively. X86_amx Type¶
The x86_amx type represents a value held in an AMX tile register on an x86 machine. The operations allowed on it are quite limited. Only few intrinsics are allowed: stride load and store, zero and dot product. No instruction is allowed for this type. There are no arguments, arrays, pointers, vectors or constants of this type.
X86_mmx Type¶
The x86_mmx type represents a value held in an MMX register on an x86 machine. The operations allowed on it are quite limited: parameters and return values, load and store, and bitcast. User-specified MMX instructions are represented as intrinsic or asm calls with arguments and/or results of this type. There are no arrays, vectors or constants of this type.
Pointer Type¶
The pointer type Pointer types may have an optional address space attribute defining the numbered address space where the pointed-to object resides. For example, The default address space is number zero. The semantics of non-zero address spaces are target-specific. Memory access through a
non-dereferenceable pointer is undefined behavior in any address space. Pointers with the bit-value 0 are only assumed to be non-dereferenceable in address space 0, unless the function is marked with the If an object can be proven accessible through a pointer with a different address space, the access may be modified to use that address space. Exceptions apply if the operation is Prior to LLVM 15, pointer types also specified a pointee type, such as
Vector Type¶
A vector type is a simple derived type that represents a vector of elements. Vector types are used when multiple primitive data are operated in parallel using a single instruction (SIMD). A vector type requires a size (number of elements), an underlying primitive data type, and a scalable property to represent vectors where the exact hardware vector length is unknown at compile time. Vector types are considered first class.
In general vector elements are laid out in memory in the same way as array types. Such an analogy works fine as long as the vector elements are byte sized. However, when the elements of the vector aren’t byte sized it gets a bit more complicated. One way to describe the layout is by describing what happens when a vector such as <N x iM> is bitcasted to an integer type with N*M bits, and then following the rules for storing such an integer to memory. A bitcast from a vector type to a scalar integer type will see the elements being packed together (without padding). The order in which elements are inserted in the integer depends on endianess. For little endian element zero is put in the least significant bits of the integer, and for big endian element zero is put in the most significant bits. Using a vector such as %val = bitcast <4 x i4> <i4 1, i4 2, i4 3, i4 5> to i16 ; Bitcasting from a vector to an integral type can be seen as ; concatenating the values: ; %val now has the hexadecimal value 0x1235. store i16 %val, ptr %ptr ; In memory the content will be (8-bit addressing): ; ; [%ptr + 0]: 00010010 (0x12) ; [%ptr + 1]: 00110101 (0x35) The same example for little endian: %val = bitcast <4 x i4> <i4 1, i4 2, i4 3, i4 5> to i16 ; Bitcasting from a vector to an integral type can be seen as ; concatenating the values: ; %val now has the hexadecimal value 0x5321. store i16 %val, ptr %ptr ; In memory the content will be (8-bit addressing): ; ; [%ptr + 0]: 01010011 (0x53) ; [%ptr + 1]: 00100001 (0x21) When
< <# elements> x <elementtype> > ; Fixed-length vector < vscale x <# elements> x <elementtype> > ; Scalable vector The number of elements is a constant integer value larger than 0; elementtype may be any integer, floating-point or pointer type. Vectors of size zero are not allowed. For scalable vectors, the total number of elements is a constant multiple (called vscale) of the specified number of elements; vscale is a positive integer that is unknown at compile time and the same hardware-dependent constant for all scalable vectors at run time. The size of a specific scalable vector type is thus constant within IR, even if the exact size in bytes cannot be determined until run time.
Label Type¶
The label type represents code labels.
Token Type¶
The token type is used when a value is associated with an instruction but all uses of the value must not attempt to introspect or obscure it. As such, it is not appropriate to have a phi or select of type token.
Aggregate Types¶Aggregate Types are a subset of derived types that can contain multiple member types. Arrays and structs are aggregate types. Vectors are not considered to be aggregate types. Array Type¶
The array type is a very simple derived type that arranges elements sequentially in memory. The array type requires a size (number of elements) and an underlying data type.
[<# elements> x <elementtype>] The number of elements is a constant integer value;
Here are some examples of multidimensional arrays:
There is no restriction on indexing beyond the end of the array implied by a static type (though there are restrictions on indexing beyond the bounds of an allocated object in some cases). This means that single-dimension ‘variable sized array’ addressing can be implemented in LLVM with a zero length array type. An implementation of ‘pascal style arrays’ in LLVM could use the type “ Structure Type¶
The structure type is used to represent a collection of data members together in memory. The elements of a structure may be any type that has a size. Structures in memory are accessed using ‘ Structures may optionally be “packed” structures, which indicate that the alignment of the struct is one byte, and that there is no padding between the elements. In non-packed structs, padding between field types is inserted as defined by the DataLayout string in the module, which is required to match what the underlying code generator expects. Structures can either be “literal” or “identified”. A literal structure is defined inline with other types (e.g.
%T1 = type { <type list> } ; Identified normal struct type %T2 = type <{ <type list> }> ; Identified packed struct type
Opaque Structure Types¶
Opaque structure types are used to represent structure types that do not have a body specified. This corresponds (for example) to the C notion of a forward declared structure. They can be named (
%X = type opaque %52 = type opaque
Constants¶LLVM has several different basic types of constants. This section describes them all and their syntax. Simple Constants¶Boolean constantsThe two strings ‘true ’ and ‘false ’ are both valid constants of the i1 type.Integer constantsStandard integers (such as ‘4’) are constants of the integer type. Negative numbers
may be used with integer types.Floating-point constantsFloating-point constants use standard decimal notation (e.g. 123.421), exponential notation (e.g. 1.23421e+2), or a more precise hexadecimal notation (see below). The assembler requires the exact decimal value of a floating-point constant. For example, the assembler accepts 1.25 but rejects 1.3 because 1.3 is a repeating decimal in binary. Floating-point constants must have a
floating-point type.Null pointer constantsThe identifier ‘null ’ is recognized as a null pointer constant and must be of pointer type.Token constantsThe identifier ‘none ’ is recognized as an empty token constant and must be of token type.The one non-intuitive notation for constants is the hexadecimal form of floating-point constants. For example, the form ‘ When using the hexadecimal form, constants of types bfloat, half, float, and double are represented using the 16-digit form shown above (which matches the IEEE754 representation for double); bfloat, half and float values must, however, be exactly
representable as bfloat, IEEE 754 half, and IEEE 754 single precision respectively. Hexadecimal format is always used for long double, and there are three forms of long double. The 80-bit format used by x86 is represented as There are no constants of type x86_mmx and x86_amx. Complex Constants¶Complex constants are a (potentially recursive) combination of simple constants and smaller complex constants. Structure constantsStructure constants are represented with notation similar to structure type definitions (a comma separated list of elements, surrounded by braces ({} )). For example: “{ i32 4, float 17.0, ptr @G } ”, where “@G ” is
declared as “@G = external global i32 ”. Structure constants must have structure type, and the number and types of elements must match those specified by the type.Array constantsArray constants are represented with notation similar to array type definitions (a comma separated list of elements, surrounded by square brackets ([] )). For example: “[ i32 42, i32 11, i32 74 ] ”. Array constants must have
array type, and the number and types of elements must match those specified by the type. As a special case, character array constants may also be represented as a double-quoted string using the c prefix. For example: “c"Hello World\0A\00" ”.Vector constantsVector constants are represented with notation similar to vector type definitions (a comma separated list of elements,
surrounded by less-than/greater-than’s (<> )). For example: “< i32 42, i32 11, i32 74, i32 100 > ”. Vector constants must have vector type, and the number and types of elements must match those specified by the type.Zero initializationThe string ‘zeroinitializer ’ can be used to zero initialize a value to zero of any type, including scalar and
aggregate types. This is often used to avoid having to print large zero initializers (e.g. for large arrays) and is always exactly equivalent to using explicit zero initializers.Metadata nodeA metadata node is a constant tuple without types. For example: “!{!0, !{!2, !0}, !"test"} ”. Metadata can reference constant values, for example: “!{!0, i32 0, ptr @global, ptr @function, !"str"} ”. Unlike other typed constants that are meant
to be interpreted as part of the instruction stream, metadata is a place to attach additional information such as debug info.Undefined Values¶The string ‘ Note A ‘ Undefined values are useful because they indicate to the compiler that the program is well defined no matter what value is used. This gives the compiler more freedom to optimize. Here are some examples of (potentially surprising) transformations that are valid (in pseudo IR): %A = add %X, undef %B = sub %X, undef %C = xor %X, undef Safe: %A = undef %B = undef %C = undef This is safe because all of the output bits are affected by the undef bits. Any output bit can have a zero or one depending on the input bits. %A = or %X, undef %B = and %X, undef Safe: %A = -1 %B = 0 Safe: %A = %X ;; By choosing undef as 0 %B = %X ;; By choosing undef as -1 Unsafe: %A = undef %B = undef These logical operations have bits that are not always affected by the
input. For example, if %A = select undef, %X, %Y %B = select undef, 42, %Y %C = select %X, %Y, undef Safe: %A = %X (or %Y) %B = 42 (or %Y) %C = %Y (if %Y is provably not poison; unsafe otherwise) Unsafe: %A = undef %B = undef %C = undef This set of examples shows that undefined ‘ %A = xor undef, undef %B = undef %C = xor %B, %B %D = undef %E = icmp slt %D, 4 %F = icmp gte %D, 4 Safe: %A = undef %B = undef %C = undef %D = undef %E = undef %F = undef This example points out that two ‘ To ensure all uses of a given
register observe the same value (even if ‘ %A = sdiv undef, %X %B = sdiv %X, undef Safe: %A = 0 b: unreachable These examples show the crucial difference between an undefined value and undefined behavior. An undefined value (like ‘ a: store undef -> %X b: store %X -> undef Safe: a: <deleted> (if the stored value in %X is provably not poison) b: unreachable A store of an undefined value can be assumed to not have any effect; we can assume that the value is overwritten with bits that happen to match what was already there. This argument is only valid if the stored value is provably not Branching on an undefined value is undefined behavior. This explains optimizations that depend on branch conditions to construct predicates, such as Correlated Value Propagation and Global Value Numbering. In case of switch instruction, the branch condition should be frozen, otherwise it is undefined behavior. Unsafe: br undef, BB1, BB2 ; UB %X = and i32 undef, 255 switch %X, label %ret [ .. ] ; UB store undef, ptr %ptr %X = load ptr %ptr ; %X is undef switch i8 %X, label %ret [ .. ] ; UB Safe: %X = or i8 undef, 255 ; always 255 switch i8 %X, label %ret [ .. ] ; Well-defined %X = freeze i1 undef br %X, BB1, BB2 ; Well-defined (non-deterministic jump) Poison Values¶A poison
value is a result of an erroneous operation. In order to facilitate speculative execution, many instructions do not invoke immediate undefined behavior when provided with illegal operands, and return a poison value instead. The string ‘ Most instructions return ‘ It is correct to replace a poison value with an undef value or any value of the type. This means that immediate undefined behavior occurs if a poison value is used as an instruction operand that has any values that trigger undefined behavior. Notably this includes (but is not limited to):
Here are some examples: entry: %poison = sub nuw i32 0, 1 ; Results in a poison value. %poison2 = sub i32 poison, 1 ; Also results in a poison value. %still_poison = and i32 %poison, 0 ; 0, but also poison. %poison_yet_again = getelementptr i32, ptr @h, i32 %still_poison store i32 0, ptr %poison_yet_again ; Undefined behavior due to ; store to poison. store i32 %poison, ptr @g ; Poison value stored to memory. %poison3 = load i32, ptr @g ; Poison value loaded back from memory. %poison4 = load i16, ptr @g ; Returns a poison value. %poison5 = load i64, ptr @g ; Returns a poison value. %cmp = icmp slt i32 %poison, 0 ; Returns a poison value. br i1 %cmp, label %end, label %end ; undefined behavior end: Well-Defined Values¶Given a program execution, a value is well defined if the value does not have an undef bit and is not poison in the execution. An aggregate value or vector is well defined if its elements are well defined. The padding of an aggregate isn’t considered, since it isn’t visible without storing it into memory and loading it with a different type. A constant of a single value, non-vector type is well defined if it is neither ‘ Addresses of Basic Blocks¶
The ‘ It always has an Taking the address of the entry block is illegal. This value only has defined behavior when used as an operand to the ‘indirectbr’ or for comparisons against null. Pointer equality tests between labels addresses
results in undefined behavior — though, again, comparison against null is ok, and no label is equal to the null pointer. This may be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows Finally, some targets may provide defined semantics when using the value as the operand to an inline assembly, but that is target specific. DSO Local Equivalent¶
A ‘ The target function may not have
This can be used wherever a This is currently only supported for ELF binary formats. No CFI¶
With Control-Flow Integrity (CFI), a ‘ Constant Expressions¶Constant expressions are used to allow expressions involving other constants to be used as constants. Constant expressions may be of any first class type and may involve any LLVM operation that does not have side effects (e.g. load and call are not supported). The following is the syntax for constant expressions: trunc (CST to TYPE) Perform the trunc operation on constants.zext (CST to TYPE) Perform the
zext operation on constants.sext (CST to TYPE) Perform the sext operation on constants.fptrunc (CST to TYPE) Truncate a floating-point constant to another floating-point type. The size of CST must be larger than the size of TYPE. Both types must be floating-point.fpext (CST to TYPE) Floating-point extend a
constant to another type. The size of CST must be smaller or equal to the size of TYPE. Both types must be floating-point.fptoui (CST to TYPE) Convert a floating-point constant to the corresponding unsigned integer constant. TYPE must be a scalar or vector integer type. CST must be of scalar or vector floating-point type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won’t fit in the integer type, the result is a
poison value.fptosi (CST to TYPE) Convert a floating-point constant to the corresponding signed integer constant. TYPE must be a scalar or vector integer type. CST must be of scalar or vector floating-point type. Both CST and TYPE must be scalars, or vectors of the same number of elements. If the value won’t fit in the integer type, the result is a
poison value.uitofp (CST to TYPE) Convert an unsigned integer constant to the corresponding floating-point constant. TYPE must be a scalar or vector floating-point type. CST must be of scalar or vector integer type. Both CST and TYPE must be scalars, or vectors of the same number of elements.sitofp (CST to TYPE) Convert a signed integer constant to the corresponding floating-point constant. TYPE
must be a scalar or vector floating-point type. CST must be of scalar or vector integer type. Both CST and TYPE must be scalars, or vectors of the same number of elements.ptrtoint (CST to TYPE) Perform the ptrtoint operation on constants.inttoptr (CST to TYPE) Perform the inttoptr operation on constants. This one
is really dangerous!bitcast (CST to TYPE) Convert a constant, CST, to another TYPE. The constraints of the operands are the same as those for the bitcast instruction.addrspacecast (CST to TYPE) Convert a constant pointer or constant vector of pointer, CST, to another TYPE in a different address space. The constraints of the operands are the same as those for the
addrspacecast instruction.getelementptr (TY, CSTPTR, IDX0, IDX1, ...) , getelementptr inbounds (TY, CSTPTR, IDX0, IDX1, ...) Perform the getelementptr operation on constants. As with the getelementptr instruction, the index list may have one or more indexes, which are required to
make sense for the type of “pointer to TY”.select (COND, VAL1, VAL2) Perform the select operation on constants.icmp COND (VAL1, VAL2) Perform the icmp operation on constants.fcmp COND (VAL1, VAL2) Perform the fcmp operation on
constants.extractelement (VAL, IDX) Perform the extractelement operation on constants.insertelement (VAL, ELT, IDX) Perform the insertelement operation on constants.shufflevector (VEC1, VEC2, IDXMASK) Perform the shufflevector
operation on constants.extractvalue (VAL, IDX0, IDX1, ...) Perform the extractvalue operation on constants. The index list is interpreted in a similar manner as indices in a ‘getelementptr’ operation. At least one index value must be specified.insertvalue (VAL, ELT, IDX0, IDX1, ...) Perform the
insertvalue operation on constants. The index list is interpreted in a similar manner as indices in a ‘getelementptr’ operation. At least one index value must be specified.OPCODE (LHS, RHS) Perform the specified operation of the LHS and RHS constants. OPCODE may be any of the
binary or bitwise binary operations. The constraints on operands are the same as those for the corresponding instruction (e.g. no bitwise operations on floating-point values are allowed).Other Values¶Inline Assembler Expressions¶LLVM supports inline assembler expressions (as opposed to Module-Level Inline Assembly) through the use of a special value. This value represents the inline assembler as a template string (containing the instructions to emit), a list of operand constraints (stored as a string), a flag that indicates whether or not the inline asm expression has side effects, and a flag indicating whether the function containing the asm needs to align its stack conservatively. The
template string supports argument substitution of the operands using “ A literal “ LLVM also supports a few more substitutions useful for writing inline assembly:
LLVM’s support for inline asm is modeled closely on the requirements of Clang’s GCC-compatible inline-asm support. Thus, the feature-set and the constraint and modifier codes listed here are similar or identical to those in GCC’s inline asm support. However, to be clear, the syntax of the template and constraint strings described here is not the same as the syntax accepted by GCC and Clang, and, while most constraint letters are passed through as-is by Clang, some get translated to other codes when converting from the C source to the LLVM assembly. An example inline assembler expression is: i32 (i32) asm "bswap $0", "=r,r" Inline assembler expressions may only be used as the callee operand of a call or an invoke instruction. Thus, typically we have: %X = call i32 asm "bswap $0", "=r,r"(i32 %Y) Inline asms with side effects not visible in the constraint list must be marked as having side effects. This is done
through the use of the ‘ call void asm sideeffect "eieio", ""() In some cases inline asms will contain code that will not work unless the stack is aligned in some way, such as calls or SSE instructions on x86, yet will not contain code that does that alignment within the asm. The compiler should make conservative assumptions about what the asm might contain and should generate its usual stack alignment code in the prologue if the ‘ call void asm alignstack "eieio", ""() Inline asms also support using non-standard assembly dialects. The assumed dialect is ATT. When the ‘ call void asm inteldialect "eieio", ""() In the case that the inline asm might unwind the stack, the ‘ call void asm unwind "call func", ""() If the inline asm unwinds the stack and isn’t marked with
the ‘ If multiple keywords appear, the ‘ Inline Asm Constraint String¶The constraint list is a comma-separated string, each element containing one or more constraint codes. For each element in the constraint list an appropriate register or memory operand will be chosen, and it will be made available to assembly template string expansion as There are three different types of constraints, which are distinguished by a prefix symbol in front of the constraint code: Output, Input, and Clobber. The constraints must always be given in that order: outputs first, then inputs, then clobbers. They cannot be intermingled. There are also three different categories of constraint codes:
Output constraints¶Output constraints are specified by an “ Normally,
it is expected that no output locations are written to by the assembly expression until all of the inputs have been read. As such, LLVM may assign the same register to an output and an input. If this is not safe (e.g. if the assembly contains two instructions, where the first writes to one output, and the second reads an input and writes to a second output), then the “ Input constraints¶Input constraints do not have a prefix – just the constraint codes. Each input constraint will consume one argument from the call instruction. It is not permitted for the asm to write to any input register or memory location (unless that input is tied to an output). Note also that multiple inputs may all be assigned to the same register, if LLVM can determine that they necessarily all contain the same value. Instead of providing a Constraint Code, input constraints may also “tie” themselves to an output constraint, by providing an integer as the constraint string. Tied inputs still consume an argument from the call instruction, and take up a position in the asm
template numbering as is usual – they will simply be constrained to always use the same register as the output they’ve been tied to. For example, a constraint string of “ It is permitted to tie an input to an “early-clobber” output. In that case, no other input may share the same register as the input tied to the early-clobber (even when the other input has the same value). You may only tie an input to an output which has a register constraint, not a memory constraint. Only a single input may be tied to an output. There is also an “interesting” feature which deserves a bit of explanation: if a register class constraint allocates a register which is too small for the value type operand provided as input, the input value will be split into multiple registers, and all of them passed to the inline asm. However, this feature is often not as useful as you might think. Firstly, the registers are not guaranteed to be consecutive. So, on those architectures that have instructions which operate on multiple consecutive instructions, this is not an appropriate way to support them. (e.g. the 32-bit SparcV8 has a 64-bit load, which instruction takes a single 32-bit register. The hardware then loads into both the named register, and the next register. This feature of inline asm would not be useful to support that.) A
few of the targets provide a template string modifier allowing explicit access to the second register of a two-register operand (e.g. MIPS Indirect inputs and outputs¶Indirect output or input constraints can be specified by the “ This is most typically used for memory constraint, e.g. “ It is also possible to use an indirect register constraint, but only on output (e.g. “ Call arguments for indirect constraints must have pointer type and must specify the elementtype attribute to indicate the pointer element type. Clobber constraints¶A clobber
constraint is indicated by a “ Note that clobbering named registers that are also present in output constraints is not legal. Label constraints¶A label constraint is indicated by a “ Label constraints can only be used in
conjunction with Constraint Codes¶After a potential prefix comes constraint code, or codes. A Constraint Code is either a single letter (e.g. “ The one and two letter constraint codes are typically chosen to be the same as GCC’s constraint codes. A single constraint may include one or more than constraint code in it, leaving it up to LLVM to choose which one to use. This is included mainly for compatibility with the translation of GCC inline asm coming from clang. There are two ways to specify alternatives, and either or both may be used in an inline asm constraint list:
Putting those together, you might have a two operand constraint string like However, the use of either of the alternatives features is NOT recommended, as LLVM is not able to
make an intelligent choice about which one to use. (At the point it currently needs to choose, not enough information is available to do so in a smart way.) Thus, it simply tries to make a choice that’s most likely to compile, not one that will be optimal performance. (e.g., given “ Supported Constraint Code List¶The constraint codes are, in general, expected to behave the same way they do in GCC. LLVM’s support is often implemented on an ‘as-needed’ basis, to support C inline asm code which was supported by GCC. A mismatch in behavior between LLVM and GCC likely indicates a bug in LLVM. Some constraint codes are typically supported by all targets:
Other constraints are target-specific: AArch64:
AMDGPU:
All ARM modes:
ARM and ARM’s Thumb2 mode:
ARM’s Thumb1 mode:
Hexagon:
LoongArch:
MSP430:
MIPS:
NVPTX:
PowerPC:
RISC-V:
Sparc:
SystemZ:
X86:
XCore:
Asm template argument modifiers¶In the asm template string,
modifiers can be used on the operand reference, like “ The modifiers are, in general, expected to behave the same way they do in GCC. LLVM’s support is often implemented on an ‘as-needed’ basis, to support C inline asm code which was supported by GCC. A mismatch in behavior between LLVM and GCC likely indicates a bug in LLVM. Target-independent:
AArch64:
AMDGPU:
ARM:
Hexagon:
LoongArch:
MSP430: No additional modifiers. MIPS:
NVPTX:
PowerPC:
RISC-V:
Sparc:
SystemZ: SystemZ implements only X86:
XCore: No additional modifiers. ThinLTO Summary¶Compiling with ThinLTO causes the building of a compact summary of the module that is emitted into the bitcode. The summary is emitted into the LLVM assembly and identified in syntax by a
caret (‘ The summary is parsed into a bitcode output, along with the Module IR, via the “ Eventually, the summary will be parsed into a ModuleSummaryIndex object under the same conditions where summary index is currently built from bitcode. Specifically,
tools that test the Thin Link portion of a ThinLTO compile (i.e. llvm-lto and llvm-lto2), or when parsing a combined index for a distributed ThinLTO backend via clang’s “ There are currently 3 types of summary entries in the LLVM assembly: module paths, global values, and type identifiers. Module Path Summary Entry¶Each module path summary entry lists a module containing global values included in the summary. For a single IR module there will be one such entry, but in a combined summary index produced during the thin link, there will be one module path entry per linked module with summary. Example: ^0 = module: (path: "/path/to/file.o", hash: (2468601609, 1329373163, 1565878005, 638838075, 3148790418)) The Global Value Summary Entry¶Each global value summary entry corresponds to a global value defined or referenced by a summarized module. Example: ^4 = gv: (name: "f"[, summaries: (Summary)[, (Summary)]*]?) ; guid = 14740650423002898831 For declarations, there will not be a summary list. For definitions, a global value will contain a list of summaries, one per module containing a definition. There can be multiple entries in a combined summary index for symbols with weak linkage. Each Function Summary¶If the global value is a function, the function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 2[, FuncFlags]?[, Calls]?[, TypeIdInfo]?[, Params]?[, Refs]? The Global Variable Summary¶If the global value is a variable, the variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0)[, Refs]? The variable entry contains a subset of the fields in a function summary, see the descriptions there. Alias Summary¶If the global value is an alias, the alias: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), aliasee: ^2) The Function Flags¶The optional funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 0, alwaysInline: 0, noUnwind: 1, mayThrow: 0, hasUnknownCall: 0) If unspecified, flags are assumed to hold the conservative Calls¶The optional calls: ((Callee)[, (Callee)]*) where each callee: ^1[, hotness: None]?[, relbf: 0]? The
Params¶The optional Params: ((Param)[, (Param)]*) where each param: 4, offset: [0, 5][, calls: ((Callee)[, (Callee)]*)]? where the first where each callee: ^3, param: 5, offset: [-3, 3] The Pointer parameter without corresponding Example: If we have the following function: define i64 @foo(ptr %0, ptr %1, ptr %2, i8 %3) { store ptr %1, ptr @x %5 = getelementptr inbounds i8, ptr %2, i64 5 %6 = load i8, ptr %5 %7 = getelementptr inbounds i8, ptr %2, i8 %3 tail call void @bar(i8 %3, ptr %7) %8 = load i64, ptr %0 ret i64 %8 } We can expect the record like this: params: ((param: 0, offset: [0, 7]),(param: 2, offset: [5, 5], calls: ((callee: ^3, param: 1, offset: [-128, 127])))) The function may access just 8 bytes of the parameter %0 .
Refs¶The optional where each TypeIdInfo¶The optional typeIdInfo: [(TypeTests)]?[, (TypeTestAssumeVCalls)]?[, (TypeCheckedLoadVCalls)]?[, (TypeTestAssumeConstVCalls)]?[, (TypeCheckedLoadConstVCalls)]? These optional fields have the following forms: TypeTests¶typeTests: (TypeIdRef[, TypeIdRef]*) Where each TypeTestAssumeVCalls¶typeTestAssumeVCalls: (VFuncId[, VFuncId]*) Where each VFuncId has the format: vFuncId: (TypeIdRef, offset: 16) Where each TypeCheckedLoadVCalls¶typeCheckedLoadVCalls: (VFuncId[, VFuncId]*) Where each VFuncId has the
format described for TypeTestAssumeConstVCalls¶typeTestAssumeConstVCalls: (ConstVCall[, ConstVCall]*) Where each ConstVCall has the format: (VFuncId, args: (Arg[, Arg]*)) and where each VFuncId has the format described for TypeCheckedLoadConstVCalls¶typeCheckedLoadConstVCalls: (ConstVCall[, ConstVCall]*) Where each ConstVCall has the format described for Type ID Summary Entry¶Each type id summary entry corresponds to a type identifier resolution which is generated during the LTO link portion of the compile when building with Control Flow Integrity, so these are only present in a combined summary index. Example: ^4 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7[, alignLog2: 0]?[, sizeM1: 0]?[, bitMask: 0]?[, inlineBits: 0]?)[, WpdResolutions]?)) ; guid = 7004155349499253778 The wpdResolutions: ((offset: 0, WpdRes)[, (offset: 1, WpdRes)]* where each entry is a mapping from the given byte offset to the whole-program devirtualization resolution WpdRes, that has one of the following formats: wpdRes: (kind: branchFunnel) wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi") wpdRes: (kind: indir) Additionally, each wpdRes has an optional resByArg: (ResByArg[, ResByArg]*) where ResByArg is: args: (Arg[, Arg]*), byArg: (kind: UniformRetVal[, info: 0][, byte: 0][, bit: 0]) Where the Intrinsic Global Variables¶LLVM has a number of “magic” global variables that contain data that affect code generation or other IR semantics. These are documented here. All globals of this sort should have a section specified as “ The ‘llvm.used’ Global Variable¶The @X = global i8 4 @Y = global i32 123 @llvm.used = appending global [2 x ptr] [ ptr @X, ptr @Y ], section "llvm.metadata" If a symbol appears in the On some targets, the code generator must emit a directive to the assembler or object file to prevent the assembler and linker from removing the symbol. The ‘llvm.compiler.used’ Global Variable¶The This is a rare construct that should only be used in rare circumstances, and should not be exposed to source languages. The ‘llvm.global_ctors’ Global Variable¶%0 = type { i32, ptr, ptr } @llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, ptr @ctor, ptr @data }] The If the third field is non-null, and points to a global variable or function, the initializer function will only run if the associated data from the current module is not discarded. On ELF the referenced global variable or function must be in a comdat. The ‘llvm.global_dtors’ Global Variable¶%0 = type { i32, ptr, ptr } @llvm.global_dtors = appending global [1 x %0] [%0 { i32 65535, ptr @dtor, ptr @data }] The If the third field is non-null, and points to a global variable or function, the destructor function will only run if the associated data from the current module is not discarded. On ELF the referenced global variable or function must be in a comdat. Instruction Reference¶The LLVM instruction set consists of several different classifications of instructions: terminator instructions, binary instructions, bitwise binary instructions, memory instructions, and other instructions. Terminator Instructions¶As mentioned previously, every basic block in a program ends with a “Terminator” instruction, which indicates which block should be executed after the current block is finished.
These terminator instructions typically yield a ‘ The terminator instructions are: ‘ret’, ‘br’, ‘switch’, ‘indirectbr’, ‘invoke’, ‘callbr’ ‘resume’, ‘catchswitch’, ‘catchret’, ‘cleanupret’, and ‘unreachable’. ‘ |
In0 | In1 | Out |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Example:¶
<result> = and i32 4, %var ; yields i32:result = 4 & %var <result> = and i32 15, 40 ; yields i32:result = 8 <result> = and i32 4, 8 ; yields i32:result = 0
‘or
’ Instruction¶
Syntax:¶
<result> = or <ty> <op1>, <op2> ; yields ty:result
Overview:¶
The ‘or
’ instruction returns the bitwise logical inclusive or of its two operands.
Arguments:¶
The two arguments to the ‘or
’ instruction must be integer or vector of integer values. Both arguments must have identical types.
Semantics:¶
The truth table used for the ‘or
’ instruction is:
In0 | In1 | Out |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Example:¶
<result> = or i32 4, %var ; yields i32:result = 4 | %var <result> = or i32 15, 40 ; yields i32:result = 47 <result> = or i32 4, 8 ; yields i32:result = 12
‘xor
’ Instruction¶
Syntax:¶
<result> = xor <ty> <op1>, <op2> ; yields ty:result
Overview:¶
The ‘xor
’ instruction returns the bitwise logical exclusive or of its two operands. The xor
is used to implement the “one’s complement” operation, which is the “~” operator in C.
Arguments:¶
The two arguments to the ‘xor
’ instruction must be integer or vector of integer values. Both arguments must have identical types.
Semantics:¶
The truth table used for the ‘xor
’ instruction is:
In0 | In1 | Out |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Example:¶
<result> = xor i32 4, %var ; yields i32:result = 4 ^ %var <result> = xor i32 15, 40 ; yields i32:result = 39 <result> = xor i32 4, 8 ; yields i32:result = 12 <result> = xor i32 %V, -1 ; yields i32:result = ~%V
Vector Operations¶
LLVM supports several instructions to represent vector operations in a target-independent manner. These instructions cover the element-access and vector-specific operations needed to process vectors effectively. While LLVM does directly support these vector operations, many sophisticated algorithms will want to use target-specific intrinsics to take full advantage of a specific target.
‘insertelement
’
Instruction¶
Syntax:¶
<result> = insertelement <n x <ty>> <val>, <ty> <elt>, <ty2> <idx> ; yields <n x <ty>> <result> = insertelement <vscale x n x <ty>> <val>, <ty> <elt>, <ty2> <idx> ; yields <vscale x n x <ty>>
Overview:¶
The ‘insertelement
’ instruction inserts a scalar
element into a vector at a specified index.
Arguments:¶
The first operand of an ‘insertelement
’ instruction is a value of vector type. The second operand is a scalar value whose type must equal the element type of the first operand. The third operand is an index indicating
the position at which to insert the value. The index may be a variable of any integer type, and will be treated as an unsigned integer.
Semantics:¶
The result is a vector of the same type as val
. Its element values are those of val
except at position idx
, where it gets the value elt
. If idx
exceeds the length of val
for a
fixed-length vector, the result is a poison value. For a scalable vector, if the value of idx
exceeds the runtime length of the vector, the result is a poison value.
Example:¶
<result> = insertelement <4 x i32> %vec, i32 1, i32 0 ; yields <4 x i32>
‘shufflevector
’ Instruction¶
Syntax:¶
<result> = shufflevector <n x <ty>> <v1>, <n x <ty>> <v2>, <m x i32> <mask> ; yields <m x <ty>> <result> = shufflevector <vscale x n x <ty>> <v1>, <vscale x n x <ty>> v2, <vscale x m x i32> <mask> ; yields <vscale x m x <ty>>
Overview:¶
The ‘shufflevector
’ instruction constructs a permutation of elements from two input vectors, returning a vector with the same element type as the input and length that is the same as the shuffle mask.
Arguments:¶
The first two operands of a ‘shufflevector
’
instruction are vectors with the same type. The third argument is a shuffle mask vector constant whose element type is i32
. The mask vector elements must be constant integers or undef
values. The result of the instruction is a vector whose length is the same as the shuffle mask and whose element type is the same as the element type of the first two operands.
Semantics:¶
The elements of the two input vectors are numbered from left to right across both of the vectors. For each element of the result vector, the shuffle mask selects an element from one of the input vectors to copy to the result. Non-negative elements in the mask represent an index into the concatenated pair of input vectors.
If the shuffle mask is undefined, the result vector is undefined. If the shuffle mask selects an undefined element from one of the input vectors, the resulting element is undefined. An undefined element in the mask vector specifies that the resulting element is undefined. An undefined element in the mask vector prevents a poisoned vector element from propagating.
For scalable vectors, the only valid mask values at present are zeroinitializer
and undef
, since we cannot write all indices as literals for a vector with a length unknown at compile time.
Example:¶
<result> = shufflevector <4 x i32> %v1, <4 x i32> %v2, <4 x i32> <i32 0, i32 4, i32 1, i32 5> ; yields <4 x i32> <result> = shufflevector <4 x i32> %v1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; yields <4 x i32> - Identity shuffle. <result> = shufflevector <8 x i32> %v1, <8 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; yields <4 x i32> <result> = shufflevector <4 x i32> %v1, <4 x i32> %v2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7 > ; yields <8 x i32>
Aggregate Operations¶
LLVM supports several instructions for working with aggregate values.
‘insertvalue
’ Instruction¶
Syntax:¶
<result> = insertvalue <aggregate type> <val>, <ty> <elt>, <idx>{, <idx>}* ; yields <aggregate type>
Overview:¶
The ‘insertvalue
’ instruction inserts a value into a member field in an aggregate value.
Arguments:¶
The first operand of an ‘insertvalue
’ instruction is a value of struct or array type. The second operand is a first-class value to insert. The following operands are constant indices indicating the position at which to
insert the value in a similar manner as indices in a ‘extractvalue
’ instruction. The value to insert must have the same type as the value identified by the indices.
Semantics:¶
The result is an aggregate of the same type as val
. Its value is that of val
except that the value at the position specified by the indices is that of elt
.
Example:¶
%agg1 = insertvalue {i32, float} undef, i32 1, 0 ; yields {i32 1, float undef} %agg2 = insertvalue {i32, float} %agg1, float %val, 1 ; yields {i32 1, float %val} %agg3 = insertvalue {i32, {float}} undef, float %val, 1, 0 ; yields {i32 undef, {float %val}}
Memory Access and Addressing Operations¶
A key design point of an SSA-based representation is how it represents memory. In LLVM, no memory locations are in SSA form, which makes things very simple. This section describes how to read, write, and allocate memory in LLVM.
‘alloca
’ Instruction¶
Syntax:¶
<result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] [, addrspace(<num>)] ; yields type addrspace(num)*:result
Overview:¶
The ‘alloca
’ instruction allocates memory on the stack frame of the currently executing function, to be automatically released when this function returns to its caller. If the address space is not explicitly specified,
the object is allocated in the alloca address space from the datalayout string.
Arguments:¶
The ‘alloca
’ instruction allocates sizeof(<type>)*NumElements
bytes of memory on the runtime stack, returning a pointer of the appropriate type to the program. If “NumElements” is
specified, it is the number of elements allocated, otherwise “NumElements” is defaulted to be one. If a constant alignment is specified, the value result of the allocation is guaranteed to be aligned to at least that boundary. The alignment may not be greater than 1 << 32
. If not specified, or if zero, the target can choose to align the allocation on any convenient boundary compatible with the type.
‘type
’ may be any sized type.
Semantics:¶
Memory is allocated; a pointer is returned. The allocated memory is uninitialized, and loading from uninitialized memory produces an undefined value. The operation itself is undefined if there is insufficient stack space for the allocation.’alloca
’d memory is automatically released when the function returns. The ‘alloca
’ instruction is commonly used to represent automatic variables
that must have an address available. When the function returns (either with the ret
or resume
instructions), the memory is reclaimed. Allocating zero bytes is legal, but the returned pointer may not be unique. The order in which memory is allocated (ie., which way the stack grows) is not specified.
Note that ‘alloca
’ outside of the alloca address space from the datalayout string is
meaningful only if the target has assigned it a semantics.
If the returned pointer is used by llvm.lifetime.start, the returned object is initially dead. See llvm.lifetime.start and llvm.lifetime.end for the precise semantics of lifetime-manipulating intrinsics.
Example:¶
%ptr = alloca i32 ; yields ptr %ptr = alloca i32, i32 4 ; yields ptr %ptr = alloca i32, i32 4, align 1024 ; yields ptr %ptr = alloca i32, align 1024 ; yields ptr
‘load
’ Instruction¶
Syntax:¶
<result> = load [volatile] <ty>, ptr <pointer>[, align <alignment>][, !nontemporal !<nontemp_node>][, !invariant.load !<empty_node>][, !invariant.group !<empty_node>][, !nonnull !<empty_node>][, !dereferenceable !<deref_bytes_node>][, !dereferenceable_or_null !<deref_bytes_node>][, !align !<align_node>][, !noundef !<empty_node>] <result> = load atomic [volatile] <ty>, ptr <pointer> [syncscope("<target-scope>")] <ordering>, align <alignment> [, !invariant.group !<empty_node>] !<nontemp_node> = !{ i32 1 } !<empty_node> = !{} !<deref_bytes_node> = !{ i64 <dereferenceable_bytes> } !<align_node> = !{ i64 <value_alignment> }
Overview:¶
The ‘load
’ instruction is used to read from memory.
Arguments:¶
The argument
to the load
instruction specifies the memory address from which to load. The type specified must be a first class type of known size (i.e. not containing an opaque structural type). If the load
is marked as volatile
, then the optimizer is not allowed to modify the number or order of execution of this load
with other volatile operations.
If the load
is marked as atomic
, it takes an extra ordering and optional syncscope("<target-scope>")
argument. The release
and acq_rel
orderings are not valid on load
instructions. Atomic loads produce
defined results when they may see multiple atomic stores. The type of the pointee must be an integer, pointer, or floating-point type whose bit width is a power of two greater than or equal to eight and less than or equal to a target-specific size limit. align
must be explicitly specified on atomic loads, and the load has undefined behavior if the alignment is not set to a value which is at least the size
in bytes of the pointee. !nontemporal
does not have any defined semantics for atomic loads.
The optional constant align
argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted align
argument means that the operation has the ABI alignment for the target. It is the responsibility of the code emitter to ensure that the alignment information is correct. Overestimating the alignment results in undefined behavior.
Underestimating the alignment may produce less efficient code. An alignment of 1 is always safe. The maximum possible alignment is 1 << 32
. An alignment value higher than the size of the loaded type implies memory up to the alignment value bytes can be safely loaded without trapping in the default address space. Access of the high bytes can interfere with debugging tools, so should not be accessed if the function has the sanitize_thread
or sanitize_address
attributes.
The optional !nontemporal
metadata must
reference a single metadata name <nontemp_node>
corresponding to a metadata node with one i32
entry of value 1. The existence of the !nontemporal
metadata on the instruction tells the optimizer and code generator that this load is not expected to be reused in the cache. The code generator may select special instructions to save cache bandwidth, such as the MOVNT
instruction on x86.
The optional !invariant.load
metadata must reference a single metadata name <empty_node>
corresponding to a metadata node
with no entries. If a load instruction tagged with the !invariant.load
metadata is executed, the memory location referenced by the load has to contain the same value at all points in the program where the memory location is dereferenceable; otherwise, the behavior is undefined.
!invariant.group
metadata must reference a single metadata name<empty_node>
corresponding to a metadata node with no entries. See invariant.group
metadata
invariant.group.The optional !nonnull
metadata must reference a single metadata name <empty_node>
corresponding to a metadata node with no entries. The existence of the !nonnull
metadata on the instruction tells the optimizer that the value loaded is known to never be null. If the value is null at runtime, the behavior is undefined. This is analogous to the nonnull
attribute on parameters
and return values. This metadata can only be applied to loads of a pointer type.
The optional !dereferenceable
metadata must reference a single metadata name <deref_bytes_node>
corresponding to a metadata node with one i64
entry. See dereferenceable
metadata dereferenceable.
The optional !dereferenceable_or_null
metadata must reference a single metadata name <deref_bytes_node>
corresponding to a metadata node with one i64
entry.
See dereferenceable_or_null
metadata dereferenceable_or_null.
The optional !align
metadata must reference a single metadata name <align_node>
corresponding to a metadata node with one i64
entry. The existence of the !align
metadata on the instruction tells the optimizer that the value loaded is known to be aligned to a boundary specified by the integer value in the metadata node. The alignment
must be a power of 2. This is analogous to the ‘’align’’ attribute on parameters and return values. This metadata can only be applied to loads of a pointer type. If the returned value is not appropriately aligned at runtime, the behavior is undefined.
The optional !noundef
metadata must reference a single metadata name <empty_node>
corresponding to a node with no entries. The existence of !noundef
metadata on the instruction tells the optimizer that the value loaded is known to be
well defined. If the value isn’t well defined, the behavior is undefined.
Semantics:¶
The location of memory pointed to is loaded. If the value being loaded is of scalar type then the number of bytes read does not exceed the minimum number of bytes needed to
hold all bits of the type. For example, loading an i24
reads at most three bytes. When loading a value of a type like i20
with a size that is not an integral number of bytes, the result is undefined if the value was not originally written using a store of the same type. If the value being loaded is of aggregate type, the bytes that correspond to padding may be accessed but are ignored, because it is impossible to observe padding from the loaded aggregate value. If <pointer>
is not a
well-defined value, the behavior is undefined.
Examples:¶
%ptr = alloca i32 ; yields ptr store i32 3, ptr %ptr ; yields void %val = load i32, ptr %ptr ; yields i32:val = i32 3
‘store
’ Instruction¶
Syntax:¶
store [volatile] <ty> <value>, ptr <pointer>[, align <alignment>][, !nontemporal !<nontemp_node>][, !invariant.group !<empty_node>] ; yields void store atomic [volatile] <ty> <value>, ptr <pointer> [syncscope("<target-scope>")] <ordering>, align <alignment> [, !invariant.group !<empty_node>] ; yields void !<nontemp_node> = !{ i32 1 } !<empty_node> = !{}
Overview:¶
The ‘store
’ instruction is used to write to memory.
Arguments:¶
There are two
arguments to the store
instruction: a value to store and an address at which to store it. The type of the <pointer>
operand must be a pointer to the first class type of the <value>
operand. If the store
is marked as volatile
, then the optimizer is not allowed to modify the number or order of execution of this store
with other
volatile operations. Only values of first class types of known size (i.e. not containing an opaque structural type) can be stored.
If the store
is marked as atomic
, it takes an extra
ordering and optional syncscope("<target-scope>")
argument. The acquire
and acq_rel
orderings aren’t valid on store
instructions. Atomic loads produce defined results when they may see multiple atomic stores. The type of the pointee must be an integer, pointer, or floating-point type whose bit width is a power of two greater than or equal
to eight and less than or equal to a target-specific size limit. align
must be explicitly specified on atomic stores, and the store has undefined behavior if the alignment is not set to a value which is at least the size in bytes of the pointee. !nontemporal
does not have any defined semantics for atomic stores.
The optional constant align
argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted align
argument means
that the operation has the ABI alignment for the target. It is the responsibility of the code emitter to ensure that the alignment information is correct. Overestimating the alignment results in undefined behavior. Underestimating the alignment may produce less efficient code. An alignment of 1 is always safe. The maximum possible alignment is 1 << 32
. An alignment value higher than the size of the stored type implies memory up to the alignment value bytes can be stored to without trapping in
the default address space. Storing to the higher bytes however may result in data races if another thread can access the same address. Introducing a data race is not allowed. Storing to the extra bytes is not allowed even in situations where a data race is known to not exist if the function has the sanitize_address
attribute.
The optional !nontemporal
metadata must reference a single metadata name <nontemp_node>
corresponding to a metadata node with one i32
entry of value 1. The existence of the
!nontemporal
metadata on the instruction tells the optimizer and code generator that this load is not expected to be reused in the cache. The code generator may select special instructions to save cache bandwidth, such as the MOVNT
instruction on x86.
The optional !invariant.group
metadata must reference a single metadata name <empty_node>
. See invariant.group
metadata.
Semantics:¶
The contents of memory are updated to contain <value>
at the location specified by the <pointer>
operand. If <value>
is of scalar type then the number of bytes written does not exceed the minimum number of bytes needed to hold all bits of the type. For example, storing an i24
writes at most three bytes. When writing a value of a type like i20
with a size that is not an
integral number of bytes, it is unspecified what happens to the extra bits that do not belong to the type, but they will typically be overwritten. If <value>
is of aggregate type, padding is filled with undef. If <pointer>
is not a well-defined value, the behavior is undefined.
Example:¶
%ptr = alloca i32 ; yields ptr store i32 3, ptr %ptr ; yields void %val = load i32, ptr %ptr ; yields i32:val = i32 3
‘fence
’ Instruction¶
Syntax:¶
fence [syncscope("<target-scope>")] <ordering> ; yields void
Overview:¶
The ‘fence
’ instruction is used to introduce happens-before edges between operations.
Arguments:¶
‘fence
’ instructions take an
ordering argument which defines what synchronizes-with edges they add. They can only be given acquire
, release
, acq_rel
, and seq_cst
orderings.
Semantics:¶
A fence A which has (at least) release
ordering semantics synchronizes with a fence B with
(at least) acquire
ordering semantics if and only if there exist atomic operations X and Y, both operating on some atomic object M, such that A is sequenced before X, X modifies M (either directly or through some side effect of a sequence headed by X), Y is sequenced before B, and Y observes M. This provides a happens-before dependency between A and B. Rather than an explicit fence
, one (but not both) of the atomic operations X or Y might provide a release
or acquire
(resp.)
ordering constraint and still synchronize-with the explicit fence
and establish the happens-before edge.
A fence
which has seq_cst
ordering, in addition to having both acquire
and release
semantics specified above, participates in the global program order of other seq_cst
operations and/or fences.
A fence
instruction can also take an optional “syncscope” argument.
Example:¶
fence acquire ; yields void fence syncscope("singlethread") seq_cst ; yields void fence syncscope("agent") seq_cst ; yields void
‘cmpxchg
’ Instruction¶
Syntax:¶
cmpxchg [weak] [volatile] ptr <pointer>, <ty> <cmp>, <ty> <new> [syncscope("<target-scope>")] <success ordering> <failure ordering>[, align <alignment>] ; yields { ty, i1 }
Overview:¶
The ‘cmpxchg
’ instruction is used to atomically modify memory. It loads a value in memory and compares it to a given value. If they are equal, it tries to store a new value into the memory.
Arguments:¶
There are three arguments to the ‘cmpxchg
’ instruction: an address to operate on, a value to compare to the value currently be at that address, and a new value to place at that address if the compared values are equal. The type of ‘<cmp>’ must be an integer or pointer type whose bit width is a power of two greater than or equal to eight and less than or equal to a
target-specific size limit. ‘<cmp>’ and ‘<new>’ must have the same type, and the type of ‘<pointer>’ must be a pointer to that type. If the cmpxchg
is marked as volatile
, then the optimizer is not allowed to modify the number or order of execution of this cmpxchg
with other volatile operations.
The success and failure
ordering arguments specify how this cmpxchg
synchronizes with other atomic operations. Both ordering parameters must be at least monotonic
, the failure ordering cannot be either release
or acq_rel
.
A cmpxchg
instruction can also take an optional “syncscope” argument.
The instruction can take an optional
align
attribute. The alignment must be a power of two greater or equal to the size of the <value> type. If unspecified, the alignment is assumed to be equal to the size of the ‘<value>’ type. Note that this default alignment assumption is different from the alignment used for the load/store instructions when align isn’t specified.
The pointer passed into cmpxchg must have alignment greater than or equal to the size in memory of the operand.
Semantics:¶
The contents of memory at the location specified by the ‘<pointer>
’ operand is read and compared to ‘<cmp>
’; if the values are equal, ‘<new>
’ is written to the location. The original value at the location is returned, together with a flag indicating success (true) or failure (false).
If the cmpxchg operation is marked as
weak
then a spurious failure is permitted: the operation may not write <new>
even if the comparison matched.
If the cmpxchg operation is strong (the default), the i1 value is 1 if and only if the value loaded equals cmp
.
A successful cmpxchg
is a read-modify-write instruction for the purpose of identifying release sequences. A failed cmpxchg
is equivalent to an atomic load with an ordering parameter determined the second ordering parameter.
Example:¶
entry: %orig = load atomic i32, ptr %ptr unordered, align 4 ; yields i32 br label %loop loop: %cmp = phi i32 [ %orig, %entry ], [%value_loaded, %loop] %squared = mul i32 %cmp, %cmp %val_success = cmpxchg ptr %ptr, i32 %cmp, i32 %squared acq_rel monotonic ; yields { i32, i1 } %value_loaded = extractvalue { i32, i1 } %val_success, 0 %success = extractvalue { i32, i1 } %val_success, 1 br i1 %success, label %done, label %loop done: ...
‘atomicrmw
’ Instruction¶
Syntax:¶
atomicrmw [volatile] <operation> ptr <pointer>, <ty> <value> [syncscope("<target-scope>")] <ordering>[, align <alignment>] ; yields ty
Overview:¶
The ‘atomicrmw
’ instruction is used to atomically modify memory.
Arguments:¶
There
are three arguments to the ‘atomicrmw
’ instruction: an operation to apply, an address whose value to modify, an argument to the operation. The operation must be one of the following keywords:
- xchg
- add
- sub
- and
- nand
- or
- xor
- max
- min
- umax
- umin
- fadd
- fsub
- fmax
- fmin
For most of these operations, the type of ‘<value>’ must be an integer type whose bit width is a
power of two greater than or equal to eight and less than or equal to a target-specific size limit. For xchg, this may also be a floating point or a pointer type with the same size constraints as integers. For fadd/fsub/fmax/fmin, this must be a floating point type. The type of the ‘<pointer>
’ operand must be a pointer to that type. If the atomicrmw
is marked as volatile
, then the optimizer is not allowed to modify the number or order of execution of this atomicrmw
with other
volatile operations.
The instruction can take an optional align
attribute. The alignment must be a power of two greater or equal to the size of the <value> type. If unspecified, the alignment is assumed to be equal to the size of the ‘<value>’ type. Note that this default alignment assumption is different from the alignment used for the load/store instructions when align isn’t
specified.
A atomicrmw
instruction can also take an optional “syncscope” argument.
Semantics:¶
The contents of memory at the location specified by the ‘<pointer>
’ operand are atomically read, modified, and written back. The original value at the location is
returned. The modification is specified by the operation argument:
- xchg:
*ptr = val
- add:
*ptr = *ptr + val
- sub:
*ptr = *ptr - val
- and:
*ptr = *ptr & val
- nand:
*ptr = ~(*ptr & val)
- or:
*ptr = *ptr | val
- xor:
*ptr = *ptr ^ val
- max:
*ptr = *ptr > val ? *ptr : val
(using a signed comparison) - min:
*ptr = *ptr < val ? *ptr : val
(using a signed comparison) - umax:
*ptr = *ptr > val ? *ptr : val
(using an unsigned comparison) - umin:
*ptr = *ptr < val ? *ptr : val
(using an unsigned comparison) - fadd:
*ptr = *ptr + val
(using floating point arithmetic) - fsub:
*ptr = *ptr - val
(using floating point arithmetic) - fmax:
*ptr = maxnum(*ptr, val)
(match the llvm.maxnum.*` intrinsic) - fmin:
*ptr = minnum(*ptr, val)
(match the llvm.minnum.*` intrinsic)
Example:¶
%old = atomicrmw add ptr %ptr, i32 1 acquire ; yields i32
‘getelementptr
’
Instruction¶
Syntax:¶
<result> = getelementptr <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}* <result> = getelementptr inbounds <ty>, ptr <ptrval>{, [inrange] <ty> <idx>}* <result> = getelementptr <ty>, <N x ptr> <ptrval>, [inrange] <vector index type> <idx>
Overview:¶
The ‘getelementptr
’ instruction is used to get the
address of a subelement of an aggregate data structure. It performs address calculation only and does not access memory. The instruction can also be used to calculate a vector of such addresses.
Arguments:¶
The first argument is always a type used as the basis for the calculations. The second argument is always a pointer or a vector of pointers, and is the base address to start from. The remaining arguments are indices that indicate which of the elements of the aggregate object are indexed. The interpretation of each index is dependent on the type being indexed into. The first index always indexes the pointer value given as the second argument, the second index indexes a value of the type pointed to (not necessarily the value directly pointed to, since the first index can be non-zero), etc. The first type indexed into must be a pointer value, subsequent types can be arrays, vectors, and structs. Note that subsequent types being indexed into can never be pointers, since that would require loading the pointer before continuing calculation.
The type of each index argument depends on the type it is indexing into. When indexing into a (optionally packed) structure, only i32
integer constants are allowed (when using a vector
of indices they must all be the same i32
integer constant). When indexing into an array, pointer or vector, integers of any width are allowed, and they are not required to be constant. These integers are treated as signed values where relevant.
For example, let’s consider a C code fragment and how it gets compiled to LLVM:
struct RT { char A; int B[10][20]; char C; }; struct ST { int X; double Y; struct RT Z; }; int *foo(struct ST *s) { return &s[1].Z.B[5][13]; }
The LLVM code generated by Clang is:
%struct.RT = type { i8, [10 x [20 x i32]], i8 } %struct.ST = type { i32, double, %struct.RT } define ptr @foo(ptr %s) nounwind uwtable readnone optsize ssp { entry: %arrayidx = getelementptr inbounds %struct.ST, ptr %s, i64 1, i32 2, i32 1, i64 5, i64 13 ret ptr %arrayidx }
Semantics:¶
In the example above, the first index is indexing into the ‘%struct.ST*
’ type, which is a pointer, yielding a ‘%struct.ST
’ = ‘{ i32, double, %struct.RT }
’ type, a structure. The second index indexes into the third element of the structure, yielding a ‘%struct.RT
’ = ‘{ i8 , [10 x [20 x i32]], i8 }
’ type, another structure. The third index indexes into the second element of the structure, yielding a ‘[10 x [20 x i32]]
’ type, an array. The two
dimensions of the array are subscripted into, yielding an ‘i32
’ type. The ‘getelementptr
’ instruction returns a pointer to this element.
Note that it is perfectly legal to index partially through a structure, returning a pointer to an inner element. Because of this, the LLVM code for the given testcase is equivalent to:
define ptr @foo(ptr %s) { %t1 = getelementptr %struct.ST, ptr %s, i32 1 %t2 = getelementptr %struct.ST, ptr %t1, i32 0, i32 2 %t3 = getelementptr %struct.RT, ptr %t2, i32 0, i32 1 %t4 = getelementptr [10 x [20 x i32]], ptr %t3, i32 0, i32 5 %t5 = getelementptr [20 x i32], ptr %t4, i32 0, i32 13 ret ptr %t5 }
If the inbounds
keyword is present, the result value of the getelementptr
is a
poison value if one of the following rules is violated:
- The base pointer has an in bounds address of an allocated object, which means that it points into an allocated object, or to its end. The only in bounds address for a null pointer in the default address-space is the null pointer itself.
- If the type of an index is larger than the pointer index type, the truncation to the pointer index type preserves the signed value.
- The multiplication of an index by the type size does not wrap the pointer index type in a signed sense (
nsw
). - The successive addition of offsets (without adding the base address) does not wrap the pointer index type in a signed sense (
nsw
). - The successive addition of the current address, interpreted as an unsigned number, and an offset, interpreted as a signed number, does not wrap the unsigned address space
and remains in bounds of the allocated object. As a corollary, if the added offset is non-negative, the addition does not wrap in an unsigned sense (
nuw
). - In cases where the base is a vector of pointers, the
inbounds
keyword applies to each of the computations element-wise.
These rules are based on the assumption that no allocated object may cross the unsigned address space boundary, and no allocated object may be larger than half the pointer index type space.
If the inbounds
keyword is not present, the offsets are added to the base address with silently-wrapping two’s complement arithmetic. If the offsets have a different width from the pointer, they are sign-extended or truncated to the width of the pointer. The result value of the getelementptr
may be outside the object pointed to by the base pointer. The result value may not necessarily be used to access memory though, even if it happens to point into allocated storage. See the
Pointer Aliasing Rules section for more information.
If the inrange
keyword is present before any index, loading from or storing to any pointer derived from the getelementptr
has undefined behavior if the load or store would access memory outside of the bounds of the element selected by the index marked as inrange
. The result of a pointer comparison or ptrtoint
(including ptrtoint
-like operations
involving memory) involving a pointer derived from a getelementptr
with the inrange
keyword is undefined, with the exception of comparisons in the case where both operands are in the range of the element selected by the inrange
keyword, inclusive of the address one past the end of that element. Note that the inrange
keyword is currently only allowed in constant getelementptr
expressions.
The getelementptr instruction is often confusing. For some more insight into how it works, see the getelementptr FAQ.
Example:¶
%aptr = getelementptr {i32, [12 x i8]}, ptr %saptr, i64 0, i32 1 %vptr = getelementptr {i32, <2 x i8>}, ptr %svptr, i64 0, i32 1, i32 1 %eptr = getelementptr [12 x i8], ptr %aptr, i64 0, i32 1 %iptr = getelementptr [10 x i32], ptr @arr, i16 0, i16 0
Vector of pointers:¶
The getelementptr
returns a vector of
pointers, instead of a single address, when one or more of its arguments is a vector. In such cases, all vector arguments should have the same number of elements, and every scalar argument will be effectively broadcast into a vector during address calculation.
; All arguments are vectors: ; A[i] = ptrs[i] + offsets[i]*sizeof(i8) %A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets ; Add the same scalar offset to each pointer of a vector: ; A[i] = ptrs[i] + offset*sizeof(i8) %A = getelementptr i8, <4 x ptr> %ptrs, i64 %offset ; Add distinct offsets to the same pointer: ; A[i] = ptr + offsets[i]*sizeof(i8) %A = getelementptr i8, ptr %ptr, <4 x i64> %offsets ; In all cases described above the type of the result is <4 x ptr>
The two following instructions are equivalent:
getelementptr %struct.ST, <4 x ptr> %s, <4 x i64> %ind1, <4 x i32> <i32 2, i32 2, i32 2, i32 2>, <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32> %ind4, <4 x i64> <i64 13, i64 13, i64 13, i64 13> getelementptr %struct.ST, <4 x ptr> %s, <4 x i64> %ind1, i32 2, i32 1, <4 x i32> %ind4, i64 13
Let’s look at the C code, where the vector version of getelementptr
makes sense:
// Let's assume that we vectorize the following loop: double *A, *B; int *C; for (int i = 0; i < size; ++i) { A[i] = B[C[i]]; }
; get pointers for 8 elements from array B %ptrs = getelementptr double, ptr %B, <8 x i32> %C ; load 8 elements from array B into A %A = call <8 x double> @llvm.masked.gather.v8f64.v8p0f64(<8 x ptr> %ptrs, i32 8, <8 x i1> %mask, <8 x double> %passthru)
Conversion Operations¶
The instructions in this category are the conversion instructions (casting) which all take a single operand and a type. They perform various bit conversions on the operand.
‘trunc .. to
’ Instruction¶
Syntax:¶
<result> = trunc <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘trunc
’ instruction truncates its operand to the type ty2
.
Arguments:¶
The ‘trunc
’ instruction takes a value to trunc, and a type to trunc it to. Both types must be of
integer types, or vectors of the same number of integers. The bit size of the value
must be larger than the bit size of the destination type, ty2
. Equal sized types are not allowed.
Semantics:¶
The ‘trunc
’ instruction truncates the high order bits in value
and converts the remaining bits to ty2
. Since the source size must be larger than the destination size, trunc
cannot be a no-op cast. It will always truncate bits.
Example:¶
%X = trunc i32 257 to i8 ; yields i8:1 %Y = trunc i32 123 to i1 ; yields i1:true %Z = trunc i32 122 to i1 ; yields i1:false %W = trunc <2 x i16> <i16 8, i16 7> to <2 x i8> ; yields <i8 8, i8 7>
‘zext .. to
’
Instruction¶
Syntax:¶
<result> = zext <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘zext
’ instruction zero extends its operand
to type ty2
.
Arguments:¶
The ‘zext
’ instruction takes a value to cast, and a type to cast it to. Both types must be of integer types, or vectors of the same number of integers. The bit size of the value
must be smaller than the bit size of the destination
type, ty2
.
Semantics:¶
The zext
fills the high order bits of the value
with zero bits until it reaches the size of the destination type, ty2
.
When zero extending from i1, the result will always be either 0 or 1.
Example:¶
%X = zext i32 257 to i64 ; yields i64:257 %Y = zext i1 true to i32 ; yields i32:1 %Z = zext <2 x i16> <i16 8, i16 7> to <2 x i32> ; yields <i32 8, i32 7>
‘sext .. to
’ Instruction¶
Syntax:¶
<result> = sext <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘sext
’ sign extends value
to the type ty2
.
Arguments:¶
The
‘sext
’ instruction takes a value to cast, and a type to cast it to. Both types must be of integer types, or vectors of the same number of integers. The bit size of the value
must be smaller than the bit size of the destination type, ty2
.
Semantics:¶
The ‘sext
’ instruction performs a sign extension by copying the sign bit (highest order bit) of the value
until it reaches the bit size of the type ty2
.
When sign extending from i1, the extension always results in -1 or 0.
Example:¶
%X = sext i8 -1 to i16 ; yields i16 :65535 %Y = sext i1 true to i32 ; yields i32:-1 %Z = sext <2 x i16> <i16 8, i16 7> to <2 x i32> ; yields <i32 8, i32 7>
‘fptrunc .. to
’ Instruction¶
Syntax:¶
<result> = fptrunc <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘fptrunc
’ instruction truncates value
to type ty2
.
Arguments:¶
The ‘fptrunc
’ instruction takes a floating-point value to cast and a
floating-point type to cast it to. The size of value
must be larger than the size of ty2
. This implies that fptrunc
cannot be used to make a no-op cast.
Example:¶
%X = fptrunc double 16777217.0 to float ; yields float:16777216.0 %Y = fptrunc double 1.0E+300 to half ; yields half:+infinity
‘fpext .. to
’ Instruction¶
Syntax:¶
<result> = fpext <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘fpext
’ extends a floating-point value
to a larger floating-point value.
Arguments:¶
The ‘fpext
’ instruction takes a floating-point value
to
cast, and a floating-point type to cast it to. The source type must be smaller than the destination type.
Semantics:¶
The ‘fpext
’ instruction extends the value
from a smaller
floating-point type to a larger floating-point type. The fpext
cannot be used to make a no-op cast because it always changes bits. Use bitcast
to make a no-op cast for a floating-point cast.
Example:¶
%X = fpext float 3.125 to double ; yields double:3.125000e+00 %Y = fpext double %X to fp128 ; yields fp128:0xL00000000000000004000900000000000
‘fptoui .. to
’ Instruction¶
Syntax:¶
<result> = fptoui <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘fptoui
’ converts a floating-point value
to its unsigned integer equivalent of type ty2
.
Arguments:¶
The ‘fptoui
’ instruction takes a value to cast, which must be a scalar or vector floating-point value, and a type to cast it to ty2
, which must be an integer type. If ty
is a vector floating-point
type, ty2
must be a vector integer type with the same number of elements as ty
Semantics:¶
The ‘fptoui
’ instruction converts its floating-point operand into the nearest (rounding towards zero) unsigned integer value. If the value cannot fit in ty2
,
the result is a poison value.
Example:¶
%X = fptoui double 123.0 to i32 ; yields i32:123 %Y = fptoui float 1.0E+300 to i1 ; yields undefined:1 %Z = fptoui float 1.04E+17 to i8 ; yields undefined:1
‘fptosi .. to
’
Instruction¶
Syntax:¶
<result> = fptosi <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘fptosi
’ instruction converts
floating-point value
to type ty2
.
Arguments:¶
The ‘fptosi
’ instruction takes a value to cast, which must be a scalar or vector floating-point value, and a type to cast it
to ty2
, which must be an integer type. If ty
is a vector floating-point type, ty2
must be a vector integer type with the same number of elements as ty
Semantics:¶
The ‘fptosi
’ instruction converts its
floating-point operand into the nearest (rounding towards zero) signed integer value. If the value cannot fit in ty2
, the result is a poison value.
Example:¶
%X = fptosi double -123.0 to i32 ; yields i32:-123 %Y = fptosi float 1.0E-247 to i1 ; yields undefined:1 %Z = fptosi float 1.04E+17 to i8 ; yields undefined:1
‘uitofp .. to
’ Instruction¶
Syntax:¶
<result> = uitofp <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘uitofp
’ instruction regards value
as an unsigned integer and converts that value to the ty2
type.
Arguments:¶
The ‘uitofp
’ instruction takes a value to cast, which must be a scalar or vector
integer value, and a type to cast it to ty2
, which must be an floating-point type. If ty
is a vector integer type, ty2
must be a vector floating-point type with the same number of elements as ty
Semantics:¶
The ‘uitofp
’ instruction interprets its operand as an unsigned integer quantity and converts it to the corresponding floating-point value. If the value cannot be exactly represented, it is rounded using the default rounding mode.
Example:¶
%X = uitofp i32 257 to float ; yields float:257.0 %Y = uitofp i8 -1 to double ; yields double:255.0
‘sitofp .. to
’ Instruction¶
Syntax:¶
<result> = sitofp <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘sitofp
’ instruction regards value
as a signed integer and converts that value to the ty2
type.
Arguments:¶
The ‘sitofp
’ instruction takes a value to cast, which must be a scalar or vector
integer value, and a type to cast it to ty2
, which must be an floating-point type. If ty
is a vector integer type, ty2
must be a vector floating-point type with the same number of elements as ty
Semantics:¶
The ‘sitofp
’ instruction interprets its operand as a signed integer quantity and converts it to the corresponding floating-point value. If the value cannot be exactly represented, it is rounded using the default rounding mode.
Example:¶
%X = sitofp i32 257 to float ; yields float:257.0 %Y = sitofp i8 -1 to double ; yields double:-1.0
‘ptrtoint .. to
’ Instruction¶
Syntax:¶
<result> = ptrtoint <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘ptrtoint
’ instruction converts the pointer or a vector of pointers value
to the integer (or vector of integers) type ty2
.
Arguments:¶
The ‘ptrtoint
’ instruction takes a value
to cast, which must be a value of type pointer or a
vector of pointers, and a type to cast it to ty2
, which must be an integer or a vector of integers type.
Semantics:¶
The ‘ptrtoint
’ instruction converts value
to integer type ty2
by interpreting the pointer value as an integer and either truncating or zero
extending that value to the size of the integer type. If value
is smaller than ty2
then a zero extension is done. If value
is larger than ty2
then a truncation is done. If they are the same size, then nothing is done (no-op cast) other than a type change.
Example:¶
%X = ptrtoint ptr %P to i8 ; yields truncation on 32-bit architecture %Y = ptrtoint ptr %P to i64 ; yields zero extension on 32-bit architecture %Z = ptrtoint <4 x ptr> %P to <4 x i64>; yields vector zero extension for a vector of addresses on 32-bit architecture
‘inttoptr .. to
’ Instruction¶
Syntax:¶
<result> = inttoptr <ty> <value> to <ty2>[, !dereferenceable !<deref_bytes_node>][, !dereferenceable_or_null !<deref_bytes_node>] ; yields ty2
Overview:¶
The ‘inttoptr
’ instruction converts an integer value
to a pointer type, ty2
.
Arguments:¶
The ‘inttoptr
’ instruction takes an integer value to cast, and a type to cast it to, which must be a
pointer type.
The optional !dereferenceable
metadata must reference a single metadata name <deref_bytes_node>
corresponding to a metadata node with one i64
entry. See dereferenceable
metadata.
The optional !dereferenceable_or_null
metadata must reference a single metadata name <deref_bytes_node>
corresponding to a metadata node with one i64
entry. See dereferenceable_or_null
metadata.
Semantics:¶
The ‘inttoptr
’ instruction converts value
to type ty2
by applying either a zero extension or a truncation depending on the size of the integer value
. If value
is larger than the size of a pointer then a truncation is done. If value
is smaller than the size of a pointer then a zero extension is done. If they are the same size, nothing is done (no-op cast).
Example:¶
%X = inttoptr i32 255 to ptr ; yields zero extension on 64-bit architecture %Y = inttoptr i32 255 to ptr ; yields no-op on 32-bit architecture %Z = inttoptr i64 0 to ptr ; yields truncation on 32-bit architecture %Z = inttoptr <4 x i32> %G to <4 x ptr>; yields truncation of vector G to four pointers
‘bitcast .. to
’ Instruction¶
Syntax:¶
<result> = bitcast <ty> <value> to <ty2> ; yields ty2
Overview:¶
The ‘bitcast
’ instruction converts value
to type ty2
without changing any bits.
Arguments:¶
The ‘bitcast
’ instruction takes a value to cast, which must be a non-aggregate first class value, and a type to cast it to, which must also be a non-aggregate first class type. The bit sizes of value
and the destination type, ty2
, must be identical. If the source type is a pointer, the
destination type must also be a pointer of the same size. This instruction supports bitwise conversion of vectors to integers and to vectors of other types (as long as they have the same size).
Semantics:¶
The ‘bitcast
’ instruction converts value
to type ty2
. It is always a no-op cast because no bits change with this conversion. The
conversion is done as if the value
had been stored to memory and read back as type ty2
. Pointer (or vector of pointers) types may only be converted to other pointer (or vector of pointers) types with the same address space through this instruction. To convert pointers to other types, use the inttoptr or ptrtoint
instructions first.
There is a caveat for bitcasts involving vector types in relation to endianess. For example bitcast <2 x i8> <value> to i16
puts element zero of the vector in the least significant bits of the i16 for little-endian while element zero ends up in the most significant bits for big-endian.
Example:¶
%X = bitcast i8 255 to i8 ; yields i8 :-1 %Y = bitcast i32* %x to i16* ; yields i16*:%x %Z = bitcast <2 x i32> %V to i64; ; yields i64: %V (depends on endianess) %Z = bitcast <2 x i32*> %V to <2 x i64*> ; yields <2 x i64*>
‘addrspacecast .. to
’ Instruction¶
Syntax:¶
<result> = addrspacecast <pty> <ptrval> to <pty2> ; yields pty2
Overview:¶
The ‘addrspacecast
’ instruction converts ptrval
from pty
in address space n
to type pty2
in address space m
.
Arguments:¶
The ‘addrspacecast
’ instruction takes a pointer or vector of pointer value to cast and a pointer type to cast
it to, which must have a different address space.
Semantics:¶
The ‘addrspacecast
’ instruction converts the pointer value ptrval
to type pty2
. It can be a no-op cast or a complex value modification, depending on the target and the address space pair. Pointer conversions within the same address space must be performed with the bitcast
instruction.
Note that if the address space conversion produces a dereferenceable result then both result and operand refer to the same memory location. The conversion must have no side effects, and must not capture the value of the pointer.
If the source is poison, the result is poison.
If the source is not poison, and both source and destination are integral pointers, and the result pointer is dereferenceable, the cast is assumed to be reversible (i.e. casting the result back to the original address space should yield the original bit pattern).
Example:¶
%X = addrspacecast ptr %x to ptr addrspace(1) %Y = addrspacecast ptr addrspace(1) %y to ptr addrspace(2) %Z = addrspacecast <4 x ptr> %z to <4 x ptr addrspace(3)>
Other Operations¶
The instructions in this category are the “miscellaneous” instructions, which defy better classification.
‘icmp
’ Instruction¶
Syntax:¶
<result> = icmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
Overview:¶
The ‘icmp
’ instruction returns a boolean value or a vector of boolean values based on comparison of its two integer, integer vector, pointer, or pointer vector operands.
Arguments:¶
The ‘icmp
’ instruction takes three operands. The first
operand is the condition code indicating the kind of comparison to perform. It is not a value, just a keyword. The possible condition codes are:
eq
: equalne
: not equalugt
: unsigned greater thanuge
: unsigned greater or equalult
: unsigned less thanule
: unsigned less or equalsgt
: signed greater thansge
: signed greater or equalslt
: signed less thansle
: signed less or equal
The remaining two arguments must be integer or pointer or integer vector typed. They must also be identical types.
Semantics:¶
The ‘icmp
’ compares op1
and op2
according to the condition code given as cond
. The comparison performed always yields either an i1 or vector of i1
result, as follows:
eq
: yieldstrue
if the operands are equal,false
otherwise. No sign interpretation is necessary or performed.ne
: yieldstrue
if the operands are unequal,false
otherwise. No sign interpretation is necessary or performed.ugt
: interprets the operands as unsigned values and yieldstrue
ifop1
is greater thanop2
.uge
: interprets the operands as unsigned values and yieldstrue
ifop1
is greater than or equal toop2
.ult
: interprets the operands as unsigned values and yieldstrue
ifop1
is less thanop2
.ule
: interprets the operands as unsigned values and yieldstrue
ifop1
is less than or equal toop2
.sgt
: interprets the operands as signed values and yieldstrue
ifop1
is greater thanop2
.sge
: interprets the operands as signed values and yieldstrue
ifop1
is greater than or equal toop2
.slt
: interprets the operands as signed values and yieldstrue
ifop1
is less thanop2
.sle
: interprets the operands as signed values and yieldstrue
ifop1
is less than or equal toop2
.
If the operands are pointer typed, the pointer values are compared as if they were integers.
If the operands are integer vectors, then they are compared element by element. The result is an i1
vector with the same number of elements as the values being compared. Otherwise, the result is an i1
.
Example:¶
<result> = icmp eq i32 4, 5 ; yields: result=false <result> = icmp ne ptr %X, %X ; yields: result=false <result> = icmp ult i16 4, 5 ; yields: result=true <result> = icmp sgt i16 4, 5 ; yields: result=false <result> = icmp ule i16 -4, 5 ; yields: result=false <result> = icmp sge i16 4, 5 ; yields: result=false
‘fcmp
’
Instruction¶
Syntax:¶
<result> = fcmp [fast-math flags]* <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
Overview:¶
The ‘fcmp
’ instruction returns a boolean value or
vector of boolean values based on comparison of its operands.
If the operands are floating-point scalars, then the result type is a boolean (i1).
If the operands are floating-point vectors, then the result type is a vector of boolean with the same number of elements as the operands being compared.
Arguments:¶
The ‘fcmp
’ instruction takes three operands. The first operand is the condition code indicating the kind of comparison to perform. It is not a value, just a keyword. The possible condition codes are:
false
: no comparison, always returns falseoeq
: ordered and equalogt
: ordered and greater thanoge
: ordered and greater than or equalolt
: ordered and less thanole
: ordered and less than or equalone
: ordered and not equalord
: ordered (no nans)ueq
: unordered or equalugt
: unordered or greater thanuge
: unordered or greater than or equalult
: unordered or less thanule
: unordered or less than or equalune
: unordered or not equaluno
: unordered (either nans)true
: no comparison, always returns true
Ordered means that neither operand is a QNAN while unordered means that either operand may be a QNAN.
Each of val1
and val2
arguments must be either a floating-point type or a vector of floating-point type. They must have identical types.
Semantics:¶
The ‘fcmp
’ instruction compares op1
and op2
according to the condition code given as cond
. If the operands are vectors, then the vectors are compared element by element. Each comparison performed always yields an i1 result, as follows:
false
: always yieldsfalse
, regardless of operands.oeq
: yieldstrue
if both operands are not a QNAN andop1
is equal toop2
.ogt
: yieldstrue
if both operands are not a QNAN andop1
is greater thanop2
.oge
: yieldstrue
if both operands are not a QNAN andop1
is greater than or equal toop2
.olt
: yieldstrue
if both operands are not a QNAN andop1
is less thanop2
.ole
: yieldstrue
if both operands are not a QNAN andop1
is less than or equal toop2
.one
: yieldstrue
if both operands are not a QNAN andop1
is not equal toop2
.ord
: yieldstrue
if both operands are not a QNAN.ueq
: yieldstrue
if either operand is a QNAN orop1
is equal toop2
.ugt
: yieldstrue
if either operand is a QNAN orop1
is greater thanop2
.uge
: yieldstrue
if either operand is a QNAN orop1
is greater than or equal toop2
.ult
: yieldstrue
if either operand is a QNAN orop1
is less thanop2
.ule
: yieldstrue
if either operand is a QNAN orop1
is less than or equal toop2
.une
: yieldstrue
if either operand is a QNAN orop1
is not equal toop2
.uno
: yieldstrue
if either operand is a QNAN.true
: always yieldstrue
, regardless of operands.
The fcmp
instruction can also optionally take any number of fast-math flags, which are optimization hints to enable otherwise unsafe floating-point optimizations.
Any set of fast-math flags are legal on an fcmp
instruction, but the only flags that have any effect on its semantics are those that allow assumptions to be made about
the values of input arguments; namely nnan
, ninf
, and reassoc
. See Fast-Math Flags for more information.
Example:¶
<result> = fcmp oeq float 4.0, 5.0 ; yields: result=false <result> = fcmp one float 4.0, 5.0 ; yields: result=true <result> = fcmp olt float 4.0, 5.0 ; yields: result=true <result> = fcmp ueq double 1.0, 2.0 ; yields: result=false
‘phi
’
Instruction¶
Syntax:¶
<result> = phi [fast-math-flags] <ty> [ <val0>, <label0>], ...
Overview:¶
The ‘phi
’ instruction is used to implement the φ
node in the SSA graph representing the function.
Arguments:¶
The type of the incoming values is specified with the first type field. After this, the ‘phi
’ instruction takes a list of pairs as arguments, with one pair for each predecessor basic block of the current block. Only values of
first class type may be used as the value arguments to the PHI node. Only labels may be used as the label arguments.
There must be no non-phi instructions between the start of a basic block and the PHI instructions: i.e. PHI instructions must be first in a basic block.
For the purposes of the SSA form, the use of each incoming value is deemed to occur on the edge from the corresponding
predecessor block to the current block (but after any definition of an ‘invoke
’ instruction’s return value on the same edge).
The optional fast-math-flags
marker indicates that the phi has one or more fast-math-flags. These are optimization hints to enable otherwise unsafe floating-point optimizations. Fast-math-flags are only valid for phis that return a floating-point scalar or vector type, or an array
(nested to any depth) of floating-point scalar or vector types.
Semantics:¶
At runtime, the ‘phi
’ instruction logically takes on the value specified by the pair corresponding to the predecessor basic block that executed just prior to the current block.
Example:¶
Loop: ; Infinite loop that counts from 0 on up... %indvar = phi i32 [ 0, %LoopHeader ], [ %nextindvar, %Loop ] %nextindvar = add i32 %indvar, 1 br label %Loop
‘select
’ Instruction¶
Syntax:¶
<result> = select [fast-math flags] selty <cond>, <ty> <val1>, <ty> <val2> ; yields ty selty is either i1 or {<N x i1>}
Overview:¶
The ‘select
’ instruction is used to choose one value based on a condition, without IR-level branching.
Arguments:¶
The ‘select
’ instruction requires an ‘i1’ value or a vector of ‘i1’ values indicating the condition, and two values of the same first class type.
- The optional
fast-math flags
marker indicates that the select has one or more fast-math flags. These are optimization hints to enable otherwise unsafe floating-point optimizations. Fast-math flags are only valid for selects that return a floating-point scalar or vector type, or an array (nested to any depth) of floating-point scalar or vector types.
Semantics:¶
If the condition is an i1 and it evaluates to 1, the instruction returns the first value argument; otherwise, it returns the second value argument.
If the condition is a vector of i1, then the value arguments must be vectors of the same size, and the selection is done element by element.
If the condition is an i1 and the value arguments are vectors of the same size, then an entire vector is selected.
Example:¶
%X = select i1 true, i8 17, i8 42 ; yields i8:17
‘freeze
’ Instruction¶
Syntax:¶
<result> = freeze ty <val> ; yields ty:result
Overview:¶
The ‘freeze
’ instruction is used to stop propagation of undef and
poison values.
Arguments:¶
The ‘freeze
’ instruction takes a single argument.
Semantics:¶
If the argument is undef
or
poison
, ‘freeze
’ returns an arbitrary, but fixed, value of type ‘ty
’. Otherwise, this instruction is a no-op and returns the input argument. All uses of a value returned by the same ‘freeze
’ instruction are guaranteed to always observe the same value, while different ‘freeze
’ instructions may yield different values.
While undef
and poison
pointers can be frozen, the result is a non-dereferenceable pointer. See the
Pointer Aliasing Rules section for more information. If an aggregate value or vector is frozen, the operand is frozen element-wise. The padding of an aggregate isn’t considered, since it isn’t visible without storing it into memory and loading it with a different type.
Example:¶
%w = i32 undef %x = freeze i32 %w %y = add i32 %w, %w ; undef %z = add i32 %x, %x ; even number because all uses of %x observe ; the same value %x2 = freeze i32 %w %cmp = icmp eq i32 %x, %x2 ; can be true or false ; example with vectors %v = <2 x i32> <i32 undef, i32 poison> %a = extractelement <2 x i32> %v, i32 0 ; undef %b = extractelement <2 x i32> %v, i32 1 ; poison %add = add i32 %a, %a ; undef %v.fr = freeze <2 x i32> %v ; element-wise freeze %d = extractelement <2 x i32> %v.fr, i32 0 ; not undef %add.f = add i32 %d, %d ; even number ; branching on frozen value %poison = add nsw i1 %k, undef ; poison %c = freeze i1 %poison br i1 %c, label %foo, label %bar ; non-deterministic branch to %foo or %bar
‘call
’ Instruction¶
Syntax:¶
<result> = [tail | musttail | notail ] call [fast-math flags] [cconv] [ret attrs] [addrspace(<num>)] <ty>|<fnty> <fnptrval>(<function args>) [fn attrs] [ operand bundles ]
Overview:¶
The ‘call
’ instruction represents a simple function call.
Arguments:¶
This instruction requires several arguments:
The optional
tail
andmusttail
markers indicate that the optimizers should perform tail call optimization. Thetail
marker is a hint that can be ignored. Themusttail
marker means that the call must be tail call optimized in order for the program to be correct. This is true even in the presence of attributes like “disable-tail-calls”. Themusttail
marker provides these guarantees:- The call will not cause unbounded stack growth if it is part of a recursive cycle in the call graph.
- Arguments with the inalloca or preallocated attribute are forwarded in place.
- If the musttail call appears in a function with the
"thunk"
attribute and the caller and callee both have varargs, than any unprototyped arguments in register or memory are forwarded to the callee. Similarly, the return value of the callee is returned to the caller’s caller, even if a void return type is in use.
Both markers imply that the callee does not access allocas from the caller. The
tail
marker additionally implies that the callee does not access varargs from the caller. Calls markedmusttail
must obey the following additional rules:- The call must immediately precede a ret instruction, or a pointer bitcast followed by a ret instruction.
- The ret instruction must return the (possibly bitcasted) value produced by the call, undef, or void.
- The calling conventions of the caller and callee must match.
- The callee must be varargs iff the caller is varargs. Bitcasting a non-varargs function to the appropriate varargs type is legal so long as the non-varargs prefixes obey the other rules.
- The return type must not undergo automatic conversion to an sret pointer.
In addition, if the calling convention is not swifttailcc or tailcc:
- All ABI-impacting function attributes, such as sret, byval, inreg, returned, and inalloca, must match.
- The caller and callee prototypes must match. Pointer types of parameters or return types may differ in pointee type, but not in address space.
On the other hand, if the calling convention is swifttailcc or swiftcc:
- Only these ABI-impacting attributes attributes are allowed: sret, byval, swiftself, and swiftasync.
- Prototypes are not required to match.
Tail call optimization for calls marked
tail
is guaranteed to occur if the following conditions are met:
- Caller and callee both have the calling convention
fastcc
ortailcc
.- The call is in tail position (ret immediately follows call and ret uses value of call or is void).
- Option
-tailcallopt
is enabled,llvm::GuaranteedTailCallOpt
istrue
, or the calling convention istailcc
- Platform-specific constraints are met.
- The optional
notail
marker indicates that the optimizers should not addtail
ormusttail
markers to the call. It is used to prevent tail call optimization from being performed on the call. - The optional
fast-math flags
marker indicates that the call has one or more fast-math flags, which are optimization hints to enable otherwise unsafe floating-point optimizations. Fast-math flags are only valid for calls that return a floating-point scalar or vector type, or an array (nested to any depth) of floating-point scalar or vector types. - The optional “cconv” marker indicates which calling convention the call should use. If none is specified, the call defaults to using C calling conventions. The calling convention of the call must match the calling convention of the target function, or else the behavior is undefined.
- The optional Parameter Attributes list for return values. Only ‘
zeroext
’, ‘signext
’, and ‘inreg
’ attributes are valid here. - The optional addrspace attribute can be used to indicate the address space of the called function. If it is not specified, the program address space from the datalayout string will be used.
- ‘
ty
’: the type of the call instruction itself which is also the type of the return value. Functions that return no value are markedvoid
. - ‘
fnty
’: shall be the signature of the function being called. The argument types must match the types implied by this signature. This type can be omitted if the function is not varargs. - ‘
fnptrval
’: An LLVM value containing a pointer to a function to be called. In most cases, this is a direct function call, but indirectcall
’s are just as possible, calling an arbitrary pointer to function value. - ‘
function args
’: argument list whose types match the function signature argument types and parameter attributes. All arguments must be of first class type. If the function signature indicates the function accepts a variable number of arguments, the extra arguments can be specified. - The optional function attributes list.
- The optional operand bundles list.
Semantics:¶
The ‘call
’ instruction is used to cause control flow to transfer to a specified
function, with its incoming arguments bound to the specified values. Upon a ‘ret
’ instruction in the called function, control flow continues with the instruction after the function call, and the return value of the function is bound to the result argument.
Example:¶
%retval = call i32 @test(i32 %argc) call i32 (ptr, ...) @printf(ptr %msg, i32 12, i8 42) ; yields i32 %X = tail call i32 @foo() ; yields i32 %Y = tail call fastcc i32 @foo() ; yields i32 call void %foo(i8 signext 97) %struct.A = type { i32, i8 } %r = call %struct.A @foo() ; yields { i32, i8 } %gr = extractvalue %struct.A %r, 0 ; yields i32 %gr1 = extractvalue %struct.A %r, 1 ; yields i8 %Z = call void @foo() noreturn ; indicates that %foo never returns normally %ZZ = call zeroext i32 @bar() ; Return value is %zero extended
llvm treats calls to some functions with names and arguments that match the standard C99 library as being the C99 library functions, and may perform optimizations or generate code for them under that assumption. This is something we’d like to change in the future to provide better support for freestanding environments and non-C-based languages.
‘va_arg
’
Instruction¶
Syntax:¶
<resultval> = va_arg <va_list*> <arglist>, <argty>
Overview:¶
The ‘va_arg
’ instruction is used to access
arguments passed through the “variable argument” area of a function call. It is used to implement the va_arg
macro in C.
Arguments:¶
This instruction takes a va_list*
value and the type of the argument. It returns a value of the specified argument type and increments the va_list
to point to the next argument. The actual type of va_list
is target
specific.
Semantics:¶
The ‘va_arg
’ instruction loads an argument of the specified type from the specified va_list
and causes the va_list
to point to the next argument. For more information, see the variable argument handling Intrinsic Functions.
It is legal
for this instruction to be called in a function which does not take a variable number of arguments, for example, the vfprintf
function.
va_arg
is an LLVM instruction instead of an intrinsic function because it takes a type as an argument.
Example:¶
See the variable argument processing section.
Note that the code generator does not yet fully support va_arg on many targets. Also, it does not currently support va_arg with aggregate types on any target.
‘landingpad
’
Instruction¶
Syntax:¶
<resultval> = landingpad <resultty> <clause>+ <resultval> = landingpad <resultty> cleanup <clause>* <clause> := catch <type> <value> <clause> := filter <array constant type> <array constant>
Overview:¶
The ‘landingpad
’ instruction is used by
LLVM’s exception handling system to specify that a basic block is a landing pad — one where the exception lands, and corresponds to the code found in the catch
portion of a try
/catch
sequence. It defines values supplied by the personality function upon re-entry to the function. The resultval
has the type
resultty
.
Arguments:¶
The optional cleanup
flag indicates that the landing pad block is a cleanup.
A clause
begins with the clause type — catch
or filter
— and contains the global variable representing the “type” that may be caught or filtered respectively. Unlike the catch
clause, the filter
clause takes an
array constant as its argument. Use “[0 x ptr] undef
” for a filter which cannot throw. The ‘landingpad
’ instruction must contain at least one clause
or the cleanup
flag.
Semantics:¶
The ‘landingpad
’ instruction defines the values which are set by the personality
function upon re-entry to the function, and therefore the “result type” of the landingpad
instruction. As with calling conventions, how the personality function results are represented in LLVM IR is target specific.
The clauses are applied in order from top to bottom. If two landingpad
instructions are merged together through inlining, the clauses from the calling function are appended to the list of clauses. When the call stack is being unwound due to an exception being thrown, the
exception is compared against each clause
in turn. If it doesn’t match any of the clauses, and the cleanup
flag is not set, then unwinding continues further up the call stack.
The landingpad
instruction has several restrictions:
- A landing pad block is a basic block which is the unwind destination of an ‘
invoke
’ instruction. - A landing pad block must have a ‘
landingpad
’ instruction as its first non-PHI instruction. - There can be only one ‘
landingpad
’ instruction within the landing pad block. - A basic block that is not a landing pad block may not include a ‘
landingpad
’ instruction.
Example:¶
;; A landing pad which can catch an integer. %res = landingpad { ptr, i32 } catch ptr @_ZTIi ;; A landing pad that is a cleanup. %res = landingpad { ptr, i32 } cleanup ;; A landing pad which can catch an integer and can only throw a double. %res = landingpad { ptr, i32 } catch ptr @_ZTIi filter [1 x ptr] [ptr @_ZTId]
‘catchpad
’
Instruction¶
Syntax:¶
<resultval> = catchpad within <catchswitch> [<args>*]
Overview:¶
The ‘catchpad
’ instruction is used by
LLVM’s exception handling system to specify that a basic block begins a catch handler — one where a personality routine attempts to transfer control to catch an exception.
Arguments:¶
The catchswitch
operand must always be a token produced by a
catchswitch instruction in a predecessor block. This ensures that each catchpad
has exactly one predecessor block, and it always terminates in a catchswitch
.
The args
correspond to whatever information the personality routine requires to know if this is an appropriate handler for the exception. Control will transfer to the catchpad
if this is the first appropriate handler for the exception.
The
resultval
has the type token and is used to match the catchpad
to corresponding catchrets and other nested EH pads.
Semantics:¶
When the call stack is being unwound due to an exception
being thrown, the exception is compared against the args
. If it doesn’t match, control will not reach the catchpad
instruction. The representation of args
is entirely target and personality function-specific.
Like the landingpad instruction, the catchpad
instruction must be the first non-phi of its parent basic block.
The meaning of the tokens produced and consumed by catchpad
and other
“pad” instructions is described in the Windows exception handling documentation.
When a catchpad
has been “entered” but not yet “exited” (as described in the EH documentation), it is undefined behavior to execute a call or
invoke that does not carry an appropriate “funclet” bundle.
Example:¶
dispatch: %cs = catchswitch within none [label %handler0] unwind to caller ;; A catch block which can catch an integer. handler0: %tok = catchpad within %cs [ptr @_ZTIi]
‘cleanuppad
’ Instruction¶
Syntax:¶
<resultval> = cleanuppad within <parent> [<args>*]
Overview:¶
The ‘cleanuppad
’ instruction is used by LLVM’s exception handling system to specify that a basic block is a cleanup block — one where a personality routine attempts to transfer control to run cleanup actions. The args
correspond to whatever additional information the personality function
requires to execute the cleanup. The resultval
has the type token and is used to match the cleanuppad
to corresponding cleanuprets. The parent
argument is the token of the funclet that contains the cleanuppad
instruction. If the cleanuppad
is not inside a funclet, this operand may be the token none
.
Arguments:¶
The instruction takes a list of arbitrary values which are interpreted by the personality function.
Semantics:¶
When the call
stack is being unwound due to an exception being thrown, the personality function transfers control to the cleanuppad
with the aid of the personality-specific arguments. As with calling conventions, how the personality function results are represented in LLVM IR is target specific.
The cleanuppad
instruction has several restrictions:
- A cleanup block is a basic block which is the unwind destination of an exceptional instruction.
- A cleanup block must have a ‘
cleanuppad
’ instruction as its first non-PHI instruction. - There can be only one ‘
cleanuppad
’ instruction within the cleanup block. - A basic block that is not a cleanup block may not include a ‘
cleanuppad
’ instruction.
When a cleanuppad
has been “entered” but not yet “exited” (as described in the EH
documentation), it is undefined behavior to execute a call or invoke that does not carry an appropriate “funclet” bundle.
Example:¶
%tok = cleanuppad within %cs []
Intrinsic Functions¶
LLVM supports the notion of an “intrinsic function”. These functions have well known names and semantics and are required to follow certain restrictions. Overall, these intrinsics represent an extension mechanism for the LLVM language that does not require changing all of the transformations in LLVM when adding to the language (or the bitcode reader/writer, the parser, etc…).
Intrinsic function names must all start with an “llvm.
” prefix. This prefix is reserved in LLVM for intrinsic names; thus, function names may not begin with this prefix. Intrinsic functions must always be
external functions: you cannot define the body of intrinsic functions. Intrinsic functions may only be used in call or invoke instructions: it is illegal to take the address of an intrinsic function. Additionally, because intrinsic functions are part of the LLVM language, it is required if any are added that they be documented here.
Some intrinsic functions can be overloaded, i.e., the intrinsic represents a family of functions that perform the same operation but on different data types. Because LLVM can represent over 8 million different integer types, overloading is used commonly to allow an intrinsic function to operate on any integer type. One or more of the argument types or the result type can be overloaded to accept any integer type. Argument types may also be defined as exactly matching a previous argument’s type or the result type. This allows an intrinsic function which accepts multiple arguments, but needs all of them to be of the same type, to only be overloaded with respect to a single argument or the result.
Overloaded intrinsics will have the names of its overloaded argument types encoded into its function name, each preceded by a period. Only those types which are overloaded result in a name suffix. Arguments whose type is matched against another type do not. For example, the llvm.ctpop
function can take an integer of any width and returns an integer of exactly the same integer width. This leads to a family of functions such as i8 @llvm.ctpop.i8(i8 %val)
and i29 @llvm.ctpop.i29(i29 %val)
.
Only one type, the return type, is overloaded, and only one type suffix is required. Because the argument’s type is matched against the return type, it does not require its own name suffix.
Unnamed types are encoded as s_s
. Overloaded intrinsics that depend on an unnamed type in one of its overloaded argument types get an additional .<number>
suffix. This allows differentiating intrinsics with
different unnamed types as arguments. (For example: llvm.ssa.copy.p0s_s.2(%42*)
) The number is tracked in the LLVM module and it ensures unique names in the module. While linking together two modules, it is still possible to get a name clash. In that case one of the names will be changed by getting a new number.
For target developers who are defining intrinsics for back-end code generation, any intrinsic overloads based solely the distinction between integer or floating point types should not be relied upon
for correct code generation. In such cases, the recommended approach for target maintainers when defining intrinsics is to create separate integer and FP intrinsics rather than rely on overloading. For example, if different codegen is required for llvm.target.foo(<4 x i32>)
and llvm.target.foo(<4 x float>)
then these should be split into different intrinsics.
To learn how to add an intrinsic function, please see the Extending LLVM Guide.
Variable Argument Handling Intrinsics¶
Variable argument support is defined in LLVM with the va_arg instruction and these three intrinsic functions.
These functions are related to the similarly named macros defined in the <stdarg.h>
header file.
All of these functions operate on arguments that use a target-specific value type “va_list
”. The LLVM assembly language reference manual does not define what this type is, so all transformations should be prepared to handle these functions regardless of the type used.
This example shows how the va_arg instruction and the variable argument handling intrinsic functions are used.
; This struct is different for every platform. For most platforms, ; it is merely a ptr. %struct.va_list = type { ptr } ; For Unix x86_64 platforms, va_list is the following struct: ; %struct.va_list = type { i32, i32, ptr, ptr } define i32 @test(i32 %X, ...) { ; Initialize variable argument processing %ap = alloca %struct.va_list call void @llvm.va_start(ptr %ap) ; Read a single integer argument %tmp = va_arg ptr %ap, i32 ; Demonstrate usage of llvm.va_copy and llvm.va_end %aq = alloca ptr call void @llvm.va_copy(ptr %aq, ptr %ap) call void @llvm.va_end(ptr %aq) ; Stop processing of arguments. call void @llvm.va_end(ptr %ap) ret i32 %tmp } declare void @llvm.va_start(ptr) declare void @llvm.va_copy(ptr, ptr) declare void @llvm.va_end(ptr)
‘llvm.va_start
’ Intrinsic¶
Syntax:¶
declare void @llvm.va_start(ptr <arglist>)
Overview:¶
The ‘llvm.va_start
’ intrinsic initializes <arglist>
for subsequent use by va_arg
.
Arguments:¶
The argument is a pointer to a va_list
element to initialize.
Semantics:¶
The ‘llvm.va_start
’ intrinsic works just like the va_start
macro available in C. In a target-dependent way, it initializes the va_list
element to which the argument points, so that the next call to va_arg
will produce the first variable argument passed to the function. Unlike the C va_start
macro, this intrinsic does not need to know the last argument of the function as the compiler can
figure that out.
‘llvm.va_end
’ Intrinsic¶
Syntax:¶
declare void @llvm.va_end(ptr <arglist>)
Overview:¶
The ‘llvm.va_end
’ intrinsic destroys <arglist>
, which has been initialized previously with llvm.va_start
or llvm.va_copy
.
Arguments:¶
The argument is a pointer to a va_list
to destroy.
Semantics:¶
The ‘llvm.va_end
’ intrinsic works just like the va_end
macro available in C. In a target-dependent way, it destroys the va_list
element to which the argument points. Calls to llvm.va_start and llvm.va_copy
must be matched exactly with calls to llvm.va_end
.
‘llvm.va_copy
’ Intrinsic¶
Syntax:¶
declare void @llvm.va_copy(ptr <destarglist>, ptr <srcarglist>)
Overview:¶
The ‘llvm.va_copy
’ intrinsic copies the current argument position from the source argument list to the destination argument list.
Arguments:¶
The first argument is a pointer to a va_list
element to initialize. The second argument is
a pointer to a va_list
element to copy from.
Semantics:¶
The ‘llvm.va_copy
’ intrinsic works just like the va_copy
macro available in C. In a target-dependent way, it copies the source va_list
element into the destination va_list
element. This intrinsic is necessary because the `` llvm.va_start`` intrinsic may be arbitrarily complex and require, for
example, memory allocation.
Accurate Garbage Collection Intrinsics¶
LLVM’s support for Accurate Garbage Collection (GC) requires the frontend to generate code containing appropriate intrinsic calls and select an appropriate GC strategy which knows how to lower these intrinsics in a manner which is appropriate for the target collector.
These intrinsics allow identification of GC roots on the stack, as well as garbage collector implementations that require read and write barriers. Frontends for type-safe garbage collected languages should generate these intrinsics to make use of the LLVM garbage collectors. For more details, see Garbage Collection with LLVM.
LLVM provides an second
experimental set of intrinsics for describing garbage collection safepoints in compiled code. These intrinsics are an alternative to the llvm.gcroot
intrinsics, but are compatible with the ones for read and write barriers. The differences in approach are covered in the
Garbage Collection with LLVM documentation. The intrinsics themselves are described in Garbage Collection Safepoints in LLVM.
‘llvm.gcroot
’
Intrinsic¶
Syntax:¶
declare void @llvm.gcroot(ptr %ptrloc, ptr %metadata)
Overview:¶
The ‘llvm.gcroot
’ intrinsic declares the existence of a
GC root to the code generator, and allows some metadata to be associated with it.
Arguments:¶
The first argument specifies the address of a stack object that contains the root pointer. The second pointer (which must be either a constant or a global value address) contains the meta-data to be associated with the root.
Semantics:¶
At runtime, a call to this intrinsic stores a null pointer into the “ptrloc” location. At compile-time, the code generator generates information to allow the runtime to find the pointer at GC safe points. The ‘llvm.gcroot
’ intrinsic may only be used in a function which specifies a GC algorithm.
‘llvm.gcread
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.gcread(ptr %ObjPtr, ptr %Ptr)
Overview:¶
The ‘llvm.gcread
’ intrinsic identifies reads of references from heap locations, allowing garbage collector implementations that require read barriers.
Arguments:¶
The second argument is the address to read from, which should be an address allocated from the garbage collector. The first object is a pointer to the start of the referenced object, if needed by the language runtime (otherwise null).
Semantics:¶
The ‘llvm.gcread
’ intrinsic has the same semantics as a load instruction, but may be replaced with substantially more complex code by the garbage collector runtime, as needed. The ‘llvm.gcread
’ intrinsic
may only be used in a function which specifies a GC algorithm.
‘llvm.gcwrite
’ Intrinsic¶
Syntax:¶
declare void @llvm.gcwrite(ptr %P1, ptr %Obj, ptr %P2)
Overview:¶
The ‘llvm.gcwrite
’ intrinsic identifies writes of references to heap locations, allowing garbage collector implementations that require write barriers (such as generational or reference counting collectors).
Arguments:¶
The first argument is the reference to store, the second is the start of the object to store it to, and the third is the address of the field of Obj to store to. If the runtime does not require a pointer to the object, Obj may be null.
Semantics:¶
The ‘llvm.gcwrite
’ intrinsic has the same semantics as a store instruction, but may be replaced with substantially more complex code by the garbage collector runtime, as needed. The ‘llvm.gcwrite
’ intrinsic may only be used in a function which specifies a GC algorithm.
‘llvm.experimental.gc.statepoint
’ Intrinsic¶
Syntax:¶
declare token @llvm.experimental.gc.statepoint(i64 <id>, i32 <num patch bytes>, ptr elementtype(func_type) <target>, i64 <#call args>, i64 <flags>, ... (call parameters), i64 0, i64 0)
Overview:¶
The statepoint intrinsic represents a call which is parse-able by the runtime.
Operands:¶
The ‘id’ operand is a constant integer that is reported as the ID field in the generated stackmap. LLVM does not interpret this parameter in any way and its meaning is up to the statepoint user to decide. Note that LLVM is free to duplicate code containing statepoint calls, and this may transform IR that had a unique ‘id’ per lexical call to statepoint to IR that does not.
If ‘num patch bytes’ is non-zero then the call instruction corresponding to the statepoint is not emitted and LLVM emits ‘num patch bytes’ bytes of nops in its place. LLVM will emit code to prepare the function arguments and retrieve the function return value in accordance to the calling convention; the former before the nop sequence and the latter after the nop sequence. It is expected that the user will patch over the ‘num patch bytes’ bytes of nops with a calling sequence specific to their runtime before executing the generated machine code. There are no guarantees with respect to the alignment of the nop sequence. Unlike Stack maps and patch points in LLVM statepoints do not have a concept of shadow bytes. Note that semantically the statepoint still represents a call or invoke to ‘target’, and the nop sequence after patching is expected to represent an operation equivalent to a call or invoke to ‘target’.
The ‘target’ operand is the function actually being called. The operand must have an elementtype attribute specifying the function type of the target. The target can be specified as either a symbolic LLVM function, or as an arbitrary Value of pointer type. Note that the function type must match the signature of the callee and the types of the ‘call parameters’ arguments.
The ‘#call args’ operand is the number of arguments to the actual call. It must exactly match the number of arguments passed in the ‘call parameters’ variable length section.
The ‘flags’ operand is used to specify extra information about the statepoint. This is currently only used to mark certain statepoints as GC transitions. This operand is a 64-bit integer with the following layout, where bit 0 is the least significant bit:
Bit # Usage 0 Set if the statepoint is a GC transition, cleared otherwise. 1-63 Reserved for future use; must be cleared.
The ‘call parameters’ arguments are simply the arguments which need to be passed to the call target. They will be lowered according to the specified calling convention and otherwise handled like a normal call instruction. The number of arguments must exactly match what is specified in ‘# call args’. The types must match the signature of ‘target’.
The ‘call parameter’ attributes must be followed by two ‘i64 0’ constants. These were originally the length prefixes for ‘gc transition parameter’ and ‘deopt parameter’ arguments, but the role of these parameter sets have been entirely replaced with the corresponding operand bundles. In a future revision, these now redundant arguments will be removed.
Semantics:¶
A statepoint is assumed to read and write all memory. As a result, memory operations can not be reordered past a statepoint. It is illegal to mark a statepoint as being either ‘readonly’ or ‘readnone’.
Note that legal IR can not perform any memory operation on a ‘gc pointer’ argument of the statepoint in a location statically reachable from the statepoint. Instead, the explicitly relocated value (from a gc.relocate
) must be used.
‘llvm.experimental.gc.result
’
Intrinsic¶
Syntax:¶
declare type @llvm.experimental.gc.result(token %statepoint_token)
Overview:¶
gc.result
extracts the result of the
original call instruction which was replaced by the gc.statepoint
. The gc.result
intrinsic is actually a family of three intrinsics due to an implementation limitation. Other than the type of the return value, the semantics are the same.
Operands:¶
The first and only argument is the gc.statepoint
which starts the safepoint sequence of which this gc.result
is a part.
Despite the typing of this as a generic token, only the value defined by a gc.statepoint
is legal here.
Semantics:¶
The gc.result
represents the return value of the call target of the statepoint
. The type of the gc.result
must exactly match the type of the target. If the call target returns void, there will be no gc.result
.
A gc.result
is modeled as a
‘readnone’ pure function. It has no side effects since it is just a projection of the return value of the previous call represented by the gc.statepoint
.
‘llvm.experimental.gc.relocate
’ Intrinsic¶
Syntax:¶
declare <pointer type> @llvm.experimental.gc.relocate(token %statepoint_token, i32 %base_offset, i32 %pointer_offset)
Overview:¶
A gc.relocate
returns the potentially relocated value of a pointer at the safepoint.
Operands:¶
The first argument is the gc.statepoint
which starts the safepoint sequence of which this gc.relocation
is a part. Despite the typing of this as a generic token, only the value defined by a gc.statepoint
is legal here.
The second and third arguments are both indices into operands of the corresponding statepoint’s gc-live operand bundle.
The second argument is an index which specifies the allocation for the pointer being relocated. The associated value must be within the object with which the pointer being relocated is associated. The optimizer is free to change which interior derived pointer is reported, provided that it does not replace an actual base pointer with another interior derived pointer. Collectors are allowed to rely on the base pointer operand remaining an actual base pointer if so constructed.
The third argument is an index which specify the (potentially) derived pointer being relocated. It is legal for this index to be the same as the second argument if-and-only-if a base pointer is being relocated.
Semantics:¶
The return value
of gc.relocate
is the potentially relocated value of the pointer specified by its arguments. It is unspecified how the value of the returned pointer relates to the argument to the gc.statepoint
other than that a) it points to the same source language object with the same offset, and b) the ‘based-on’ relationship of the newly relocated pointers is a projection of the unrelocated pointers. In particular, the integer value of the pointer returned is unspecified.
A gc.relocate
is modeled as a readnone
pure function. It has no side effects since it is just a way to extract information about work done during the actual call modeled by the gc.statepoint
.
‘llvm.experimental.gc.get.pointer.base
’ Intrinsic¶
Syntax:¶
declare <pointer type> @llvm.experimental.gc.get.pointer.base( <pointer type> readnone nocapture %derived_ptr) nounwind readnone willreturn
Overview:¶
gc.get.pointer.base
for a derived pointer returns its base pointer.
Operands:¶
The only argument is a pointer which is based on some object with an unknown offset from the base of said object.
Semantics:¶
This intrinsic is used in the abstract machine model for GC to represent the base pointer for an arbitrary derived pointer.
This intrinsic is inlined by the RewriteStatepointsForGC pass by replacing all uses of this callsite with the offset of a derived pointer from its base pointer value. The replacement is done as part of the lowering to the explicit statepoint model.
The return pointer type must be the same as the type of the parameter.
‘llvm.experimental.gc.get.pointer.offset
’ Intrinsic¶
Syntax:¶
declare i64 @llvm.experimental.gc.get.pointer.offset( <pointer type> readnone nocapture %derived_ptr) nounwind readnone willreturn
Overview:¶
gc.get.pointer.offset
for a derived pointer returns the offset from its base pointer.
Operands:¶
The only argument is a pointer which is based on some object with an unknown offset from the base of said object.
Semantics:¶
This intrinsic is used in the abstract machine model for GC to represent the offset of an arbitrary derived pointer from its base pointer.
This intrinsic is inlined by the RewriteStatepointsForGC pass by replacing all uses of this callsite with the offset of a derived pointer from its base pointer value. The replacement is done as part of the lowering to the explicit statepoint model.
Basically this call calculates difference between the derived pointer and its base pointer (see ‘llvm.experimental.gc.get.pointer.base’ Intrinsic) both ptrtoint casted. But this cast done outside the RewriteStatepointsForGC pass could result in the pointers lost for further lowering from the abstract model to the explicit physical one.
Code Generator Intrinsics¶
These intrinsics are provided by LLVM to expose special features that may only be implemented with code generator support.
‘llvm.returnaddress
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.returnaddress(i32 <level>)
Overview:¶
The ‘llvm.returnaddress
’ intrinsic attempts to compute a target-specific value indicating the return address of the current function or one of its callers.
Arguments:¶
The argument to this intrinsic indicates which function to return the address for. Zero indicates the calling function, one indicates its caller, etc. The argument is required to be a constant integer value.
Semantics:¶
The ‘llvm.returnaddress
’ intrinsic either returns a pointer indicating the return address of the specified call frame, or zero if it cannot be identified. The value returned by this intrinsic is likely to be incorrect or 0 for arguments other than zero, so it should only be used for debugging purposes.
Note that calling this intrinsic does not prevent function inlining or other aggressive transformations, so the value returned may not be that of the obvious source-language caller.
‘llvm.addressofreturnaddress
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.addressofreturnaddress()
Overview:¶
The ‘llvm.addressofreturnaddress
’ intrinsic returns a target-specific pointer to the place in the stack frame where the return address of the current function is stored.
Semantics:¶
Note that calling this intrinsic does not prevent function inlining or other aggressive transformations, so the value returned may not be that of the obvious source-language caller.
This intrinsic is only implemented for x86 and aarch64.
‘llvm.sponentry
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.sponentry()
Overview:¶
The ‘llvm.sponentry
’ intrinsic returns the stack pointer value at the entry of the current function calling this intrinsic.
Semantics:¶
Note this intrinsic is only verified on AArch64 and ARM.
‘llvm.frameaddress
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.frameaddress(i32 <level>)
Overview:¶
The ‘llvm.frameaddress
’ intrinsic attempts to return the target-specific frame pointer value for the specified stack frame.
Arguments:¶
The argument to this intrinsic indicates which function to return the frame pointer for. Zero indicates the calling function, one indicates its caller, etc. The argument is required to be a constant integer value.
Semantics:¶
The ‘llvm.frameaddress
’ intrinsic either returns a pointer indicating the frame address of
the specified call frame, or zero if it cannot be identified. The value returned by this intrinsic is likely to be incorrect or 0 for arguments other than zero, so it should only be used for debugging purposes.
Note that calling this intrinsic does not prevent function inlining or other aggressive transformations, so the value returned may not be that of the obvious source-language caller.
‘llvm.swift.async.context.addr
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.swift.async.context.addr()
Overview:¶
The ‘llvm.swift.async.context.addr
’ intrinsic returns a pointer to the part of the extended frame record containing the asynchronous context of a Swift execution.
Semantics:¶
If the caller has a swiftasync
parameter, that argument will initially be stored at the
returned address. If not, it will be initialized to null.
‘llvm.localescape
’ and ‘llvm.localrecover
’ Intrinsics¶
Syntax:¶
declare void @llvm.localescape(...) declare ptr @llvm.localrecover(ptr %func, ptr %fp, i32 %idx)
Overview:¶
The ‘llvm.localescape
’ intrinsic escapes offsets of a collection of static allocas, and the ‘llvm.localrecover
’ intrinsic applies those offsets to a live frame pointer to recover the address of the allocation. The offset is computed during
frame layout of the caller of llvm.localescape
.
Arguments:¶
All arguments to ‘llvm.localescape
’ must be pointers to static allocas or casts of static allocas. Each function can only call ‘llvm.localescape
’ once, and it can only do so from the entry block.
The func
argument to ‘llvm.localrecover
’ must be a constant bitcasted pointer to a function defined in the current module.
The code generator cannot determine the frame allocation offset of functions defined in other modules.
The fp
argument to ‘llvm.localrecover
’ must be a frame pointer of a call frame that is currently live. The return value of ‘llvm.localaddress
’ is one way to produce such a value, but various runtimes also expose a suitable pointer in platform-specific ways.
The idx
argument to ‘llvm.localrecover
’ indicates which alloca passed to ‘llvm.localescape
’ to recover. It is zero-indexed.
Semantics:¶
These intrinsics allow a group of functions to share access to a set of local stack allocations of a one parent function. The parent function may call the ‘llvm.localescape
’ intrinsic once from the function entry block, and the child functions can use ‘llvm.localrecover
’ to access the escaped allocas. The ‘llvm.localescape
’ intrinsic blocks inlining, as inlining changes where the escaped
allocas are allocated, which would break attempts to use ‘llvm.localrecover
’.
‘llvm.seh.try.begin
’ and ‘llvm.seh.try.end
’ Intrinsics¶
Syntax:¶
declare void @llvm.seh.try.begin() declare void @llvm.seh.try.end()
Overview:¶
The ‘llvm.seh.try.begin
’ and ‘llvm.seh.try.end
’ intrinsics mark the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
Semantics:¶
When a C-function is compiled with Windows SEH Asynchrous Exception option, -feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mark _try boundary and to prevent potential exceptions from being moved across boundary. Any set of operations can then be confined to the region by reading their leaf inputs via volatile loads and writing their root outputs via volatile stores.
‘llvm.seh.scope.begin
’ and ‘llvm.seh.scope.end
’ Intrinsics¶
Syntax:¶
declare void @llvm.seh.scope.begin() declare void @llvm.seh.scope.end()
Overview:¶
The ‘llvm.seh.scope.begin
’ and ‘llvm.seh.scope.end
’ intrinsics mark the boundary of a CPP object lifetime for Windows SEH Asynchrous Exception Handling (MSVC option -EHa).
Semantics:¶
LLVM’s ordinary exception-handling
representation associates EH cleanups and handlers only with invoke``s, which normally correspond only to call sites. To
support arbitrary faulting instructions, it must be possible to recover the current
EH scope for any instruction. Turning every operation in LLVM that could fault
into an ``invoke
of a new, potentially-throwing intrinsic would require adding a large number of intrinsics, impede optimization of those operations, and make compilation slower by introducing many extra basic blocks. These intrinsics can be used instead to mark the region protected by a cleanup, such as for a local C++ object with a non-trivial destructor. llvm.seh.scope.begin
is used to mark the start of the region; it is always called with invoke
,
with the unwind block being the desired unwind destination for any potentially-throwing instructions within the region. llvm.seh.scope.end is used to mark when the scope ends and the EH cleanup is no longer required (e.g. because the destructor is being called).
‘llvm.read_register
’, ‘llvm.read_volatile_register
’, and ‘llvm.write_register
’
Intrinsics¶
Syntax:¶
declare i32 @llvm.read_register.i32(metadata) declare i64 @llvm.read_register.i64(metadata) declare i32 @llvm.read_volatile_register.i32(metadata) declare i64 @llvm.read_volatile_register.i64(metadata) declare void @llvm.write_register.i32(metadata, i32 @value) declare void @llvm.write_register.i64(metadata, i64 @value) !0 = !{!"sp\00"}
Overview:¶
The ‘llvm.read_register
’, ‘llvm.read_volatile_register
’, and ‘llvm.write_register
’ intrinsics provide access to the named register. The register must be valid on the architecture being compiled to. The type needs to be compatible with the register being read.
Semantics:¶
The ‘llvm.read_register
’
and ‘llvm.read_volatile_register
’ intrinsics return the current value of the register, where possible. The ‘llvm.write_register
’ intrinsic sets the current value of the register, where possible.
A call to ‘llvm.read_volatile_register
’ is assumed to have side-effects and possibly return a different value each time (e.g. for a timer register).
This is useful to implement named register global variables that need to always be mapped to a specific register, as is common practice on bare-metal programs including OS kernels.
The compiler doesn’t check for register availability or use of the used register in surrounding code, including inline assembly. Because of that, allocatable registers are not supported.
Warning: So far it only works with the stack pointer on selected architectures (ARM, AArch64, PowerPC and x86_64). Significant amount of work is needed to support other registers and even more so, allocatable registers.
‘llvm.stacksave
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.stacksave()
Overview:¶
The ‘llvm.stacksave
’ intrinsic is used to remember the current state of the function stack, for use with llvm.stackrestore. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
Semantics:¶
This
intrinsic returns an opaque pointer value that can be passed to llvm.stackrestore. When an llvm.stackrestore
intrinsic is executed with a value saved from llvm.stacksave
, it effectively restores the state of the stack to the state it was in when the llvm.stacksave
intrinsic executed. In practice, this pops any alloca blocks from the
stack that were allocated after the llvm.stacksave
was executed.
‘llvm.stackrestore
’ Intrinsic¶
Syntax:¶
declare void @llvm.stackrestore(ptr %ptr)
Overview:¶
The ‘llvm.stackrestore
’ intrinsic is used to restore the state of the function stack to the state it was in when the corresponding llvm.stacksave intrinsic executed. This is useful for implementing language features like scoped automatic variable sized arrays in
C99.
‘llvm.get.dynamic.area.offset
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.get.dynamic.area.offset.i32() declare i64 @llvm.get.dynamic.area.offset.i64()
Overview:¶
The ‘
llvm.get.dynamic.area.offset.*
’ intrinsic family is used to get the offset from native stack pointer to the address of the most recent dynamic alloca on the caller’s stack. These intrinsics are intended for use in combination with llvm.stacksave to get a pointer to the most recent dynamic alloca. This is useful, for example, for AddressSanitizer’s stack unpoisoning routines.
Semantics:¶
These intrinsics return a non-negative integer value that can be used to get the address of the most recent dynamic alloca, allocated by alloca on the caller’s stack. In particular, for targets where stack grows downwards, adding this offset to the native stack pointer would get the address of the most recent dynamic alloca. For targets where stack grows upwards, the situation is a bit more complicated, because subtracting this value from stack pointer would get the address one past the end of the most recent dynamic alloca.
Although for most targets llvm.get.dynamic.area.offset <int_get_dynamic_area_offset> returns just a zero, for others, such as PowerPC and PowerPC64, it returns a compile-time-known constant value.
The return value type of llvm.get.dynamic.area.offset must match the target’s default address space’s (address space 0) pointer type.
‘llvm.prefetch
’ Intrinsic¶
Syntax:¶
declare void @llvm.prefetch(ptr <address>, i32 <rw>, i32 <locality>, i32 <cache type>)
Overview:¶
The ‘llvm.prefetch
’ intrinsic 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.
Arguments:¶
address
is the address to be prefetched, rw
is the specifier determining if the fetch should be for a read (0) or write (1), and locality
is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local keep in cache. The cache type
specifies whether the prefetch is performed on the data (1) or instruction (0) cache. The rw
, locality
and cache type
arguments must be constant integers.
Semantics:¶
This intrinsic does not modify the behavior of the program. In particular, prefetches cannot trap and do not produce a value. On targets that support this intrinsic, the prefetch can provide hints to the processor cache for better performance.
‘llvm.pcmarker
’
Intrinsic¶
Syntax:¶
declare void @llvm.pcmarker(i32 <id>)
Overview:¶
The ‘llvm.pcmarker
’ intrinsic is a method to export a
Program Counter (PC) in a region of code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. The marker makes no guarantees that it will remain with any specific instruction after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optimizations to allow correlations of simulation runs.
Arguments:¶
id
is a numerical id identifying the marker.
Semantics:¶
This intrinsic does not modify the behavior of the program. Backends that do not support this intrinsic may ignore it.
‘llvm.readcyclecounter
’ Intrinsic¶
Syntax:¶
declare i64 @llvm.readcyclecounter()
Overview:¶
The ‘llvm.readcyclecounter
’ intrinsic provides access to the cycle counter register (or similar low latency, high accuracy clocks) on those targets that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. As the backing counters overflow quickly (on the order of 9 seconds on alpha), this should only be used for small timings.
Semantics:¶
When directly supported, reading the cycle counter should not modify any memory. Implementations are allowed to either return an application specific value or a system wide value. On backends without support, this is lowered to a constant 0.
Note that runtime support may be conditional on the privilege-level code is running at and the host platform.
‘llvm.clear_cache
’ Intrinsic¶
Syntax:¶
declare void @llvm.clear_cache(ptr, ptr)
Overview:¶
The ‘llvm.clear_cache
’ intrinsic 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.
Semantics:¶
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 intrinsic is 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 run time library.
This intrinsic does not empty the instruction pipeline. Modifications of the current function are outside the scope of the intrinsic.
‘llvm.instrprof.increment
’ Intrinsic¶
Syntax:¶
declare void @llvm.instrprof.increment(ptr <name>, i64 <hash>, i32 <num-counters>, i32 <index>)
Overview:¶
The ‘llvm.instrprof.increment
’ intrinsic can be emitted by a frontend for use with instrumentation based profiling. These will be lowered by the -instrprof
pass to generate execution counts of a program at runtime.
Arguments:¶
The first argument is a pointer to a global variable containing the name of the entity being instrumented. This should generally be the (mangled) function name for a set of counters.
The second argument is a hash value that can be used by the consumer of the profile data to detect changes to the instrumented source, and the third is the number of counters associated with name
. It is an error if hash
or num-counters
differ between two instances of instrprof.increment
that refer to the same name.
The last argument
refers to which of the counters for name
should be incremented. It should be a value between 0 and num-counters
.
Semantics:¶
This intrinsic represents an increment of a profiling counter. It will cause the -instrprof
pass to generate the appropriate data structures and the code to increment the appropriate value, in a format that can be written out by a
compiler runtime and consumed via the llvm-profdata
tool.
‘llvm.instrprof.increment.step
’ Intrinsic¶
Syntax:¶
declare void @llvm.instrprof.increment.step(ptr <name>, i64 <hash>, i32 <num-counters>, i32 <index>, i64 <step>)
Overview:¶
The ‘llvm.instrprof.increment.step
’ intrinsic is an extension to the ‘llvm.instrprof.increment
’ intrinsic with an additional fifth argument to specify the step of the increment.
Arguments:¶
The first four arguments are the same
as ‘llvm.instrprof.increment
’ intrinsic.
The last argument specifies the value of the increment of the counter variable.
Semantics:¶
See description of ‘llvm.instrprof.increment
’ intrinsic.
‘llvm.instrprof.cover
’
Intrinsic¶
Syntax:¶
declare void @llvm.instrprof.cover(ptr <name>, i64 <hash>, i32 <num-counters>, i32 <index>)
Overview:¶
The ‘llvm.instrprof.cover
’ intrinsic is used to
implement coverage instrumentation.
Arguments:¶
The arguments are the same as the first four arguments of ‘llvm.instrprof.increment
’.
Semantics:¶
Similar to the ‘llvm.instrprof.increment
’ intrinsic, but it stores zero to the profiling variable to
signify that the function has been covered. We store zero because this is more efficient on some targets.
‘llvm.instrprof.value.profile
’ Intrinsic¶
Syntax:¶
declare void @llvm.instrprof.value.profile(ptr <name>, i64 <hash>, i64 <value>, i32 <value_kind>, i32 <index>)
Overview:¶
The ‘llvm.instrprof.value.profile
’ intrinsic can be emitted by a frontend for use with instrumentation based profiling. This will be lowered by the -instrprof
pass to find out the target values, instrumented expressions take in a program at
runtime.
Arguments:¶
The first argument is a pointer to a global variable containing the name of the entity being instrumented. name
should generally be the (mangled) function name for a set of counters.
The second argument is a hash value that can be used by the consumer of the profile data to detect changes to the instrumented source. It is an
error if hash
differs between two instances of llvm.instrprof.*
that refer to the same name.
The third argument is the value of the expression being profiled. The profiled expression’s value should be representable as an unsigned 64-bit value. The fourth argument represents the kind of value profiling that is being done. The supported value profiling kinds are enumerated through the InstrProfValueKind
type declared in the <include/llvm/ProfileData/InstrProf.h>
header file. The last argument is the index of the instrumented
expression within name
. It should be >= 0.
Semantics:¶
This intrinsic represents the point where a call to a runtime routine should be inserted for value profiling of target expressions. -instrprof
pass will generate the appropriate data structures and replace the llvm.instrprof.value.profile
intrinsic with the call to the profile runtime library with proper arguments.
‘llvm.thread.pointer
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.thread.pointer()
Overview:¶
The ‘llvm.thread.pointer
’ intrinsic returns the value of the thread pointer.
Semantics:¶
The ‘llvm.thread.pointer
’ intrinsic returns a pointer to the TLS area for the current thread. The exact semantics of this value are target specific: it may point to the start of
TLS area, to the end, or somewhere in the middle. Depending on the target, this intrinsic may read a register, call a helper function, read from an alternate memory space, or perform other operations necessary to locate the TLS area. Not all targets support this intrinsic.
‘llvm.call.preallocated.setup
’
Intrinsic¶
Syntax:¶
declare token @llvm.call.preallocated.setup(i32 %num_args)
Overview:¶
The ‘llvm.call.preallocated.setup
’ intrinsic returns a
token which can be used with a call’s "preallocated"
operand bundle to indicate that certain arguments are allocated and initialized before the call.
Semantics:¶
The ‘llvm.call.preallocated.setup
’ intrinsic returns a token which is associated with at most one call. The token can be passed to ‘@llvm.call.preallocated.arg
’ to get a pointer to get that corresponding argument. The token must be the
parameter to a "preallocated"
operand bundle for the corresponding call.
Nested calls to ‘llvm.call.preallocated.setup
’ are allowed, but must be properly nested. e.g.
:: code-block:: llvm
%t1 = call token @llvm.call.preallocated.setup(i32 0) %t2 = call token @llvm.call.preallocated.setup(i32 0) call void foo() [“preallocated”(token %t2)] call void foo() [“preallocated”(token %t1)]
is allowed, but not
:: code-block:: llvm
%t1 = call token @llvm.call.preallocated.setup(i32 0) %t2 = call token @llvm.call.preallocated.setup(i32 0) call void foo() [“preallocated”(token %t1)] call void foo() [“preallocated”(token %t2)]
‘llvm.call.preallocated.arg
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.call.preallocated.arg(token %setup_token, i32 %arg_index)
Overview:¶
The ‘llvm.call.preallocated.arg
’ intrinsic returns a pointer to the corresponding preallocated argument for the preallocated call.
Semantics:¶
The ‘llvm.call.preallocated.arg
’ intrinsic returns a pointer to the %arg_index``th argument with the ``preallocated
attribute for the call associated with the %setup_token
, which must be from ‘llvm.call.preallocated.setup
’.
A call to ‘llvm.call.preallocated.arg
’ must have a call site preallocated
attribute. The type of the preallocated
attribute must match the type used by the preallocated
attribute of the corresponding argument at the preallocated call. The type is used in the case that
an llvm.call.preallocated.setup
does not have a corresponding call (e.g. due to DCE), where otherwise we cannot know how large the arguments are.
It is undefined behavior if this is called with a token from an ‘llvm.call.preallocated.setup
’ if another ‘llvm.call.preallocated.setup
’ has already been called or if the preallocated call corresponding to the ‘llvm.call.preallocated.setup
’ has already been called.
‘llvm.call.preallocated.teardown
’
Intrinsic¶
Syntax:¶
declare ptr @llvm.call.preallocated.teardown(token %setup_token)
Overview:¶
The ‘llvm.call.preallocated.teardown
’ intrinsic cleans
up the stack created by a ‘llvm.call.preallocated.setup
’.
Semantics:¶
The token argument must be a ‘llvm.call.preallocated.setup
’.
The ‘llvm.call.preallocated.teardown
’ intrinsic cleans up the stack allocated by the corresponding ‘llvm.call.preallocated.setup
’. Exactly one of this or the preallocated call must be called to prevent stack leaks. It is undefined behavior to call both a ‘llvm.call.preallocated.teardown
’ and the preallocated call for a given
‘llvm.call.preallocated.setup
’.
For example, if the stack is allocated for a preallocated call by a ‘llvm.call.preallocated.setup
’, then an initializer function called on an allocated argument throws an exception, there should be a ‘llvm.call.preallocated.teardown
’ in the exception handler to prevent stack leaks.
Following the nesting rules in ‘llvm.call.preallocated.setup
’, nested calls to ‘llvm.call.preallocated.setup
’ and ‘llvm.call.preallocated.teardown
’ are allowed but must be properly nested.
Example:¶
%cs = call token @llvm.call.preallocated.setup(i32 1) %x = call ptr @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32) invoke void @constructor(ptr %x) to label %conta unwind label %contb conta: call void @foo1(ptr preallocated(i32) %x) ["preallocated"(token %cs)] ret void contb: %s = catchswitch within none [label %catch] unwind to caller catch: %p = catchpad within %s [] call void @llvm.call.preallocated.teardown(token %cs) ret void
Standard C/C++ Library Intrinsics¶
LLVM provides intrinsics for a few important standard C/C++ library functions. These intrinsics allow source-language front-ends to pass information about the alignment of the pointer arguments to the code generator, providing opportunity for more efficient code generation.
‘llvm.abs.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.abs
on any integer bit width or any vector of integer elements.
declare i32 @llvm.abs.i32(i32 <src>, i1 <is_int_min_poison>) declare <4 x i32> @llvm.abs.v4i32(<4 x i32> <src>, i1 <is_int_min_poison>)
Overview:¶
The ‘llvm.abs
’ family of intrinsic functions returns the absolute value of an argument.
Arguments:¶
The first argument is the value for which the absolute value is to be returned. This argument may be of any integer type or a vector with integer element type. The return type must match the first argument type.
The second argument must be a constant and is a flag to indicate whether the result value of the ‘llvm.abs
’ intrinsic is a poison value if the argument is statically or dynamically an INT_MIN
value.
Semantics:¶
The ‘llvm.abs
’ intrinsic returns the magnitude (always positive) of the argument or each element of a vector argument.”. If the argument is INT_MIN
, then the result is also INT_MIN
if is_int_min_poison == 0
and poison
otherwise.
‘llvm.smax.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use @llvm.smax
on any
integer bit width or any vector of integer elements.
declare i32 @llvm.smax.i32(i32 %a, i32 %b) declare <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
Return the larger of %a
and %b
comparing the values as signed integers. Vector intrinsics operate on a per-element basis. The larger element of %a
and %b
at a given index is returned for that index.
Arguments:¶
The arguments (%a
and %b
) may be of any integer type or a vector with integer element type. The argument types must match each other, and the return type must match the argument type.
‘llvm.smin.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use @llvm.smin
on any integer bit width or any vector of integer elements.
declare i32 @llvm.smin.i32(i32 %a, i32 %b) declare <4 x i32> @llvm.smin.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
Return the smaller of %a
and %b
comparing the values as signed integers. Vector intrinsics operate on a per-element basis. The smaller element of %a
and %b
at a given index is returned for that index.
Arguments:¶
The
arguments (%a
and %b
) may be of any integer type or a vector with integer element type. The argument types must match each other, and the return type must match the argument type.
‘llvm.umax.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use @llvm.umax
on any integer bit width or any vector of integer elements.
declare i32 @llvm.umax.i32(i32 %a, i32 %b) declare <4 x i32> @llvm.umax.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
Return the larger of %a
and %b
comparing the values as unsigned integers. Vector intrinsics
operate on a per-element basis. The larger element of %a
and %b
at a given index is returned for that index.
Arguments:¶
The arguments (%a
and %b
) may be of any integer type or a vector with integer element type. The argument types must match each other, and the return type must match the argument type.
‘llvm.umin.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use @llvm.umin
on any integer bit width or any vector of integer
elements.
declare i32 @llvm.umin.i32(i32 %a, i32 %b) declare <4 x i32> @llvm.umin.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
Return the smaller of %a
and %b
comparing the values as unsigned integers. Vector intrinsics operate on a per-element basis. The smaller element of %a
and %b
at a given index is returned for that index.
Arguments:¶
The arguments (%a
and %b
) may be of any integer type or a vector with integer element type. The argument types must match each other, and the return type must match the argument type.
‘llvm.memcpy
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memcpy
on any integer bit width and for different address spaces. Not all targets support all bit widths however.
declare void @llvm.memcpy.p0.p0.i32(ptr <dest>, ptr <src>, i32 <len>, i1 <isvolatile>) declare void @llvm.memcpy.p0.p0.i64(ptr <dest>, ptr <src>, i64 <len>, i1 <isvolatile>)
Overview:¶
The ‘llvm.memcpy.*
’ intrinsics copy a block of memory from the source location to the destination location.
Note that, unlike the standard libc function, the llvm.memcpy.*
intrinsics do not return a value, takes extra isvolatile arguments and the pointers can be in specified address spaces.
Arguments:¶
The first argument is a pointer to the destination, the second is a pointer to the source. The third argument is an integer argument specifying the number of bytes to copy, and the fourth is a boolean indicating a volatile access.
The align parameter attribute can be provided for the first and second arguments.
If the isvolatile
parameter is true
, the llvm.memcpy
call is a volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to depend on it.
Semantics:¶
The ‘llvm.memcpy.*
’ intrinsics copy a block of memory from
the source location to the destination location, which must either be equal or non-overlapping. It copies “len” bytes of memory over. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
If <len>
is 0, it is no-op modulo the behavior of attributes attached to the arguments. If <len>
is not a well-defined value, the behavior is undefined. If <len>
is not zero, both <dest>
and <src>
should be well-defined, otherwise the
behavior is undefined.
‘llvm.memcpy.inline
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use
llvm.memcpy.inline
on any integer bit width and for different address spaces. Not all targets support all bit widths however.
declare void @llvm.memcpy.inline.p0.p0.i32(ptr <dest>, ptr <src>, i32 <len>, i1 <isvolatile>) declare void @llvm.memcpy.inline.p0.p0.i64(ptr <dest>, ptr <src>, i64 <len>, i1 <isvolatile>)
Overview:¶
The ‘llvm.memcpy.inline.*
’ intrinsics copy a block of memory from the source location to the destination location and guarantees that no external functions are called.
Note that,
unlike the standard libc function, the llvm.memcpy.inline.*
intrinsics do not return a value, takes extra isvolatile arguments and the pointers can be in specified address spaces.
Arguments:¶
The first argument is a pointer to the destination, the second is a pointer to the source. The third argument is a constant integer argument specifying the number of bytes to copy, and the fourth is a boolean indicating a volatile access.
The align parameter attribute can be provided for the first and second arguments.
If the isvolatile
parameter is true
, the llvm.memcpy.inline
call is a volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to
depend on it.
Semantics:¶
The ‘llvm.memcpy.inline.*
’ intrinsics copy a block of memory from the source location to the destination location, which are not allowed to overlap. It copies “len” bytes of memory over. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument. The behavior of ‘llvm.memcpy.inline.*
’ is equivalent to
the behavior of ‘llvm.memcpy.*
’, but the generated code is guaranteed not to call any external functions.
‘llvm.memmove
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memmove on any integer bit width and for different address space. Not all targets support all bit widths however.
declare void @llvm.memmove.p0.p0.i32(ptr <dest>, ptr <src>, i32 <len>, i1 <isvolatile>) declare void @llvm.memmove.p0.p0.i64(ptr <dest>, ptr <src>, i64 <len>, i1 <isvolatile>)
Overview:¶
The ‘llvm.memmove.*
’ intrinsics move a block of memory from
the source location to the destination location. It is similar to the ‘llvm.memcpy
’ intrinsic but allows the two memory locations to overlap.
Note that, unlike the standard libc function, the llvm.memmove.*
intrinsics do not return a value, takes an extra isvolatile argument and the pointers can be in specified address spaces.
Arguments:¶
The first argument is a pointer to the destination, the second is a pointer to the source. The third argument is an integer argument specifying the number of bytes to copy, and the fourth is a boolean indicating a volatile access.
The align parameter attribute can be provided for the first and second arguments.
If the isvolatile
parameter is true
, the llvm.memmove
call is a
volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to depend on it.
Semantics:¶
The ‘llvm.memmove.*
’ intrinsics copy a block of memory from the source location to the destination location, which may overlap. It copies “len” bytes of
memory over. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
If <len>
is 0, it is no-op modulo the behavior of attributes attached to the arguments. If <len>
is not a well-defined value, the behavior is undefined. If <len>
is not zero, both <dest>
and <src>
should be well-defined, otherwise the behavior is undefined.
‘llvm.memset.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memset on any integer bit width and for different address spaces. However, not all targets support all bit widths.
declare void @llvm.memset.p0.i32(ptr <dest>, i8 <val>, i32 <len>, i1 <isvolatile>) declare void @llvm.memset.p0.i64(ptr <dest>, i8 <val>, i64 <len>, i1 <isvolatile>)
Overview:¶
The ‘llvm.memset.*
’ intrinsics fill a block of memory with a particular byte value.
Note that, unlike the standard libc function, the llvm.memset
intrinsic does not return a value and takes an extra volatile argument. Also, the destination can be in an arbitrary address space.
Arguments:¶
The first argument is a pointer to the destination to fill, the second is the byte value with which to fill it, the third argument is an integer argument specifying the number of bytes to fill, and the fourth is a boolean indicating a volatile access.
The align parameter attribute can be provided for the first arguments.
If the isvolatile
parameter is true
, the llvm.memset
call is a volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to depend on it.
Semantics:¶
The ‘llvm.memset.*
’
intrinsics fill “len” bytes of memory starting at the destination location. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
If <len>
is 0, it is no-op modulo the behavior of attributes attached to the arguments. If <len>
is not a well-defined value, the behavior is undefined. If <len>
is not zero, <dest>
should be well-defined, otherwise the behavior is undefined.
‘llvm.memset.inline
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memset.inline
on any integer bit width and for
different address spaces. Not all targets support all bit widths however.
declare void @llvm.memset.inline.p0.p0i8.i32(ptr <dest>, i8 <val>, i32 <len>, i1 <isvolatile>) declare void @llvm.memset.inline.p0.p0.i64(ptr <dest>, i8 <val>, i64 <len>, i1 <isvolatile>)
Overview:¶
The ‘llvm.memset.inline.*
’ intrinsics fill a block of memory with a particular byte value and guarantees that no external functions are called.
Note that, unlike the standard libc function, the llvm.memset.inline.*
intrinsics do not return a value, take an extra isvolatile
argument and the pointer can be in specified address spaces.
Arguments:¶
The first argument is a pointer to the destination to fill, the second is the byte value with which to fill it, the third argument is a constant integer argument specifying the number of bytes to fill, and the fourth is a boolean indicating a volatile access.
The align parameter attribute can be provided for the first argument.
If the isvolatile
parameter is true
, the llvm.memset.inline
call is a volatile operation. The detailed access behavior is not very cleanly specified and it is unwise to depend on it.
Semantics:¶
The ‘llvm.memset.inline.*
’ intrinsics fill “len” bytes of memory starting at the destination location. If the argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
len
must be a constant expression. If <len>
is 0, it is no-op modulo the behavior of attributes attached to the arguments. If <len>
is not a well-defined value, the
behavior is undefined. If <len>
is not zero, <dest>
should be well-defined, otherwise the behavior is undefined.
The behavior of ‘llvm.memset.inline.*
’ is equivalent to the behavior of ‘llvm.memset.*
’, but the generated code is guaranteed not to call any external functions.
‘llvm.sqrt.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.sqrt
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.sqrt.f32(float %Val) declare double @llvm.sqrt.f64(double %Val) declare x86_fp80 @llvm.sqrt.f80(x86_fp80 %Val) declare fp128 @llvm.sqrt.f128(fp128 %Val) declare ppc_fp128 @llvm.sqrt.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.sqrt
’ intrinsics return the square root of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘sqrt
’ function but without trapping or setting errno
. For types specified by IEEE-754, the result matches a conforming libm implementation.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.powi.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.powi
on any floating-point or vector of floating-point type. Not all targets support all types
however.
Generally, the only supported type for the exponent is the one matching with the C type int
.
declare float @llvm.powi.f32.i32(float %Val, i32 %power) declare double @llvm.powi.f64.i16(double %Val, i16 %power) declare x86_fp80 @llvm.powi.f80.i32(x86_fp80 %Val, i32 %power) declare fp128 @llvm.powi.f128.i32(fp128 %Val, i32 %power) declare ppc_fp128 @llvm.powi.ppcf128.i32(ppc_fp128 %Val, i32 %power)
Overview:¶
The ‘llvm.powi.*
’ intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating-point type is used, the
second argument remains a scalar integer value.
Arguments:¶
The second argument is an integer power, and the first is a value to raise to that power.
Semantics:¶
This function returns the first value raised to the second power with an unspecified sequence of rounding operations.
‘llvm.sin.*
’ Intrinsic¶
Syntax:¶
This is an overloaded
intrinsic. You can use llvm.sin
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.sin.f32(float %Val) declare double @llvm.sin.f64(double %Val) declare x86_fp80 @llvm.sin.f80(x86_fp80 %Val) declare fp128 @llvm.sin.f128(fp128 %Val) declare ppc_fp128 @llvm.sin.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.sin.*
’ intrinsics return the sine of the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘sin
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.cos.*
’ Intrinsic¶
Syntax:¶
This is an overloaded
intrinsic. You can use llvm.cos
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.cos.f32(float %Val) declare double @llvm.cos.f64(double %Val) declare x86_fp80 @llvm.cos.f80(x86_fp80 %Val) declare fp128 @llvm.cos.f128(fp128 %Val) declare ppc_fp128 @llvm.cos.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.cos.*
’ intrinsics return the cosine of the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘cos
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.pow.*
’ Intrinsic¶
Syntax:¶
This is an overloaded
intrinsic. You can use llvm.pow
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.pow.f32(float %Val, float %Power) declare double @llvm.pow.f64(double %Val, double %Power) declare x86_fp80 @llvm.pow.f80(x86_fp80 %Val, x86_fp80 %Power) declare fp128 @llvm.pow.f128(fp128 %Val, fp128 %Power) declare ppc_fp128 @llvm.pow.ppcf128(ppc_fp128 %Val, ppc_fp128 Power)
Overview:¶
The ‘llvm.pow.*
’ intrinsics return the first operand raised to the specified (positive or negative) power.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘pow
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.exp.*
’ Intrinsic¶
Syntax:¶
This is an
overloaded intrinsic. You can use llvm.exp
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.exp.f32(float %Val) declare double @llvm.exp.f64(double %Val) declare x86_fp80 @llvm.exp.f80(x86_fp80 %Val) declare fp128 @llvm.exp.f128(fp128 %Val) declare ppc_fp128 @llvm.exp.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.exp.*
’ intrinsics compute the base-e exponential of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘exp
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.exp2.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.exp2
on any floating-point or
vector of floating-point type. Not all targets support all types however.
declare float @llvm.exp2.f32(float %Val) declare double @llvm.exp2.f64(double %Val) declare x86_fp80 @llvm.exp2.f80(x86_fp80 %Val) declare fp128 @llvm.exp2.f128(fp128 %Val) declare ppc_fp128 @llvm.exp2.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.exp2.*
’ intrinsics compute the base-2 exponential of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘exp2
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.log.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.log
on any floating-point or vector of floating-point type. Not all targets support all types
however.
declare float @llvm.log.f32(float %Val) declare double @llvm.log.f64(double %Val) declare x86_fp80 @llvm.log.f80(x86_fp80 %Val) declare fp128 @llvm.log.f128(fp128 %Val) declare ppc_fp128 @llvm.log.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.log.*
’ intrinsics compute the base-e logarithm of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘log
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.log10.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.log10
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.log10.f32(float %Val) declare double @llvm.log10.f64(double %Val) declare x86_fp80 @llvm.log10.f80(x86_fp80 %Val) declare fp128 @llvm.log10.f128(fp128 %Val) declare ppc_fp128 @llvm.log10.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.log10.*
’ intrinsics compute the base-10 logarithm of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘log10
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.log2.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.log2
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.log2.f32(float %Val) declare double @llvm.log2.f64(double %Val) declare x86_fp80 @llvm.log2.f80(x86_fp80 %Val) declare fp128 @llvm.log2.f128(fp128 %Val) declare ppc_fp128 @llvm.log2.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.log2.*
’ intrinsics compute the base-2 logarithm of the specified value.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘log2
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.fma.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fma
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.fma.f32(float %a, float %b, float %c) declare double @llvm.fma.f64(double %a, double %b, double %c) declare x86_fp80 @llvm.fma.f80(x86_fp80 %a, x86_fp80 %b, x86_fp80 %c) declare fp128 @llvm.fma.f128(fp128 %a, fp128 %b, fp128 %c) declare ppc_fp128 @llvm.fma.ppcf128(ppc_fp128 %a, ppc_fp128 %b, ppc_fp128 %c)
Overview:¶
The ‘llvm.fma.*
’ intrinsics perform the fused multiply-add operation.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
Return the same value as a corresponding libm ‘fma
’ function but without trapping or setting errno
.
When specified with the fast-math-flag ‘afn’, the result may be approximated using a less accurate calculation.
‘llvm.fabs.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fabs
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.fabs.f32(float %Val) declare double @llvm.fabs.f64(double %Val) declare x86_fp80 @llvm.fabs.f80(x86_fp80 %Val) declare fp128 @llvm.fabs.f128(fp128 %Val) declare ppc_fp128 @llvm.fabs.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.fabs.*
’ intrinsics return the absolute value of the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm fabs
functions would, and handles error conditions in the same way.
‘llvm.minnum.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.minnum
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.minnum.f32(float %Val0, float %Val1) declare double @llvm.minnum.f64(double %Val0, double %Val1) declare x86_fp80 @llvm.minnum.f80(x86_fp80 %Val0, x86_fp80 %Val1) declare fp128 @llvm.minnum.f128(fp128 %Val0, fp128 %Val1) declare ppc_fp128 @llvm.minnum.ppcf128(ppc_fp128 %Val0, ppc_fp128 %Val1)
Overview:¶
The ‘llvm.minnum.*
’ intrinsics
return the minimum of the two arguments.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
Follows the IEEE-754 semantics for minNum, except for handling of signaling NaNs. This match’s the behavior of libm’s fmin.
If either operand is a NaN, returns the other non-NaN operand. Returns NaN only if both operands are NaN. The returned NaN is always quiet. If the operands compare equal, returns a value that compares equal to both operands. This means that fmin(+/-0.0, +/-0.0) could return either -0.0 or 0.0.
Unlike the IEEE-754 2008 behavior, this does not distinguish between signaling and quiet NaN inputs. If a target’s implementation follows the
standard and returns a quiet NaN if either input is a signaling NaN, the intrinsic lowering is responsible for quieting the inputs to correctly return the non-NaN input (e.g. by using the equivalent of llvm.canonicalize
).
‘llvm.maxnum.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.maxnum
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.maxnum.f32(float %Val0, float %Val1) declare double @llvm.maxnum.f64(double %Val0, double %Val1) declare x86_fp80 @llvm.maxnum.f80(x86_fp80 %Val0, x86_fp80 %Val1) declare fp128 @llvm.maxnum.f128(fp128 %Val0, fp128 %Val1) declare ppc_fp128 @llvm.maxnum.ppcf128(ppc_fp128 %Val0, ppc_fp128 %Val1)
Overview:¶
The ‘llvm.maxnum.*
’ intrinsics return the maximum of
the two arguments.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
Follows the IEEE-754 semantics for maxNum except for the handling of signaling NaNs. This matches the behavior of libm’s fmax.
If either operand is a NaN, returns the other non-NaN operand. Returns NaN only if both operands are NaN. The returned NaN is always quiet. If the operands compare equal, returns a value that compares equal to both operands. This means that fmax(+/-0.0, +/-0.0) could return either -0.0 or 0.0.
Unlike the IEEE-754 2008 behavior, this does not distinguish between signaling and quiet NaN inputs. If a target’s implementation follows the standard and returns a
quiet NaN if either input is a signaling NaN, the intrinsic lowering is responsible for quieting the inputs to correctly return the non-NaN input (e.g. by using the equivalent of llvm.canonicalize
).
‘llvm.minimum.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.minimum
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.minimum.f32(float %Val0, float %Val1) declare double @llvm.minimum.f64(double %Val0, double %Val1) declare x86_fp80 @llvm.minimum.f80(x86_fp80 %Val0, x86_fp80 %Val1) declare fp128 @llvm.minimum.f128(fp128 %Val0, fp128 %Val1) declare ppc_fp128 @llvm.minimum.ppcf128(ppc_fp128 %Val0, ppc_fp128 %Val1)
Overview:¶
The ‘llvm.minimum.*
’ intrinsics return the minimum of the two
arguments, propagating NaNs and treating -0.0 as less than +0.0.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
If either operand is a NaN, returns NaN. Otherwise returns the lesser of the two arguments. -0.0 is considered to be less than +0.0 for this intrinsic. Note that these are the semantics specified in the draft of IEEE 754-2018.
‘llvm.maximum.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.maximum
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.maximum.f32(float %Val0, float %Val1) declare double @llvm.maximum.f64(double %Val0, double %Val1) declare x86_fp80 @llvm.maximum.f80(x86_fp80 %Val0, x86_fp80 %Val1) declare fp128 @llvm.maximum.f128(fp128 %Val0, fp128 %Val1) declare ppc_fp128 @llvm.maximum.ppcf128(ppc_fp128 %Val0, ppc_fp128 %Val1)
Overview:¶
The ‘llvm.maximum.*
’ intrinsics return the maximum of the two
arguments, propagating NaNs and treating -0.0 as less than +0.0.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
If either operand is a NaN, returns NaN. Otherwise returns the greater of the two arguments. -0.0 is considered to be less than +0.0 for this intrinsic. Note that these are the semantics specified in the draft of IEEE 754-2018.
‘llvm.copysign.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.copysign
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.copysign.f32(float %Mag, float %Sgn) declare double @llvm.copysign.f64(double %Mag, double %Sgn) declare x86_fp80 @llvm.copysign.f80(x86_fp80 %Mag, x86_fp80 %Sgn) declare fp128 @llvm.copysign.f128(fp128 %Mag, fp128 %Sgn) declare ppc_fp128 @llvm.copysign.ppcf128(ppc_fp128 %Mag, ppc_fp128 %Sgn)
Overview:¶
The ‘llvm.copysign.*
’ intrinsics return a value with the magnitude of
the first operand and the sign of the second operand.
Arguments:¶
The arguments and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm copysign
functions would, and handles error conditions in the same way.
‘llvm.floor.*
’ Intrinsic¶
Syntax:¶
This is an overloaded
intrinsic. You can use llvm.floor
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.floor.f32(float %Val) declare double @llvm.floor.f64(double %Val) declare x86_fp80 @llvm.floor.f80(x86_fp80 %Val) declare fp128 @llvm.floor.f128(fp128 %Val) declare ppc_fp128 @llvm.floor.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.floor.*
’ intrinsics return the floor of the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm floor
functions would, and handles error conditions in the same way.
‘llvm.ceil.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.ceil
on any floating-point or vector of floating-point type.
Not all targets support all types however.
declare float @llvm.ceil.f32(float %Val) declare double @llvm.ceil.f64(double %Val) declare x86_fp80 @llvm.ceil.f80(x86_fp80 %Val) declare fp128 @llvm.ceil.f128(fp128 %Val) declare ppc_fp128 @llvm.ceil.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.ceil.*
’ intrinsics return the ceiling of the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm ceil
functions would, and handles error conditions in the same way.
‘llvm.trunc.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.trunc
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.trunc.f32(float %Val) declare double @llvm.trunc.f64(double %Val) declare x86_fp80 @llvm.trunc.f80(x86_fp80 %Val) declare fp128 @llvm.trunc.f128(fp128 %Val) declare ppc_fp128 @llvm.trunc.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.trunc.*
’ intrinsics returns the operand rounded to the nearest integer not larger in magnitude than the operand.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm trunc
functions would, and handles error conditions in the same way.
‘llvm.rint.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.rint
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.rint.f32(float %Val) declare double @llvm.rint.f64(double %Val) declare x86_fp80 @llvm.rint.f80(x86_fp80 %Val) declare fp128 @llvm.rint.f128(fp128 %Val) declare ppc_fp128 @llvm.rint.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.rint.*
’ intrinsics
returns the operand rounded to the nearest integer. It may raise an inexact floating-point exception if the operand isn’t an integer.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm rint
functions would, and handles error conditions in the same way.
‘llvm.nearbyint.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.nearbyint
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.nearbyint.f32(float %Val) declare double @llvm.nearbyint.f64(double %Val) declare x86_fp80 @llvm.nearbyint.f80(x86_fp80 %Val) declare fp128 @llvm.nearbyint.f128(fp128 %Val) declare ppc_fp128 @llvm.nearbyint.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.nearbyint.*
’ intrinsics returns the operand rounded to the nearest integer.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm nearbyint
functions would, and handles error conditions in the same way.
‘llvm.round.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.round
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.round.f32(float %Val) declare double @llvm.round.f64(double %Val) declare x86_fp80 @llvm.round.f80(x86_fp80 %Val) declare fp128 @llvm.round.f128(fp128 %Val) declare ppc_fp128 @llvm.round.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.round.*
’ intrinsics
returns the operand rounded to the nearest integer.
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function returns the same values as the libm round
functions would, and handles error conditions in the same way.
‘llvm.roundeven.*
’ Intrinsic¶
Syntax:¶
This is an
overloaded intrinsic. You can use llvm.roundeven
on any floating-point or vector of floating-point type. Not all targets support all types however.
declare float @llvm.roundeven.f32(float %Val) declare double @llvm.roundeven.f64(double %Val) declare x86_fp80 @llvm.roundeven.f80(x86_fp80 %Val) declare fp128 @llvm.roundeven.f128(fp128 %Val) declare ppc_fp128 @llvm.roundeven.ppcf128(ppc_fp128 %Val)
Overview:¶
The ‘llvm.roundeven.*
’ intrinsics returns the operand rounded to the nearest integer in floating-point format rounding halfway cases to even (that is, to the nearest value that is an even
integer).
Arguments:¶
The argument and return value are floating-point numbers of the same type.
Semantics:¶
This function implements IEEE-754 operation roundToIntegralTiesToEven
. It also behaves in the same way as C standard
function roundeven
, except that it does not raise floating point exceptions.
‘llvm.lround.*
’ Intrinsic¶
Syntax:¶
This is an
overloaded intrinsic. You can use llvm.lround
on any floating-point type. Not all targets support all types however.
declare i32 @llvm.lround.i32.f32(float %Val) declare i32 @llvm.lround.i32.f64(double %Val) declare i32 @llvm.lround.i32.f80(float %Val) declare i32 @llvm.lround.i32.f128(double %Val) declare i32 @llvm.lround.i32.ppcf128(double %Val) declare i64 @llvm.lround.i64.f32(float %Val) declare i64 @llvm.lround.i64.f64(double %Val) declare i64 @llvm.lround.i64.f80(float %Val) declare i64 @llvm.lround.i64.f128(double %Val) declare i64 @llvm.lround.i64.ppcf128(double %Val)
Overview:¶
The ‘llvm.lround.*
’ intrinsics return the operand rounded to the nearest integer with ties away from zero.
Arguments:¶
The argument is a floating-point number and the return value is an integer type.
Semantics:¶
This function returns the same values as the libm lround
functions would, but without setting errno.
‘llvm.llround.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.llround
on any floating-point type. Not all targets support all types however.
declare i64 @llvm.lround.i64.f32(float %Val) declare i64 @llvm.lround.i64.f64(double %Val) declare i64 @llvm.lround.i64.f80(float %Val) declare i64 @llvm.lround.i64.f128(double %Val) declare i64 @llvm.lround.i64.ppcf128(double %Val)
Overview:¶
The ‘llvm.llround.*
’ intrinsics return the operand rounded to the nearest integer with ties away from zero.
Arguments:¶
The argument is a floating-point number and the return value is an integer type.
Semantics:¶
This function returns the same values as the libm llround
functions would, but without setting errno.
‘llvm.lrint.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.lrint
on any floating-point type. Not all targets support all types however.
declare i32 @llvm.lrint.i32.f32(float %Val) declare i32 @llvm.lrint.i32.f64(double %Val) declare i32 @llvm.lrint.i32.f80(float %Val) declare i32 @llvm.lrint.i32.f128(double %Val) declare i32 @llvm.lrint.i32.ppcf128(double %Val) declare i64 @llvm.lrint.i64.f32(float %Val) declare i64 @llvm.lrint.i64.f64(double %Val) declare i64 @llvm.lrint.i64.f80(float %Val) declare i64 @llvm.lrint.i64.f128(double %Val) declare i64 @llvm.lrint.i64.ppcf128(double %Val)
Overview:¶
The ‘llvm.lrint.*
’ intrinsics return the operand rounded to the nearest integer.
Arguments:¶
The argument is a floating-point number and the return value is an integer type.
Semantics:¶
This function returns the same values as the libm lrint
functions would, but without setting errno.
‘llvm.llrint.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.llrint
on any floating-point type. Not all targets support all types however.
declare i64 @llvm.llrint.i64.f32(float %Val) declare i64 @llvm.llrint.i64.f64(double %Val) declare i64 @llvm.llrint.i64.f80(float %Val) declare i64 @llvm.llrint.i64.f128(double %Val) declare i64 @llvm.llrint.i64.ppcf128(double %Val)
Overview:¶
The ‘llvm.llrint.*
’ intrinsics return the operand rounded to the nearest
integer.
Arguments:¶
The argument is a floating-point number and the return value is an integer type.
Semantics:¶
This function returns the same values as the libm llrint
functions would, but without setting
errno.
Bit Manipulation Intrinsics¶
LLVM provides intrinsics for a few important bit manipulation operations. These allow efficient code generation for some algorithms.
‘llvm.bitreverse.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic function. You can use bitreverse on any integer type.
declare i16 @llvm.bitreverse.i16(i16 <id>) declare i32 @llvm.bitreverse.i32(i32 <id>) declare i64 @llvm.bitreverse.i64(i64 <id>) declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> <id>)
Overview:¶
The ‘llvm.bitreverse
’ family of intrinsics is used to reverse the bitpattern of an integer value or vector of integer values; for example 0b10110110
becomes 0b01101101
.
Semantics:¶
The llvm.bitreverse.iN
intrinsic returns an iN value that has bit M
in the
input moved to bit N-M-1
in the output. The vector intrinsics, such as llvm.bitreverse.v4i32
, operate on a per-element basis and the element order is not affected.
‘llvm.bswap.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic function. You can use bswap on any integer type that is an even number of bytes (i.e. BitWidth % 16 == 0).
declare i16 @llvm.bswap.i16(i16 <id>) declare i32 @llvm.bswap.i32(i32 <id>) declare i64 @llvm.bswap.i64(i64 <id>) declare <4 x i32> @llvm.bswap.v4i32(<4 x i32> <id>)
Overview:¶
The ‘llvm.bswap
’ family of intrinsics is used to byte swap an integer value or
vector of integer values with an even number of bytes (positive multiple of 16 bits).
Semantics:¶
The llvm.bswap.i16
intrinsic returns an i16 value that has the high and low byte of the input i16 swapped. Similarly, the llvm.bswap.i32
intrinsic returns an i32 value that has the four bytes of the input i32 swapped, so that if the input bytes are numbered 0, 1, 2, 3
then the returned i32 will have its bytes in 3, 2, 1, 0 order. The llvm.bswap.i48
, llvm.bswap.i64
and other intrinsics extend this concept to additional even-byte lengths (6 bytes, 8 bytes and more, respectively). The vector intrinsics, such as llvm.bswap.v4i32
, operate on a per-element basis and the element order is not affected.
‘llvm.ctpop.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.ctpop on any integer bit width, or on any vector with integer elements. Not all targets support all bit widths or vector types, however.
declare i8 @llvm.ctpop.i8(i8 <src>) declare i16 @llvm.ctpop.i16(i16 <src>) declare i32 @llvm.ctpop.i32(i32 <src>) declare i64 @llvm.ctpop.i64(i64 <src>) declare i256 @llvm.ctpop.i256(i256 <src>) declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32> <src>)
Overview:¶
The ‘llvm.ctpop
’ family of intrinsics counts the number of bits set in a value.
Arguments:¶
The only argument is the value to be counted. The argument may be of any integer type, or a vector with integer elements. The return type must match the argument type.
Semantics:¶
The ‘llvm.ctpop
’ intrinsic counts the 1’s in a variable, or within each element of a vector.
‘llvm.ctlz.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.ctlz
on any integer bit width, or any vector whose elements are integers. Not all targets support all bit widths or vector types, however.
declare i8 @llvm.ctlz.i8 (i8 <src>, i1 <is_zero_poison>) declare <2 x i37> @llvm.ctlz.v2i37(<2 x i37> <src>, i1 <is_zero_poison>)
Overview:¶
The ‘llvm.ctlz
’ family of intrinsic functions counts the number of leading zeros in a variable.
Arguments:¶
The first argument is the value to be counted. This argument may be of any integer type, or a vector with integer element type. The return type must match the first argument type.
The second argument is a constant flag that indicates whether the intrinsic returns a valid result if the first argument is zero. If the first argument is zero and the second argument is true, the result is poison. Historically some architectures did not provide a defined result for zero values as efficiently, and many algorithms are now predicated on avoiding zero-value inputs.
Semantics:¶
The ‘llvm.ctlz
’ intrinsic counts the leading (most significant) zeros in a variable, or within each element of the vector. If src == 0
then the result is the size in bits of the type of src
if is_zero_poison == 0
and poison
otherwise. For example, llvm.ctlz(i32 2) = 30
.
‘llvm.cttz.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.cttz
on any integer bit width, or any vector of integer elements. Not all targets support all bit widths or vector types, however.
declare i42 @llvm.cttz.i42 (i42 <src>, i1 <is_zero_poison>) declare <2 x i32> @llvm.cttz.v2i32(<2 x i32> <src>, i1 <is_zero_poison>)
Overview:¶
The ‘llvm.cttz
’ family of intrinsic functions counts the number of trailing zeros.
Arguments:¶
The first argument is the value to be counted. This argument may be of any integer type, or a vector with integer element type. The return type must match the first argument type.
The second argument is a constant flag that indicates whether the intrinsic returns a valid result if the first argument is zero. If the first argument is zero and the second argument is true, the result is poison. Historically some architectures did not provide a defined result for zero values as efficiently, and many algorithms are now predicated on avoiding zero-value inputs.
Semantics:¶
The ‘llvm.cttz
’ intrinsic counts the trailing (least significant) zeros in a variable, or within each element of a vector. If src == 0
then the result is the size in bits of the type of src
if is_zero_poison == 0
and poison
otherwise. For example, llvm.cttz(2) = 1
.
‘llvm.fshl.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fshl
on any integer bit width or any vector of integer elements. Not all targets support all bit widths or vector types, however.
declare i8 @llvm.fshl.i8 (i8 %a, i8 %b, i8 %c) declare i67 @llvm.fshl.i67(i67 %a, i67 %b, i67 %c) declare <2 x i32> @llvm.fshl.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)
Overview:¶
The ‘llvm.fshl
’ family of intrinsic functions performs a funnel shift left: the first two values are concatenated as { %a : %b } (%a is the most significant bits of the wide value), the combined value is shifted left, and the most significant bits are extracted to produce a result that is the same size as the original arguments. If the first 2 arguments are
identical, this is equivalent to a rotate left operation. For vector types, the operation occurs for each element of the vector. The shift argument is treated as an unsigned amount modulo the element size of the arguments.
Arguments:¶
The first two arguments are the values to be concatenated. The third argument is the shift amount. The arguments may be any integer type or a vector with integer element type. All arguments and the return value must have the same type.
Example:¶
%r = call i8 @llvm.fshl.i8(i8 %x, i8 %y, i8 %z) ; %r = i8: msb_extract((concat(x, y) << (z % 8)), 8) %r = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 15) ; %r = i8: 128 (0b10000000) %r = call i8 @llvm.fshl.i8(i8 15, i8 15, i8 11) ; %r = i8: 120 (0b01111000) %r = call i8 @llvm.fshl.i8(i8 0, i8 255, i8 8) ; %r = i8: 0 (0b00000000)
‘llvm.fshr.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fshr
on any integer bit width or any vector of integer elements. Not all targets support all bit widths or vector types, however.
declare i8 @llvm.fshr.i8 (i8 %a, i8 %b, i8 %c) declare i67 @llvm.fshr.i67(i67 %a, i67 %b, i67 %c) declare <2 x i32> @llvm.fshr.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c)
Overview:¶
The ‘llvm.fshr
’ family of intrinsic functions performs a funnel shift right: the first two values are concatenated as { %a : %b } (%a is the most significant bits of the wide value), the combined value is shifted right, and the least significant bits are extracted to produce a result that is the same size as the original arguments. If the first 2 arguments are
identical, this is equivalent to a rotate right operation. For vector types, the operation occurs for each element of the vector. The shift argument is treated as an unsigned amount modulo the element size of the arguments.
Arguments:¶
The first two arguments are the values to be concatenated. The third argument is the shift amount. The arguments may be any integer type or a vector with integer element type. All arguments and the return value must have the same type.
Example:¶
%r = call i8 @llvm.fshr.i8(i8 %x, i8 %y, i8 %z) ; %r = i8: lsb_extract((concat(x, y) >> (z % 8)), 8) %r = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 15) ; %r = i8: 254 (0b11111110) %r = call i8 @llvm.fshr.i8(i8 15, i8 15, i8 11) ; %r = i8: 225 (0b11100001) %r = call i8 @llvm.fshr.i8(i8 0, i8 255, i8 8) ; %r = i8: 255 (0b11111111)
Arithmetic with Overflow Intrinsics¶
LLVM provides intrinsics for fast arithmetic overflow checking.
Each of these intrinsics returns a two-element struct. The first element of this struct contains the result of the corresponding arithmetic operation modulo 2n, where n is the bit width of the result. Therefore, for example, the first element of the struct
returned by llvm.sadd.with.overflow.i32
is always the same as the result of a 32-bit add
instruction with the same operands, where the add
is not modified by an nsw
or nuw
flag.
The second element of the result is an i1
that is 1 if the arithmetic operation overflowed and 0 otherwise. An operation overflows if, for any values of its operands A
and B
and for any N
larger than the operands’ width, ext(A op B) to iN
is not equal to (ext(A) to iN) op (ext(B) to iN)
where ext
is
sext
for signed overflow and zext
for unsigned overflow, and op
is the underlying arithmetic operation.
The behavior of these intrinsics is well-defined for all argument values.
‘llvm.sadd.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.sadd.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.sadd.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.sadd.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.sadd.with.overflow
’ family of intrinsic functions perform a signed addition of the two arguments, and indicate whether an overflow occurred during the signed summation.
Arguments:¶
The arguments (%a and %b) and the first element of the result
structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo signed addition.
Semantics:¶
The ‘llvm.sadd.with.overflow
’ family of intrinsic functions perform a signed addition of the two variables. They return a
structure — the first element of which is the signed summation, and the second element of which is a bit specifying if the signed summation resulted in an overflow.
Examples:¶
%res = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %overflow, label %normal
‘llvm.uadd.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.uadd.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.uadd.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.uadd.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.uadd.with.overflow
’ family of intrinsic functions perform an unsigned addition of the two arguments, and indicate whether a carry occurred during the unsigned summation.
Arguments:¶
The arguments (%a and %b) and the first element of the result
structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo unsigned addition.
Semantics:¶
The ‘llvm.uadd.with.overflow
’ family of intrinsic functions perform an unsigned addition of the two arguments. They return
a structure — the first element of which is the sum, and the second element of which is a bit specifying if the unsigned summation resulted in a carry.
Examples:¶
%res = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %carry, label %normal
‘llvm.ssub.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.ssub.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.ssub.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.ssub.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.ssub.with.overflow
’ family of intrinsic functions perform a signed subtraction of the two arguments, and indicate whether an overflow occurred during the signed subtraction.
Arguments:¶
The arguments (%a and %b) and the first element of the result
structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo signed subtraction.
Semantics:¶
The ‘llvm.ssub.with.overflow
’ family of intrinsic functions perform a signed subtraction of the two arguments. They return
a structure — the first element of which is the subtraction, and the second element of which is a bit specifying if the signed subtraction resulted in an overflow.
Examples:¶
%res = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %overflow, label %normal
‘llvm.usub.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.usub.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.usub.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.usub.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.usub.with.overflow
’ family of intrinsic functions perform an unsigned subtraction of the two arguments, and indicate whether an overflow occurred during the unsigned subtraction.
Arguments:¶
The arguments (%a and %b) and the first element of the
result structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo unsigned subtraction.
Semantics:¶
The ‘llvm.usub.with.overflow
’ family of intrinsic functions perform an unsigned subtraction of the two arguments.
They return a structure — the first element of which is the subtraction, and the second element of which is a bit specifying if the unsigned subtraction resulted in an overflow.
Examples:¶
%res = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %overflow, label %normal
‘llvm.smul.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.smul.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.smul.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.smul.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.smul.with.overflow
’ family of intrinsic functions perform a signed multiplication of the two arguments, and indicate whether an overflow occurred during the signed multiplication.
Arguments:¶
The arguments (%a and %b) and the first element of the
result structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo signed multiplication.
Semantics:¶
The ‘llvm.smul.with.overflow
’ family of intrinsic functions perform a signed multiplication of the two
arguments. They return a structure — the first element of which is the multiplication, and the second element of which is a bit specifying if the signed multiplication resulted in an overflow.
Examples:¶
%res = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %overflow, label %normal
‘llvm.umul.with.overflow.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.umul.with.overflow
on any integer bit width or vectors of integers.
declare {i16, i1} @llvm.umul.with.overflow.i16(i16 %a, i16 %b) declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b) declare {i64, i1} @llvm.umul.with.overflow.i64(i64 %a, i64 %b) declare {<4 x i32>, <4 x i1>} @llvm.umul.with.overflow.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview:¶
The ‘llvm.umul.with.overflow
’ family of intrinsic functions perform a unsigned multiplication of the two arguments, and indicate whether an overflow occurred during the unsigned multiplication.
Arguments:¶
The arguments (%a and %b) and the first element of the
result structure may be of integer types of any bit width, but they must have the same bit width. The second element of the result structure must be of type i1
. %a
and %b
are the two values that will undergo unsigned multiplication.
Semantics:¶
The ‘llvm.umul.with.overflow
’ family of intrinsic functions perform an unsigned multiplication of the two
arguments. They return a structure — the first element of which is the multiplication, and the second element of which is a bit specifying if the unsigned multiplication resulted in an overflow.
Examples:¶
%res = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b) %sum = extractvalue {i32, i1} %res, 0 %obit = extractvalue {i32, i1} %res, 1 br i1 %obit, label %overflow, label %normal
Saturation Arithmetic Intrinsics¶
Saturation arithmetic is a version of arithmetic in which operations are limited to a fixed range between a minimum and maximum value. If the result of an operation is greater than the maximum value, the result is set (or “clamped”) to this maximum. If it is below the minimum, it is clamped to this minimum.
‘llvm.sadd.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can
use llvm.sadd.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.sadd.sat.i16(i16 %a, i16 %b) declare i32 @llvm.sadd.sat.i32(i32 %a, i32 %b) declare i64 @llvm.sadd.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.sadd.sat
’ family of intrinsic functions perform signed saturating addition on the 2 arguments.
Arguments¶
The arguments
(%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo signed addition.
Semantics:¶
The maximum value this operation can clamp to is the largest signed value representable by the bit width of the arguments. The minimum value is the smallest signed value representable by this bit width.
Examples¶
%res = call i4 @llvm.sadd.sat.i4(i4 1, i4 2) ; %res = 3 %res = call i4 @llvm.sadd.sat.i4(i4 5, i4 6) ; %res = 7 %res = call i4 @llvm.sadd.sat.i4(i4 -4, i4 2) ; %res = -2 %res = call i4 @llvm.sadd.sat.i4(i4 -4, i4 -5) ; %res = -8
‘llvm.uadd.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.uadd.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.uadd.sat.i16(i16 %a, i16 %b) declare i32 @llvm.uadd.sat.i32(i32 %a, i32 %b) declare i64 @llvm.uadd.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.uadd.sat
’ family of intrinsic functions perform unsigned saturating addition on the 2
arguments.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo unsigned addition.
Semantics:¶
The maximum value this operation can clamp to is the largest unsigned value representable by the bit width of the arguments. Because this is an unsigned operation, the result will never saturate towards zero.
Examples¶
%res = call i4 @llvm.uadd.sat.i4(i4 1, i4 2) ; %res = 3 %res = call i4 @llvm.uadd.sat.i4(i4 5, i4 6) ; %res = 11 %res = call i4 @llvm.uadd.sat.i4(i4 8, i4 8) ; %res = 15
‘llvm.ssub.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.ssub.sat
on any integer bit width or vectors of
integers.
declare i16 @llvm.ssub.sat.i16(i16 %a, i16 %b) declare i32 @llvm.ssub.sat.i32(i32 %a, i32 %b) declare i64 @llvm.ssub.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.ssub.sat
’ family of intrinsic functions perform signed saturating subtraction on the 2 arguments.
Arguments¶
The arguments (%a and %b) and the result may be of integer types
of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo signed subtraction.
Semantics:¶
The maximum value this operation can clamp to is the largest signed value representable by the bit width of the arguments. The minimum value is the smallest signed value representable by this bit width.
Examples¶
%res = call i4 @llvm.ssub.sat.i4(i4 2, i4 1) ; %res = 1 %res = call i4 @llvm.ssub.sat.i4(i4 2, i4 6) ; %res = -4 %res = call i4 @llvm.ssub.sat.i4(i4 -4, i4 5) ; %res = -8 %res = call i4 @llvm.ssub.sat.i4(i4 4, i4 -5) ; %res = 7
‘llvm.usub.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.usub.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.usub.sat.i16(i16 %a, i16 %b) declare i32 @llvm.usub.sat.i32(i32 %a, i32 %b) declare i64 @llvm.usub.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.usub.sat
’ family of intrinsic functions perform unsigned saturating subtraction on the 2 arguments.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo unsigned subtraction.
Semantics:¶
The minimum value this operation can clamp to is 0, which is the smallest unsigned value representable by the bit width of the unsigned arguments. Because this is an unsigned operation, the result will never saturate towards the largest possible value representable by this bit width.
Examples¶
%res = call i4 @llvm.usub.sat.i4(i4 2, i4 1) ; %res = 1 %res = call i4 @llvm.usub.sat.i4(i4 2, i4 6) ; %res = 0
‘llvm.sshl.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.sshl.sat
on integers or vectors of integers of any bit
width.
declare i16 @llvm.sshl.sat.i16(i16 %a, i16 %b) declare i32 @llvm.sshl.sat.i32(i32 %a, i32 %b) declare i64 @llvm.sshl.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.sshl.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.sshl.sat
’ family of intrinsic functions perform signed saturating left shift on the first argument.
Arguments¶
The arguments (%a
and %b
) and the result may be of
integer types of any bit width, but they must have the same bit width. %a
is the value to be shifted, and %b
is the amount to shift by. If b
is (statically or dynamically) equal to or larger than the integer bit width of the arguments, the result is a poison value. If the arguments are vectors, each vector element of a
is shifted by the corresponding shift amount in b
.
Semantics:¶
The maximum value this operation can clamp to is the largest signed value representable by the bit width of the arguments. The minimum value is the smallest signed value representable by this bit width.
Examples¶
%res = call i4 @llvm.sshl.sat.i4(i4 2, i4 1) ; %res = 4 %res = call i4 @llvm.sshl.sat.i4(i4 2, i4 2) ; %res = 7 %res = call i4 @llvm.sshl.sat.i4(i4 -5, i4 1) ; %res = -8 %res = call i4 @llvm.sshl.sat.i4(i4 -1, i4 1) ; %res = -2
‘llvm.ushl.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.ushl.sat
on
integers or vectors of integers of any bit width.
declare i16 @llvm.ushl.sat.i16(i16 %a, i16 %b) declare i32 @llvm.ushl.sat.i32(i32 %a, i32 %b) declare i64 @llvm.ushl.sat.i64(i64 %a, i64 %b) declare <4 x i32> @llvm.ushl.sat.v4i32(<4 x i32> %a, <4 x i32> %b)
Overview¶
The ‘llvm.ushl.sat
’ family of intrinsic functions perform unsigned saturating left shift on the first argument.
Arguments¶
The arguments
(%a
and %b
) and the result may be of integer types of any bit width, but they must have the same bit width. %a
is the value to be shifted, and %b
is the amount to shift by. If b
is (statically or dynamically) equal to or larger than the integer bit width of the arguments, the result is a poison value. If the arguments are vectors, each vector element of
a
is shifted by the corresponding shift amount in b
.
Semantics:¶
The maximum value this operation can clamp to is the largest unsigned value representable by the bit width of the arguments.
Examples¶
%res = call i4 @llvm.ushl.sat.i4(i4 2, i4 1) ; %res = 4 %res = call i4 @llvm.ushl.sat.i4(i4 3, i4 3) ; %res = 15
Fixed Point Arithmetic Intrinsics¶
A fixed point number represents a real data type for a number that has a fixed number of digits after a radix point (equivalent to the decimal point ‘.’). The number of digits after the radix point is referred as the scale. These are useful for representing fractional values to a specific precision. The following intrinsics perform fixed point arithmetic operations on 2 operands of the same scale, specified as the third argument.
The llvm.*mul.fix
family of intrinsic functions represents a multiplication of fixed point numbers through
scaled integers. Therefore, fixed point multiplication can be represented as
%result = call i4 @llvm.smul.fix.i4(i4 %a, i4 %b, i32 %scale) ; Expands to %a2 = sext i4 %a to i8 %b2 = sext i4 %b to i8 %mul = mul nsw nuw i8 %a2, %b2 %scale2 = trunc i32 %scale to i8 %r = ashr i8 %mul, i8 %scale2 ; this is for a target rounding down towards negative infinity %result = trunc i8 %r to i4
The llvm.*div.fix
family of intrinsic functions represents a division of fixed point numbers through scaled integers. Fixed point division can be represented as:
%result call i4 @llvm.sdiv.fix.i4(i4 %a, i4 %b, i32 %scale) ; Expands to %a2 = sext i4 %a to i8 %b2 = sext i4 %b to i8 %scale2 = trunc i32 %scale to i8 %a3 = shl i8 %a2, %scale2 %r = sdiv i8 %a3, %b2 ; this is for a target rounding towards zero %result = trunc i8 %r to i4
For each of these functions, if the result cannot be represented exactly with the provided scale, the result is rounded. Rounding is unspecified since preferred rounding may vary for different targets. Rounding is specified through a target hook. Different pipelines should legalize or optimize this using the rounding specified by this hook if it is provided. Operations like constant folding, instruction combining, KnownBits, and ValueTracking should also use this hook, if provided, and not assume the direction of rounding. A rounded result must always be within one unit of precision from the true result. That is, the error between the returned result and the true result must be less than 1/2^(scale).
‘llvm.smul.fix.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.smul.fix
on any integer bit width or vectors of
integers.
declare i16 @llvm.smul.fix.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.smul.fix.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.smul.fix.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.smul.fix.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.smul.fix
’ family of intrinsic functions perform signed fixed point multiplication on 2 arguments of the same scale.
Arguments¶
The arguments (%a and %b) and the result may
be of integer types of any bit width, but they must have the same bit width. The arguments may also work with int vectors of the same length and int size. %a
and %b
are the two values that will undergo signed fixed point multiplication. The argument %scale
represents the scale of both operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point multiplication on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
It is undefined behavior if the result value does not fit within the range of the fixed point type.
Examples¶
%res = call i4 @llvm.smul.fix.i4(i4 3, i4 2, i32 0) ; %res = 6 (2 x 3 = 6) %res = call i4 @llvm.smul.fix.i4(i4 3, i4 2, i32 1) ; %res = 3 (1.5 x 1 = 1.5) %res = call i4 @llvm.smul.fix.i4(i4 3, i4 -2, i32 1) ; %res = -3 (1.5 x -1 = -1.5) ; The result in the following could be rounded up to -2 or down to -2.5 %res = call i4 @llvm.smul.fix.i4(i4 3, i4 -3, i32 1) ; %res = -5 (or -4) (1.5 x -1.5 = -2.25)
‘llvm.umul.fix.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.umul.fix
on any integer bit width or vectors of integers.
declare i16 @llvm.umul.fix.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.umul.fix.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.umul.fix.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.umul.fix.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.umul.fix
’ family of intrinsic functions perform unsigned fixed point multiplication on 2 arguments of the same
scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. The arguments may also work with int vectors of the same length and int size. %a
and %b
are the two values that will undergo unsigned fixed point multiplication. The argument %scale
represents the scale
of both operands, and must be a constant integer.
Semantics:¶
This operation performs unsigned fixed point multiplication on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
It is undefined behavior if the result value does not fit within the range of the fixed point type.
Examples¶
%res = call i4 @llvm.umul.fix.i4(i4 3, i4 2, i32 0) ; %res = 6 (2 x 3 = 6) %res = call i4 @llvm.umul.fix.i4(i4 3, i4 2, i32 1) ; %res = 3 (1.5 x 1 = 1.5) ; The result in the following could be rounded down to 3.5 or up to 4 %res = call i4 @llvm.umul.fix.i4(i4 15, i4 1, i32 1) ; %res = 7 (or 8) (7.5 x 0.5 = 3.75)
‘llvm.smul.fix.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.smul.fix.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.smul.fix.sat.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.smul.fix.sat.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.smul.fix.sat.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.smul.fix.sat.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.smul.fix.sat
’ family of intrinsic functions perform signed fixed point saturating multiplication on 2 arguments of the same scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have
the same bit width. %a
and %b
are the two values that will undergo signed fixed point multiplication. The argument %scale
represents the scale of both operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point multiplication on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
The maximum value this operation can clamp to is the largest signed value representable by the bit width of the first 2 arguments. The minimum value is the smallest signed value representable by this bit width.
Examples¶
%res = call i4 @llvm.smul.fix.sat.i4(i4 3, i4 2, i32 0) ; %res = 6 (2 x 3 = 6) %res = call i4 @llvm.smul.fix.sat.i4(i4 3, i4 2, i32 1) ; %res = 3 (1.5 x 1 = 1.5) %res = call i4 @llvm.smul.fix.sat.i4(i4 3, i4 -2, i32 1) ; %res = -3 (1.5 x -1 = -1.5) ; The result in the following could be rounded up to -2 or down to -2.5 %res = call i4 @llvm.smul.fix.sat.i4(i4 3, i4 -3, i32 1) ; %res = -5 (or -4) (1.5 x -1.5 = -2.25) ; Saturation %res = call i4 @llvm.smul.fix.sat.i4(i4 7, i4 2, i32 0) ; %res = 7 %res = call i4 @llvm.smul.fix.sat.i4(i4 7, i4 4, i32 2) ; %res = 7 %res = call i4 @llvm.smul.fix.sat.i4(i4 -8, i4 5, i32 2) ; %res = -8 %res = call i4 @llvm.smul.fix.sat.i4(i4 -8, i4 -2, i32 1) ; %res = 7 ; Scale can affect the saturation result %res = call i4 @llvm.smul.fix.sat.i4(i4 2, i4 4, i32 0) ; %res = 7 (2 x 4 -> clamped to 7) %res = call i4 @llvm.smul.fix.sat.i4(i4 2, i4 4, i32 1) ; %res = 4 (1 x 2 = 2)
‘llvm.umul.fix.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.umul.fix.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.umul.fix.sat.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.umul.fix.sat.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.umul.fix.sat.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.umul.fix.sat.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.umul.fix.sat
’ family of intrinsic functions perform unsigned fixed point saturating multiplication on 2 arguments
of the same scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo unsigned fixed point multiplication. The argument %scale
represents the scale of both operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point multiplication on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
The maximum value this operation can clamp to is the largest unsigned value representable by the bit width of the first 2 arguments. The minimum value is the smallest unsigned value representable by this bit width (zero).
Examples¶
%res = call i4 @llvm.umul.fix.sat.i4(i4 3, i4 2, i32 0) ; %res = 6 (2 x 3 = 6) %res = call i4 @llvm.umul.fix.sat.i4(i4 3, i4 2, i32 1) ; %res = 3 (1.5 x 1 = 1.5) ; The result in the following could be rounded down to 2 or up to 2.5 %res = call i4 @llvm.umul.fix.sat.i4(i4 3, i4 3, i32 1) ; %res = 4 (or 5) (1.5 x 1.5 = 2.25) ; Saturation %res = call i4 @llvm.umul.fix.sat.i4(i4 8, i4 2, i32 0) ; %res = 15 (8 x 2 -> clamped to 15) %res = call i4 @llvm.umul.fix.sat.i4(i4 8, i4 8, i32 2) ; %res = 15 (2 x 2 -> clamped to 3.75) ; Scale can affect the saturation result %res = call i4 @llvm.umul.fix.sat.i4(i4 2, i4 4, i32 0) ; %res = 7 (2 x 4 -> clamped to 7) %res = call i4 @llvm.umul.fix.sat.i4(i4 2, i4 4, i32 1) ; %res = 4 (1 x 2 = 2)
‘llvm.sdiv.fix.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.sdiv.fix
on any integer bit width or vectors of integers.
declare i16 @llvm.sdiv.fix.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.sdiv.fix.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.sdiv.fix.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.sdiv.fix.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.sdiv.fix
’ family of intrinsic functions perform signed fixed point division on 2 arguments of the same scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they
must have the same bit width. The arguments may also work with int vectors of the same length and int size. %a
and %b
are the two values that will undergo signed fixed point division. The argument %scale
represents the scale of both operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point division on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
It is undefined behavior if the result value does not fit within the range of the fixed point type, or if the second argument is zero.
Examples¶
%res = call i4 @llvm.sdiv.fix.i4(i4 6, i4 2, i32 0) ; %res = 3 (6 / 2 = 3) %res = call i4 @llvm.sdiv.fix.i4(i4 6, i4 4, i32 1) ; %res = 3 (3 / 2 = 1.5) %res = call i4 @llvm.sdiv.fix.i4(i4 3, i4 -2, i32 1) ; %res = -3 (1.5 / -1 = -1.5) ; The result in the following could be rounded up to 1 or down to 0.5 %res = call i4 @llvm.sdiv.fix.i4(i4 3, i4 4, i32 1) ; %res = 2 (or 1) (1.5 / 2 = 0.75)
‘llvm.udiv.fix.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.udiv.fix
on any integer bit width or vectors of integers.
declare i16 @llvm.udiv.fix.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.udiv.fix.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.udiv.fix.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.udiv.fix.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.udiv.fix
’ family of intrinsic functions perform unsigned fixed point division on 2 arguments of the same
scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. The arguments may also work with int vectors of the same length and int size. %a
and %b
are the two values that will undergo unsigned fixed point division. The argument %scale
represents the scale of both
operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point division on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
It is undefined behavior if the result value does not fit within the range of the fixed point type, or if the second argument is zero.
Examples¶
%res = call i4 @llvm.udiv.fix.i4(i4 6, i4 2, i32 0) ; %res = 3 (6 / 2 = 3) %res = call i4 @llvm.udiv.fix.i4(i4 6, i4 4, i32 1) ; %res = 3 (3 / 2 = 1.5) %res = call i4 @llvm.udiv.fix.i4(i4 1, i4 -8, i32 4) ; %res = 2 (0.0625 / 0.5 = 0.125) ; The result in the following could be rounded up to 1 or down to 0.5 %res = call i4 @llvm.udiv.fix.i4(i4 3, i4 4, i32 1) ; %res = 2 (or 1) (1.5 / 2 = 0.75)
‘llvm.sdiv.fix.sat.*
’ Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.sdiv.fix.sat
on any integer bit width or vectors of
integers.
declare i16 @llvm.sdiv.fix.sat.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.sdiv.fix.sat.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.sdiv.fix.sat.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.sdiv.fix.sat.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.sdiv.fix.sat
’ family of intrinsic functions perform signed fixed point saturating division on 2 arguments of the same scale.
Arguments¶
The arguments (%a and %b) and the result
may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo signed fixed point division. The argument %scale
represents the scale of both operands, and must be a constant integer.
Semantics:¶
This operation performs fixed point division on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
The maximum value this operation can clamp to is the largest signed value representable by the bit width of the first 2 arguments. The minimum value is the smallest signed value representable by this bit width.
It is undefined behavior if the second argument is zero.
Examples¶
%res = call i4 @llvm.sdiv.fix.sat.i4(i4 6, i4 2, i32 0) ; %res = 3 (6 / 2 = 3) %res = call i4 @llvm.sdiv.fix.sat.i4(i4 6, i4 4, i32 1) ; %res = 3 (3 / 2 = 1.5) %res = call i4 @llvm.sdiv.fix.sat.i4(i4 3, i4 -2, i32 1) ; %res = -3 (1.5 / -1 = -1.5) ; The result in the following could be rounded up to 1 or down to 0.5 %res = call i4 @llvm.sdiv.fix.sat.i4(i4 3, i4 4, i32 1) ; %res = 2 (or 1) (1.5 / 2 = 0.75) ; Saturation %res = call i4 @llvm.sdiv.fix.sat.i4(i4 -8, i4 -1, i32 0) ; %res = 7 (-8 / -1 = 8 => 7) %res = call i4 @llvm.sdiv.fix.sat.i4(i4 4, i4 2, i32 2) ; %res = 7 (1 / 0.5 = 2 => 1.75) %res = call i4 @llvm.sdiv.fix.sat.i4(i4 -4, i4 1, i32 2) ; %res = -8 (-1 / 0.25 = -4 => -2)
‘llvm.udiv.fix.sat.*
’
Intrinsics¶
Syntax¶
This is an overloaded intrinsic. You can use llvm.udiv.fix.sat
on any integer bit width or vectors of integers.
declare i16 @llvm.udiv.fix.sat.i16(i16 %a, i16 %b, i32 %scale) declare i32 @llvm.udiv.fix.sat.i32(i32 %a, i32 %b, i32 %scale) declare i64 @llvm.udiv.fix.sat.i64(i64 %a, i64 %b, i32 %scale) declare <4 x i32> @llvm.udiv.fix.sat.v4i32(<4 x i32> %a, <4 x i32> %b, i32 %scale)
Overview¶
The ‘llvm.udiv.fix.sat
’ family of intrinsic functions perform unsigned fixed point
saturating division on 2 arguments of the same scale.
Arguments¶
The arguments (%a and %b) and the result may be of integer types of any bit width, but they must have the same bit width. %a
and %b
are the two values that will undergo unsigned fixed point division. The argument %scale
represents the scale of both operands, and must be a
constant integer.
Semantics:¶
This operation performs fixed point division on the 2 arguments of a specified scale. The result will also be returned in the same scale specified in the third argument.
If the result value cannot be precisely represented in the given scale, the value is rounded up or down to the closest representable value. The rounding direction is unspecified.
The maximum value this operation can clamp to is the largest unsigned value representable by the bit width of the first 2 arguments. The minimum value is the smallest unsigned value representable by this bit width (zero).
It is undefined behavior if the second argument is zero.
Examples¶
%res = call i4 @llvm.udiv.fix.sat.i4(i4 6, i4 2, i32 0) ; %res = 3 (6 / 2 = 3) %res = call i4 @llvm.udiv.fix.sat.i4(i4 6, i4 4, i32 1) ; %res = 3 (3 / 2 = 1.5) ; The result in the following could be rounded down to 0.5 or up to 1 %res = call i4 @llvm.udiv.fix.sat.i4(i4 3, i4 4, i32 1) ; %res = 1 (or 2) (1.5 / 2 = 0.75) ; Saturation %res = call i4 @llvm.udiv.fix.sat.i4(i4 8, i4 2, i32 2) ; %res = 15 (2 / 0.5 = 4 => 3.75)
Specialised Arithmetic Intrinsics¶
‘llvm.canonicalize.*
’
Intrinsic¶
Syntax:¶
declare float @llvm.canonicalize.f32(float %a) declare double @llvm.canonicalize.f64(double %b)
Overview:¶
The ‘llvm.canonicalize.*
’ intrinsic returns the platform
specific canonical encoding of a floating-point number. This canonicalization is useful for implementing certain numeric primitives such as frexp. The canonical encoding is defined by IEEE-754-2008 to be:
2.1.8 canonical encoding: The preferred encoding of a floating-point representation in a format. Applied to declets, significands of finite numbers, infinities, and NaNs, especially in decimal formats.
This operation can also be considered equivalent to the IEEE-754-2008 conversion of a floating-point value to the same format. NaNs are handled according to section 6.2.
Examples of non-canonical encodings:
- x87 pseudo denormals, pseudo NaNs, pseudo Infinity, Unnormals. These are converted to a canonical representation per hardware-specific protocol.
- Many normal decimal floating-point numbers have non-canonical alternative encodings.
- Some machines, like GPUs or ARMv7 NEON, do not support subnormal values. These are treated as non-canonical encodings of zero and will be flushed to a zero of the same sign by this operation.
Note that per IEEE-754-2008 6.2, systems that support signaling NaNs with default exception handling must signal an invalid exception, and produce a quiet NaN result.
This function should always be implementable as multiplication by 1.0, provided that the compiler does not constant fold the operation. Likewise, division by 1.0 and llvm.minnum(x, x)
are possible implementations. Addition with -0.0 is also sufficient provided that the rounding mode is not -Infinity.
@llvm.canonicalize
must preserve the equality relation. That is:
(@llvm.canonicalize(x) == x)
is equivalent to(x == x)
(@llvm.canonicalize(x) == @llvm.canonicalize(y))
is equivalent to(x == y)
Additionally, the sign of zero must be conserved: @llvm.canonicalize(-0.0) = -0.0
and @llvm.canonicalize(+0.0) = +0.0
The payload bits of a NaN must be conserved, with two exceptions. First, environments which use only a single canonical representation of NaN must perform said canonicalization. Second, SNaNs must be quieted per the usual methods.
The canonicalization operation may be optimized away if:
- The input is known to be canonical. For example, it was produced by a floating-point operation that is required by the standard to be canonical.
- The result is consumed only by (or fused with) other floating-point operations. That is, the bits of the floating-point value are not examined.
‘llvm.fmuladd.*
’
Intrinsic¶
Syntax:¶
declare float @llvm.fmuladd.f32(float %a, float %b, float %c) declare double @llvm.fmuladd.f64(double %a, double %b, double %c)
Overview:¶
The ‘llvm.fmuladd.*
’ intrinsic functions represent
multiply-add expressions that can be fused if the code generator determines that (a) the target instruction set has support for a fused operation, and (b) that the fused operation is more efficient than the equivalent, separate pair of mul and add instructions.
Arguments:¶
The ‘llvm.fmuladd.*
’ intrinsics each take three arguments: two multiplicands, a and b, and
an addend c.
Semantics:¶
The expression:
%0 = call float @llvm.fmuladd.f32(%a, %b, %c)
is equivalent to the expression a * b + c, except that it is unspecified whether rounding will be performed between the multiplication and addition steps. Fusion is not guaranteed, even if the target platform supports it. If a fused multiply-add is required, the corresponding
llvm.fma intrinsic function should be used instead. This never sets errno, just as ‘llvm.fma.*
’.
Examples:¶
%r2 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) ; yields float:r2 = (a * b) + c
Hardware-Loop Intrinsics¶
LLVM support several intrinsics to mark a loop as a hardware-loop. They are hints to the backend which are required to lower these intrinsics further to target specific instructions, or revert the hardware-loop to a normal loop if target specific restriction are not met and a hardware-loop can’t be generated.
These intrinsics may be modified in the future and are not intended to be used outside the backend. Thus, front-end and mid-level optimizations should not be generating these intrinsics.
‘llvm.set.loop.iterations.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare void @llvm.set.loop.iterations.i32(i32) declare void @llvm.set.loop.iterations.i64(i64)
Overview:¶
The ‘llvm.set.loop.iterations.*
’ intrinsics are used to specify the hardware-loop trip count. They are placed in the loop preheader basic block and are marked as IntrNoDuplicate
to avoid optimizers duplicating
these instructions.
Arguments:¶
The integer operand is the loop trip count of the hardware-loop, and thus not e.g. the loop back-edge taken count.
Semantics:¶
The ‘llvm.set.loop.iterations.*
’ intrinsics do not perform any arithmetic
on their operand. It’s a hint to the backend that can use this to set up the hardware-loop count with a target specific instruction, usually a move of this value to a special register or a hardware-loop instruction.
‘llvm.start.loop.iterations.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.start.loop.iterations.i32(i32) declare i64 @llvm.start.loop.iterations.i64(i64)
Overview:¶
The ‘llvm.start.loop.iterations.*
’ intrinsics are similar to the ‘llvm.set.loop.iterations.*
’ intrinsics, used to specify the hardware-loop trip count but also produce a value identical to the input that can be used as the input to the loop. They are placed in the loop preheader basic block and the output is expected to be the input to the phi for the induction variable of the loop, decremented by the ‘llvm.loop.decrement.reg.*
’.
Arguments:¶
The integer operand is the loop trip count of the hardware-loop, and thus not e.g. the loop back-edge taken count.
Semantics:¶
The ‘llvm.start.loop.iterations.*
’ intrinsics do not perform any arithmetic on their operand. It’s a hint to the backend that can use this
to set up the hardware-loop count with a target specific instruction, usually a move of this value to a special register or a hardware-loop instruction.
‘llvm.test.set.loop.iterations.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare i1 @llvm.test.set.loop.iterations.i32(i32) declare i1 @llvm.test.set.loop.iterations.i64(i64)
Overview:¶
The ‘llvm.test.set.loop.iterations.*
’ intrinsics are used to specify the the loop trip count, and also test that the given count is not zero, allowing it to control entry to a while-loop. They are placed in
the loop preheader’s predecessor basic block, and are marked as IntrNoDuplicate
to avoid optimizers duplicating these instructions.
Arguments:¶
The integer operand is the loop trip count of the hardware-loop, and thus not e.g. the loop back-edge taken count.
Semantics:¶
The ‘llvm.test.set.loop.iterations.*
’ intrinsics do not perform any arithmetic on their operand. It’s a hint to the backend that can use this to set up the hardware-loop count with a target specific instruction, usually a move of this value to a special register or a hardware-loop instruction. The result is the conditional value of whether the given count is not zero.
‘llvm.test.start.loop.iterations.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare {i32, i1} @llvm.test.start.loop.iterations.i32(i32) declare {i64, i1} @llvm.test.start.loop.iterations.i64(i64)
Overview:¶
The ‘llvm.test.start.loop.iterations.*
’ intrinsics are similar to the ‘llvm.test.set.loop.iterations.*
’ and ‘llvm.start.loop.iterations.*
’ intrinsics, used to specify the hardware-loop trip count, but also produce a value identical to the input that can be used as the input to the loop. The second i1 output controls entry to a while-loop.
Arguments:¶
The integer operand is the loop trip count of the hardware-loop, and thus not e.g. the loop back-edge taken count.
Semantics:¶
The ‘llvm.test.start.loop.iterations.*
’ intrinsics do not perform any arithmetic on their operand. It’s a hint to the backend that can use this
to set up the hardware-loop count with a target specific instruction, usually a move of this value to a special register or a hardware-loop instruction. The result is a pair of the input and a conditional value of whether the given count is not zero.
‘llvm.loop.decrement.reg.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.loop.decrement.reg.i32(i32, i32) declare i64 @llvm.loop.decrement.reg.i64(i64, i64)
Overview:¶
The
‘llvm.loop.decrement.reg.*
’ intrinsics are used to lower the loop iteration counter and return an updated value that will be used in the next loop test check.
Arguments:¶
Both arguments must have identical integer types. The first operand is the loop iteration counter. The second operand is the maximum number of elements processed in an iteration.
Semantics:¶
The ‘llvm.loop.decrement.reg.*
’ intrinsics do an integer SUB
of its two operands, which is not allowed to wrap. They return the remaining number of iterations still to be executed, and can be used together with a PHI
, ICMP
and BR
to control the number of loop iterations executed. Any optimisations are allowed to treat it is a SUB
, and it is supported by SCEV,
so it’s the backends responsibility to handle cases where it may be optimised. These intrinsics are marked as IntrNoDuplicate
to avoid optimizers duplicating these instructions.
‘llvm.loop.decrement.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare i1 @llvm.loop.decrement.i32(i32) declare i1 @llvm.loop.decrement.i64(i64)
Overview:¶
The HardwareLoops pass allows the loop decrement value to be specified with an option. It defaults to a loop decrement value of 1, but it can be an unsigned integer value provided by
this option. The ‘llvm.loop.decrement.*
’ intrinsics decrement the loop iteration counter with this value, and return a false predicate if the loop should exit, and true otherwise. This is emitted if the loop counter is not updated via a PHI
node, which can also be controlled with an option.
Arguments:¶
The integer argument is the loop decrement value used to decrement the loop iteration counter.
Semantics:¶
The ‘llvm.loop.decrement.*
’ intrinsics do a SUB
of the loop iteration counter with the given loop decrement value, and return false if the loop should exit, this SUB
is not allowed to wrap. The result is a condition that is used by the conditional branch controlling the loop.
Vector Reduction Intrinsics¶
Horizontal reductions of vectors can be expressed using the following intrinsics. Each one takes a vector operand as an input and applies its respective operation across all elements of the vector, returning a single scalar result of the same element type.
‘llvm.vector.reduce.add.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a) declare i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %a)
Overview:¶
The ‘llvm.vector.reduce.add.*
’ intrinsics do an integer ADD
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.fadd.*
’ Intrinsic¶
Syntax:¶
declare float @llvm.vector.reduce.fadd.v4f32(float %start_value, <4 x float> %a) declare double @llvm.vector.reduce.fadd.v2f64(double %start_value, <2 x double> %a)
Overview:¶
The ‘llvm.vector.reduce.fadd.*
’ intrinsics do a floating-point ADD
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
If the intrinsic call has the ‘reassoc’ flag set, then the reduction will not preserve the associativity of an equivalent scalarized counterpart. Otherwise the reduction will be sequential, thus implying that the operation respects the associativity of a scalarized reduction. That is, the reduction begins with the start value and performs an fadd operation with consecutively increasing vector element indices. See the following pseudocode:
float sequential_fadd(start_value, input_vector) result = start_value for i = 0 to length(input_vector) result = result + input_vector[i] return result
Arguments:¶
The first argument to this intrinsic is a scalar start value for the reduction. The type of the start value matches the element-type of the vector input. The second argument must be a vector of floating-point values.
To ignore the start value, negative zero (-0.0
) can be used, as it is the neutral value of floating point addition.
Examples:¶
%unord = call reassoc float @llvm.vector.reduce.fadd.v4f32(float -0.0, <4 x float> %input) ; relaxed reduction %ord = call float @llvm.vector.reduce.fadd.v4f32(float %start_value, <4 x float> %input) ; sequential reduction
‘llvm.vector.reduce.mul.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %a) declare i64 @llvm.vector.reduce.mul.v2i64(<2 x i64> %a)
Overview:¶
The ‘llvm.vector.reduce.mul.*
’ intrinsics do an integer MUL
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.fmul.*
’ Intrinsic¶
Syntax:¶
declare float @llvm.vector.reduce.fmul.v4f32(float %start_value, <4 x float> %a) declare double @llvm.vector.reduce.fmul.v2f64(double %start_value, <2 x double> %a)
Overview:¶
The ‘llvm.vector.reduce.fmul.*
’ intrinsics do a floating-point MUL
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
If the intrinsic call has the ‘reassoc’ flag set, then the reduction will not preserve the associativity of an equivalent scalarized counterpart. Otherwise the reduction will be sequential, thus implying that the operation respects the associativity of a scalarized reduction. That is, the reduction begins with the start value and performs an fmul operation with consecutively increasing vector element indices. See the following pseudocode:
float sequential_fmul(start_value, input_vector) result = start_value for i = 0 to length(input_vector) result = result * input_vector[i] return result
Arguments:¶
The first argument to this intrinsic is a scalar start value for the reduction. The type of the start value matches the element-type of the vector input. The second argument must be a vector of floating-point values.
To ignore the start value, one (1.0
) can be used, as it is the neutral value of floating point multiplication.
Examples:¶
%unord = call reassoc float @llvm.vector.reduce.fmul.v4f32(float 1.0, <4 x float> %input) ; relaxed reduction %ord = call float @llvm.vector.reduce.fmul.v4f32(float %start_value, <4 x float> %input) ; sequential reduction
‘llvm.vector.reduce.and.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.and.*
’ intrinsics do a bitwise AND
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.or.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.or.*
’ intrinsics do a bitwise OR
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.xor.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.xor.*
’ intrinsics do a bitwise XOR
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.smax.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.smax.*
’ intrinsics do a signed integer MAX
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.smin.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.smin.*
’ intrinsics do a signed integer MIN
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.umax.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.umax.*
’ intrinsics do an unsigned integer MAX
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.umin.*
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %a)
Overview:¶
The ‘llvm.vector.reduce.umin.*
’ intrinsics do an unsigned integer MIN
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
Arguments:¶
The argument to this intrinsic must be a vector of integer values.
‘llvm.vector.reduce.fmax.*
’ Intrinsic¶
Syntax:¶
declare float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a) declare double @llvm.vector.reduce.fmax.v2f64(<2 x double> %a)
Overview:¶
The ‘llvm.vector.reduce.fmax.*
’ intrinsics do a floating-point MAX
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
This instruction has the same comparison semantics as the ‘llvm.maxnum.*
’ intrinsic. That is, the result will always be a number unless all elements of the vector are NaN. For a vector with maximum element
magnitude 0.0 and containing both +0.0 and -0.0 elements, the sign of the result is unspecified.
If the intrinsic call has the nnan
fast-math flag, then the operation can assume that NaNs are not present in the input vector.
Arguments:¶
The argument to this intrinsic must be a vector of floating-point values.
‘llvm.vector.reduce.fmin.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare float @llvm.vector.reduce.fmin.v4f32(<4 x float> %a) declare double @llvm.vector.reduce.fmin.v2f64(<2 x double> %a)
Overview:¶
The ‘llvm.vector.reduce.fmin.*
’ intrinsics do a floating-point MIN
reduction of a vector, returning the result as a scalar. The return type matches the element-type of the vector input.
This instruction has the same comparison semantics as the ‘llvm.minnum.*
’ intrinsic. That is, the result will always be a number unless all elements of the vector are NaN. For a vector with minimum element
magnitude 0.0 and containing both +0.0 and -0.0 elements, the sign of the result is unspecified.
If the intrinsic call has the nnan
fast-math flag, then the operation can assume that NaNs are not present in the input vector.
Arguments:¶
The argument to this intrinsic must be a vector of floating-point values.
‘llvm.vector.insert
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
; Insert fixed type into scalable type declare <vscale x 4 x float> @llvm.vector.insert.nxv4f32.v4f32(<vscale x 4 x float> %vec, <4 x float> %subvec, i64 <idx>) declare <vscale x 2 x double> @llvm.vector.insert.nxv2f64.v2f64(<vscale x 2 x double> %vec, <2 x double> %subvec, i64 <idx>) ; Insert scalable type into scalable type declare <vscale x 4 x float> @llvm.vector.insert.nxv4f64.nxv2f64(<vscale x 4 x float> %vec, <vscale x 2 x float> %subvec, i64 <idx>) ; Insert fixed type into fixed type declare <4 x double> @llvm.vector.insert.v4f64.v2f64(<4 x double> %vec, <2 x double> %subvec, i64 <idx>)
Overview:¶
The ‘llvm.vector.insert.*
’ intrinsics insert a vector into another vector starting from a given index. The return type matches the type of the vector we insert into. Conceptually, this can be used to build a scalable vector out of non-scalable vectors, however this intrinsic can also be used on purely fixed types.
Scalable vectors can only be inserted into other scalable vectors.
Arguments:¶
The vec
is the vector which subvec
will be inserted into. The subvec
is the vector that will be inserted.
idx
represents the starting element number at which subvec
will be inserted. idx
must be a constant multiple of subvec
’s known minimum vector length. If subvec
is a scalable vector, idx
is first scaled by the
runtime scaling factor of subvec
. The elements of vec
starting at idx
are overwritten with subvec
. Elements idx
through (idx
+ num_elements(subvec
) - 1) must be valid vec
indices. If this condition cannot be determined statically but is false at runtime, then the result vector is a poison value.
‘llvm.experimental.vector.reverse
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <2 x i8> @llvm.experimental.vector.reverse.v2i8(<2 x i8> %a) declare <vscale x 4 x i32> @llvm.experimental.vector.reverse.nxv4i32(<vscale x 4 x i32> %a)
Overview:¶
The ‘llvm.experimental.vector.reverse.*
’ intrinsics reverse a vector. The intrinsic takes a single vector and returns a vector of matching type but with the original lane order reversed. These intrinsics work for both fixed and scalable vectors. While this intrinsic is marked as experimental the recommended way to express reverse operations for fixed-width vectors is still to use a shufflevector, as that may
allow for more optimization opportunities.
Arguments:¶
The argument to this intrinsic must be a vector.
‘llvm.experimental.vector.splice
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <2 x double> @llvm.experimental.vector.splice.v2f64(<2 x double> %vec1, <2 x double> %vec2, i32 %imm) declare <vscale x 4 x i32> @llvm.experimental.vector.splice.nxv4i32(<vscale x 4 x i32> %vec1, <vscale x 4 x i32> %vec2, i32 %imm)
Overview:¶
The ‘llvm.experimental.vector.splice.*
’ intrinsics construct a vector by concatenating elements from the first input vector with elements of the second input vector, returning a vector of the same type as the input vectors. The signed immediate, modulo the number of elements in the vector, is the index into the first vector from which to extract the result value. This means conceptually that for a positive immediate, a vector is extracted from concat(%vec1, %vec2)
starting at index imm
, whereas for a negative
immediate, it extracts -imm
trailing elements from the first vector, and the remaining elements from %vec2
.
These intrinsics work for both fixed and scalable vectors. While this intrinsic is marked as experimental, the recommended way to express this operation for fixed-width vectors is still to use a shufflevector, as that may allow for more optimization opportunities.
For example:
llvm.experimental.vector.splice(<A,B,C,D>, <E,F,G,H>, 1) ==> <B, C, D, E> ; index llvm.experimental.vector.splice(<A,B,C,D>, <E,F,G,H>, -3) ==> <B, C, D, E> ; trailing elements
Arguments:¶
The first two operands are vectors with the same type. The start index is imm modulo the runtime number of elements in the source vector. For a fixed-width vector <N x eltty>, imm is a signed integer constant in the range -N <= imm < N. For a scalable vector <vscale x N x eltty>, imm is a signed integer constant in the range -X <= imm < X where X=vscale_range_min * N.
‘llvm.experimental.stepvector
’ Intrinsic¶
This is an overloaded intrinsic. You can use llvm.experimental.stepvector
to generate a vector whose lane values comprise the linear sequence <0, 1, 2, …>. It is primarily intended
for scalable vectors.
declare <vscale x 4 x i32> @llvm.experimental.stepvector.nxv4i32() declare <vscale x 8 x i16> @llvm.experimental.stepvector.nxv8i16()
The ‘llvm.experimental.stepvector
’ intrinsics are used to create vectors of integers whose elements contain a linear sequence of values starting from 0 with a step of 1. This experimental intrinsic can only be used for vectors with integer elements that are at least 8 bits in size. If the sequence value exceeds the allowed limit for the element type then the result for that lane is undefined.
These intrinsics work for both fixed and scalable vectors. While this intrinsic is marked as experimental, the recommended way to express this operation for fixed-width vectors is still to generate a constant vector instead.
Matrix Intrinsics¶
Operations on matrixes requiring shape information (like number of rows/columns or
the memory layout) can be expressed using the matrix intrinsics. These intrinsics require matrix dimensions to be passed as immediate arguments, and matrixes are passed and returned as vectors. This means that for a R
x C
matrix, element i
of column j
is at index j * R + i
in the corresponding vector, with indices starting at 0. Currently column-major layout is assumed. The intrinsics support both integer and floating point matrixes.
‘llvm.matrix.transpose.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare vectorty @llvm.matrix.transpose.*(vectorty %In, i32 <Rows>, i32 <Cols>)
Overview:¶
The ‘llvm.matrix.transpose.*
’ intrinsics treat %In
as a <Rows> x
<Cols>
matrix and return the transposed matrix in the result vector.
Arguments:¶
The first argument %In
is a vector that corresponds to a <Rows> x
<Cols>
matrix. Thus, arguments <Rows>
and <Cols>
correspond to the number of rows and columns, respectively, and must be positive, constant integers. The returned vector must have <Rows> * <Cols>
elements, and have the same float or integer element type as %In
.
‘llvm.matrix.multiply.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare vectorty @llvm.matrix.multiply.*(vectorty %A, vectorty %B, i32 <OuterRows>, i32 <Inner>, i32 <OuterColumns>)
Overview:¶
The ‘llvm.matrix.multiply.*
’ intrinsics treat %A
as a <OuterRows> x
<Inner>
matrix, %B
as a <Inner> x <OuterColumns>
matrix, and multiplies them. The result matrix is returned in the
result vector.
Arguments:¶
The first vector argument %A
corresponds to a matrix with <OuterRows> *
<Inner>
elements, and the second argument %B
to a matrix with <Inner> * <OuterColumns>
elements. Arguments <OuterRows>
, <Inner>
and <OuterColumns>
must be positive, constant integers. The returned vector must have <OuterRows> * <OuterColumns>
elements. Vectors %A
, %B
, and the returned vector
all have the same float or integer element type.
‘llvm.matrix.column.major.load.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare vectorty @llvm.matrix.column.major.load.*( ptrty %Ptr, i64 %Stride, i1 <IsVolatile>, i32 <Rows>, i32 <Cols>)
Overview:¶
The ‘llvm.matrix.column.major.load.*
’ intrinsics load a <Rows> x <Cols>
matrix using a stride of %Stride
to compute the start address of the different columns. The offset is computed using %Stride
’s bitwidth. This allows for convenient loading of sub matrixes. If <IsVolatile>
is true, the intrinsic is considered a
volatile memory access. The result matrix is returned in the result vector. If the %Ptr
argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
Arguments:¶
The first argument %Ptr
is a pointer type to the returned
vector type, and corresponds to the start address to load from. The second argument %Stride
is a positive, constant integer with %Stride >= <Rows>
. %Stride
is used to compute the column memory addresses. I.e., for a column C
, its start memory addresses is calculated with %Ptr + C * %Stride
. The third Argument <IsVolatile>
is a boolean value. The fourth and fifth arguments, <Rows>
and <Cols>
, correspond to the number of rows and columns, respectively, and must be positive, constant integers. The returned
vector must have <Rows> * <Cols>
elements.
The align parameter attribute can be provided for the %Ptr
arguments.
‘llvm.matrix.column.major.store.*
’
Intrinsic¶
Syntax:¶
declare void @llvm.matrix.column.major.store.*( vectorty %In, ptrty %Ptr, i64 %Stride, i1 <IsVolatile>, i32 <Rows>, i32 <Cols>)
Overview:¶
The ‘llvm.matrix.column.major.store.*
’ intrinsics store
the <Rows> x
<Cols>
matrix in %In
to memory using a stride of %Stride
between columns. The offset is computed using %Stride
’s bitwidth. If <IsVolatile>
is true, the intrinsic is considered a volatile memory access.
If the %Ptr
argument is known to be aligned to some boundary, this can be specified as an attribute on the argument.
Arguments:¶
The first argument %In
is a vector that corresponds to a <Rows> x
<Cols>
matrix to be stored to memory. The second argument %Ptr
is a pointer to the vector type of %In
, and is the start address of the matrix in memory. The third argument %Stride
is a positive, constant integer with %Stride >= <Rows>
. %Stride
is used to compute the column memory addresses. I.e., for a column C
,
its start memory addresses is calculated with %Ptr + C * %Stride
. The fourth argument <IsVolatile>
is a boolean value. The arguments <Rows>
and <Cols>
correspond to the number of rows and columns, respectively, and must be positive, constant integers.
The align parameter attribute can be provided for the %Ptr
arguments.
Half Precision Floating-Point Intrinsics¶
For most target platforms, half precision floating-point is a storage-only format. This means that it is a dense encoding (in memory) but does not support computation in the format.
This means that code must first load the half-precision floating-point value as an i16, then convert it to float with llvm.convert.from.fp16. Computation can then be performed on the float value (including extending to double etc). To store the value back to memory, it is first converted to float if needed, then converted to i16 with llvm.convert.to.fp16, then storing as an i16 value.
‘llvm.convert.to.fp16
’ Intrinsic¶
Syntax:¶
declare i16 @llvm.convert.to.fp16.f32(float %a) declare i16 @llvm.convert.to.fp16.f64(double %a)
Overview:¶
The ‘llvm.convert.to.fp16
’ intrinsic function performs a conversion from a conventional floating-point type to half precision floating-point format.
Arguments:¶
The intrinsic function contains single argument - the value to be converted.
Semantics:¶
The ‘llvm.convert.to.fp16
’ intrinsic function performs a conversion from a conventional floating-point format to half precision floating-point format. The return value
is an i16
which contains the converted number.
Examples:¶
%res = call i16 @llvm.convert.to.fp16.f32(float %a) store i16 %res, i16* @x, align 2
‘llvm.convert.from.fp16
’
Intrinsic¶
Syntax:¶
declare float @llvm.convert.from.fp16.f32(i16 %a) declare double @llvm.convert.from.fp16.f64(i16 %a)
Overview:¶
The ‘llvm.convert.from.fp16
’ intrinsic function
performs a conversion from half precision floating-point format to single precision floating-point format.
Arguments:¶
The intrinsic function contains single argument - the value to be converted.
Semantics:¶
The
‘llvm.convert.from.fp16
’ intrinsic function performs a conversion from half single precision floating-point format to single precision floating-point format. The input half-float value is represented by an i16
value.
Examples:¶
%a = load i16, ptr @x, align 2 %res = call float @llvm.convert.from.fp16(i16 %a)
Saturating floating-point to integer conversions¶
The fptoui
and fptosi
instructions return a poison value if the rounded-towards-zero value is not representable by the result
type. These intrinsics provide an alternative conversion, which will saturate towards the smallest and largest representable integer values instead.
‘llvm.fptoui.sat.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fptoui.sat
on any floating-point argument type and any integer result type, or vectors thereof. Not all targets may support all types, however.
declare i32 @llvm.fptoui.sat.i32.f32(float %f) declare i19 @llvm.fptoui.sat.i19.f64(double %f) declare <4 x i100> @llvm.fptoui.sat.v4i100.v4f128(<4 x fp128> %f)
Overview:¶
This intrinsic converts the argument into an unsigned integer using saturating semantics.
Arguments:¶
The argument may be any floating-point or vector of floating-point type. The return value may be any integer or vector of integer type. The number of vector elements in argument and return must be the same.
Semantics:¶
The conversion to integer is performed subject to the following rules:
- If the argument is any NaN, zero is returned.
- If the argument is smaller than zero (this includes negative infinity), zero is returned.
- If the argument is larger than the largest representable unsigned integer of the result type (this includes positive infinity), the largest representable unsigned integer is returned.
- Otherwise, the result of rounding the argument towards zero is returned.
Example:¶
%a = call i8 @llvm.fptoui.sat.i8.f32(float 123.9) ; yields i8: 123 %b = call i8 @llvm.fptoui.sat.i8.f32(float -5.7) ; yields i8: 0 %c = call i8 @llvm.fptoui.sat.i8.f32(float 377.0) ; yields i8: 255 %d = call i8 @llvm.fptoui.sat.i8.f32(float 0xFFF8000000000000) ; yields i8: 0
‘llvm.fptosi.sat.*
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.fptosi.sat
on any floating-point argument type and any integer result type, or vectors thereof. Not all targets may support all types, however.
declare i32 @llvm.fptosi.sat.i32.f32(float %f) declare i19 @llvm.fptosi.sat.i19.f64(double %f) declare <4 x i100> @llvm.fptosi.sat.v4i100.v4f128(<4 x fp128> %f)
Overview:¶
This intrinsic converts the argument into a signed integer using saturating semantics.
Arguments:¶
The argument may be any floating-point or vector of floating-point type. The return value may be any integer or vector of integer type. The number of vector elements in argument and return must be the same.
Semantics:¶
The conversion to integer is performed subject to the following rules:
- If the argument is any NaN, zero is returned.
- If the argument is smaller than the smallest representable signed integer of the result type (this includes negative infinity), the smallest representable signed integer is returned.
- If the argument is larger than the largest representable signed integer of the result type (this includes positive infinity), the largest representable signed integer is returned.
- Otherwise, the result of rounding the argument towards zero is returned.
Example:¶
%a = call i8 @llvm.fptosi.sat.i8.f32(float 23.9) ; yields i8: 23 %b = call i8 @llvm.fptosi.sat.i8.f32(float -130.8) ; yields i8: -128 %c = call i8 @llvm.fptosi.sat.i8.f32(float 999.0) ; yields i8: 127 %d = call i8 @llvm.fptosi.sat.i8.f32(float 0xFFF8000000000000) ; yields i8: 0
Trampoline Intrinsics¶
These intrinsics make it possible to excise one parameter, marked with the nest attribute, from a function. The result is a callable function pointer lacking the nest parameter - the caller does not need to provide a value for it. Instead, the value to use is stored in advance in a “trampoline”, a block of memory usually allocated on the stack, which also contains code to splice the nest value into the argument list. This is used to implement the GCC nested function address extension.
For example, if the function is i32 f(ptr nest %c, i32 %x, i32 %y)
then the resulting function pointer has signature i32 (i32, i32)
. It can be created as
follows:
%tramp = alloca [10 x i8], align 4 ; size and alignment only correct for X86 call ptr @llvm.init.trampoline(ptr %tramp, ptr @f, ptr %nval) %fp = call ptr @llvm.adjust.trampoline(ptr %tramp)
The call %val = call i32 %fp(i32 %x, i32 %y)
is then equivalent to %val = call i32 %f(ptr %nval, i32 %x, i32 %y)
.
‘llvm.init.trampoline
’ Intrinsic¶
Syntax:¶
declare void @llvm.init.trampoline(ptr <tramp>, ptr <func>, ptr <nval>)
Overview:¶
This fills the memory pointed to by tramp
with executable code, turning it into a trampoline.
Arguments:¶
The llvm.init.trampoline
intrinsic takes three arguments, all pointers. The tramp
argument
must point to a sufficiently large and sufficiently aligned block of memory; this memory is written to by the intrinsic. Note that the size and the alignment are target-specific - LLVM currently provides no portable way of determining them, so a front-end that generates this intrinsic needs to have some target-specific knowledge. The func
argument must hold a function.
Semantics:¶
The block of memory pointed to by tramp
is filled with target dependent code, turning it into a function. Then tramp
needs to be passed to llvm.adjust.trampoline to get a pointer which can be bitcast (to a new function) and called. The new function’s signature is the same as that of
func
with any arguments marked with the nest
attribute removed. At most one such nest
argument is allowed, and it must be of pointer type. Calling the new function is equivalent to calling func
with the same argument list, but with nval
used for the missing nest
argument. If, after calling llvm.init.trampoline
, the memory pointed to by tramp
is modified, then the effect of any later call to the returned function pointer is undefined.
‘llvm.adjust.trampoline
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.adjust.trampoline(ptr <tramp>)
Overview:¶
This performs any required machine-specific adjustment to the address of a trampoline (passed as tramp
).
Arguments:¶
tramp
must point to a block of memory which already has trampoline code filled in by a previous call to llvm.init.trampoline.
Semantics:¶
On some architectures the address of the code to be executed needs to be different than the address where the trampoline is actually stored. This intrinsic returns the executable address corresponding to tramp
after performing the required machine
specific adjustments. The pointer returned can then be bitcast and executed.
Vector Predication Intrinsics¶
VP intrinsics are intended for predicated SIMD/vector code. A typical VP operation takes a vector mask and an explicit vector length parameter as in:
<W x T> llvm.vp.<opcode>.*(<W x T> %x, <W x T> %y, <W x i1> %mask, i32 %evl)
The vector mask parameter (%mask) always has a vector of i1 type, for example <32 x i1>. The explicit vector length parameter always has the type i32 and is an unsigned integer value. The explicit vector length parameter (%evl) is in the range:
0 <= %evl <= W, where W is the number of vector elements
Note that for
scalable vector types W
is the runtime length of the vector.
The VP intrinsic has undefined behavior if %evl > W
. The explicit vector length (%evl) creates a mask, %EVLmask, with all elements 0 <= i < %evl
set to True, and all other lanes %evl <= i < W
to False. A new mask %M is calculated with an element-wise AND from %mask and %EVLmask:
A vector operation <opcode>
on vectors A
and B
calculates:
A <opcode> B = { A[i] <opcode> B[i] M[i] = True, and { undef otherwise
Optimization Hint¶
Some targets, such as AVX512, do not support the %evl parameter in hardware. The use of an effective %evl is discouraged for those targets. The function TargetTransformInfo::hasActiveVectorLength()
returns true when the target has native support for
%evl.
‘llvm.vp.select.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.select.v16i32 (<16 x i1> <condition>, <16 x i32> <on_true>, <16 x i32> <on_false>, i32 <evl>) declare <vscale x 4 x i64> @llvm.vp.select.nxv4i64 (<vscale x 4 x i1> <condition>, <vscale x 4 x i64> <on_true>, <vscale x 4 x i64> <on_false>, i32 <evl>)
Overview:¶
The ‘llvm.vp.select
’ intrinsic is used to choose one value based on a condition vector, without IR-level branching.
Arguments:¶
The first operand is a vector of i1
and indicates the condition. The second operand is the value that
is selected where the condition vector is true. The third operand is the value that is selected where the condition vector is false. The vectors must be of the same size. The fourth operand is the explicit vector length.
- The optional
fast-math flags
marker indicates that the select has one or more fast-math flags. These are optimization hints to enable otherwise unsafe floating-point optimizations. Fast-math flags are only valid for selects that return a floating-point scalar or vector type, or an array (nested to any depth) of floating-point scalar or vector types.
Semantics:¶
The intrinsic selects lanes from the second and third operand depending on a condition vector.
All result lanes at positions greater or equal than %evl
are
undefined. For all lanes below %evl
where the condition vector is true the lane is taken from the second operand. Otherwise, the lane is taken from the third operand.
Example:¶
%r = call <4 x i32> @llvm.vp.select.v4i32(<4 x i1> %cond, <4 x i32> %on_true, <4 x i32> %on_false, i32 %evl) ;;; Expansion. ;; Any result is legal on lanes at and above %evl. %also.r = select <4 x i1> %cond, <4 x i32> %on_true, <4 x i32> %on_false
‘llvm.vp.merge.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.merge.v16i32 (<16 x i1> <condition>, <16 x i32> <on_true>, <16 x i32> <on_false>, i32 <pivot>) declare <vscale x 4 x i64> @llvm.vp.merge.nxv4i64 (<vscale x 4 x i1> <condition>, <vscale x 4 x i64> <on_true>, <vscale x 4 x i64> <on_false>, i32 <pivot>)
Overview:¶
The
‘llvm.vp.merge
’ intrinsic is used to choose one value based on a condition vector and an index operand, without IR-level branching.
Arguments:¶
The first operand is a vector of i1
and indicates the condition. The second operand is the value that is merged where the condition vector is true. The third operand is the value
that is selected where the condition vector is false or the lane position is greater equal than the pivot. The fourth operand is the pivot.
- The optional
fast-math flags
marker indicates that the merge has one or more fast-math flags. These are optimization hints to enable otherwise unsafe floating-point optimizations. Fast-math flags are only valid for merges that return a floating-point scalar or vector type, or an array (nested to any depth) of floating-point scalar or vector types.
Semantics:¶
The intrinsic selects lanes from the second and third operand depending on a condition vector and pivot value.
For all lanes where the condition vector is true and the lane position is less than %pivot
the lane is taken from the second operand.
Otherwise, the lane is taken from the third operand.
Example:¶
%r = call <4 x i32> @llvm.vp.merge.v4i32(<4 x i1> %cond, <4 x i32> %on_true, <4 x i32> %on_false, i32 %pivot) ;;; Expansion. ;; Lanes at and above %pivot are taken from %on_false %atfirst = insertelement <4 x i32> undef, i32 %pivot, i32 0 %splat = shufflevector <4 x i32> %atfirst, <4 x i32> poison, <4 x i32> zeroinitializer %pivotmask = icmp ult <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> %splat %mergemask = and <4 x i1> %cond, <4 x i1> %pivotmask %also.r = select <4 x i1> %mergemask, <4 x i32> %on_true, <4 x i32> %on_false
‘llvm.vp.add.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.add.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.add.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.add.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer addition of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.add
’ intrinsic performs integer addition (add) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.add.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = add <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.sub.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.sub.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.sub.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.sub.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer subtraction of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.sub
’ intrinsic performs integer subtraction (sub) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.sub.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = sub <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.mul.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.mul.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.mul.nxv46i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.mul.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer multiplication of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.mul
’ intrinsic performs integer multiplication (mul) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.mul.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = mul <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.sdiv.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.sdiv.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.sdiv.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.sdiv.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated, signed division of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.sdiv
’ intrinsic performs signed division (sdiv) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.sdiv.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = sdiv <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.udiv.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.udiv.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.udiv.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.udiv.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated, unsigned division of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.udiv
’ intrinsic performs unsigned division
(udiv) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.udiv.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = udiv <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.srem.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.srem.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.srem.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.srem.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated computations of the signed remainder of two integer vectors.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.srem
’ intrinsic computes the remainder of the signed division (srem) of the first and second vector operand on each enabled lane. The result on disabled lanes is a
poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.srem.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = srem <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.urem.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.urem.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.urem.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.urem.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated computation of the unsigned remainder of two integer vectors.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.urem
’ intrinsic computes the remainder of the unsigned division (urem) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.urem.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = urem <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.ashr.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.ashr.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.ashr.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.ashr.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated arithmetic right-shift.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.ashr
’ intrinsic computes the arithmetic right shift (ashr) of the first operand by the second operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.ashr.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = ashr <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.lshr.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.lshr.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.lshr.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.lshr.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated logical right-shift.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.lshr
’ intrinsic computes the logical right shift (lshr) of the first operand by the second operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.lshr.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = lshr <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.shl.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.shl.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.shl.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.shl.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated left shift.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.shl
’ intrinsic computes the left shift
(shl) of the first operand by the second operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.shl.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = shl <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.or.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.or.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.or.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.or.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated or.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.or
’ intrinsic performs a bitwise or (or) of the first two operands on each enabled lane. The result on disabled lanes is a poison
value.
Examples:¶
%r = call <4 x i32> @llvm.vp.or.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = or <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.and.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.and.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.and.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.and.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated and.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.and
’ intrinsic performs a bitwise and
(and) of the first two operands on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.and.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = and <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.xor.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.xor.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.xor.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.xor.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Vector-predicated, bitwise xor.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.xor
’ intrinsic performs a bitwise xor (xor) of the first two operands on each enabled lane. The result on disabled lanes is a
poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.xor.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = xor <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.smax.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.smax.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.smax.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.smax.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer signed maximum of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.smax
’ intrinsic performs integer signed maximum (smax) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.smax.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b) %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.smin.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.smin.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.smin.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.smin.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer signed minimum of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.smin
’ intrinsic performs integer signed minimum (smin) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.smin.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %a, <4 x i32> %b) %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.umax.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.umax.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.umax.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.umax.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer unsigned maximum of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.umax
’ intrinsic performs integer unsigned maximum (umax) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.umax.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x i32> @llvm.umax.v4i32(<4 x i32> %a, <4 x i32> %b) %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.umin.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.umin.v16i32 (<16 x i32> <left_op>, <16 x i32> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.umin.nxv4i32 (<vscale x 4 x i32> <left_op>, <vscale x 4 x i32> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.umin.v256i64 (<256 x i64> <left_op>, <256 x i64> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer unsigned minimum of two vectors of integers.
Arguments:¶
The first two operands and the result have the same vector of integer type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.umin
’ intrinsic performs integer unsigned minimum (umin) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.umin.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x i32> @llvm.umin.v4i32(<4 x i32> %a, <4 x i32> %b) %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.copysign.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.copysign.v16f32 (<16 x float> <mag_op>, <16 x float> <sign_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.copysign.nxv4f32 (<vscale x 4 x float> <mag_op>, <vscale x 4 x float> <sign_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.copysign.v256f64 (<256 x double> <mag_op>, <256 x double> <sign_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point copysign of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.copysign
’ intrinsic performs floating-point copysign (copysign) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed
in the default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.copysign.v4f32(<4 x float> %mag, <4 x float> %sign, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.copysign.v4f32(<4 x float> %mag, <4 x float> %sign) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.minnum.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.minnum.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.minnum.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.minnum.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point IEEE-754 minNum of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.minnum
’ intrinsic performs floating-point minimum (minnum) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.minnum.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.minnum.v4f32(<4 x float> %a, <4 x float> %b) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.maxnum.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.maxnum.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.maxnum.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.maxnum.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point IEEE-754 maxNum of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.maxnum
’ intrinsic performs floating-point maximum (maxnum) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.maxnum.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.maxnum.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fadd.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fadd.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fadd.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fadd.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point addition of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fadd
’ intrinsic performs floating-point addition (fadd) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fadd.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fadd <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fsub.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fsub.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fsub.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fsub.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point subtraction of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fsub
’ intrinsic performs floating-point subtraction (fsub) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fsub.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fsub <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fmul.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fmul.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fmul.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fmul.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point multiplication of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fmul
’ intrinsic performs floating-point multiplication (fmul) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in
the default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fmul.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fmul <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fdiv.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fdiv.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fdiv.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fdiv.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point division of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fdiv
’ intrinsic performs floating-point division (fdiv) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fdiv.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fdiv <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.frem.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.frem.v16f32 (<16 x float> <left_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.frem.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.frem.v256f64 (<256 x double> <left_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point remainder of two vectors of floating-point values.
Arguments:¶
The first two operands and the result have the same vector of floating-point type. The third operand is the vector mask and has the same number of elements as the result vector type. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.frem
’ intrinsic performs floating-point remainder (frem) of the first and second vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the
default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.frem.v4f32(<4 x float> %a, <4 x float> %b, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = frem <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fneg.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fneg.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fneg.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fneg.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point negation of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fneg
’ intrinsic performs floating-point
negation (fneg) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.fneg.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fneg <4 x float> %a %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fabs.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fabs.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fabs.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fabs.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point absolute value of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fabs
’ intrinsic performs floating-point absolute value (fabs) of the first vector operand on each enabled lane. The result on disabled lanes is a
poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.fabs.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.fabs.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.sqrt.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.sqrt.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.sqrt.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.sqrt.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point square root of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.sqrt
’ intrinsic performs floating-point square root (sqrt) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation is performed in the default
floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.sqrt.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fma.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fma.v16f32 (<16 x float> <left_op>, <16 x float> <middle_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fma.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <middle_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fma.v256f64 (<256 x double> <left_op>, <256 x double> <middle_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point fused multiply-add of two vectors of floating-point values.
Arguments:¶
The first three operands and the result have the same vector of floating-point type. The fourth operand is the vector mask and has the same number of elements as the result vector type. The fifth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fma
’ intrinsic performs floating-point fused multiply-add (llvm.fma) of the first, second, and third vector operand on each enabled lane. The result on disabled lanes is a poison value. The operation
is performed in the default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fma.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.fma(<4 x float> %a, <4 x float> %b, <4 x float> %c) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fmuladd.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fmuladd.v16f32 (<16 x float> <left_op>, <16 x float> <middle_op>, <16 x float> <right_op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.fmuladd.nxv4f32 (<vscale x 4 x float> <left_op>, <vscale x 4 x float> <middle_op>, <vscale x 4 x float> <right_op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.fmuladd.v256f64 (<256 x double> <left_op>, <256 x double> <middle_op>, <256 x double> <right_op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point multiply-add of two vectors of floating-point values that can be fused if code generator determines that (a) the target instruction set has support for a fused operation, and (b) that the fused operation is more efficient than the equivalent, separate pair of mul and add instructions.
Arguments:¶
The first three operands and the result have the same vector of floating-point type. The fourth operand is the vector mask and has the same number of elements as the result vector type. The fifth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fmuladd
’ intrinsic performs floating-point multiply-add (llvm.fuladd) of the first, second, and third vector operand on each enabled lane. The result on disabled lanes
is a poison value. The operation is performed in the default floating-point environment.
Examples:¶
%r = call <4 x float> @llvm.vp.fmuladd.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.fmuladd(<4 x float> %a, <4 x float> %b, <4 x float> %c) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.reduce.add.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.add.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.add.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated
integer ADD
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.add
’ intrinsic performs the integer ADD
reduction
(llvm.vector.reduce.add) of the vector operand val
on each enabled lane, adding it to the scalar start_value
. Disabled lanes are treated as containing the neutral value 0
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is equal to start_value
.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.add.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> zeroinitializer %reduction = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %masked.a) %also.r = add i32 %reduction, %start
‘llvm.vp.reduce.fadd.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare float @llvm.vp.reduce.fadd.v4f32(float <start_value>, <4 x float> <val>, <4 x i1> <mask>, i32 <vector_length>) declare double @llvm.vp.reduce.fadd.nxv8f64(double <start_value>, <vscale x 8 x double> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point ADD
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar floating-point type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of floating-point values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.fadd
’ intrinsic performs the floating-point ADD
reduction (llvm.vector.reduce.fadd) of the vector operand val
on each enabled lane,
adding it to the scalar start_value
. Disabled lanes are treated as containing the neutral value -0.0
(i.e. having no effect on the reduction operation). If no lanes are enabled, the resulting value will be equal to start_value
.
To ignore the start value, the neutral value can be used.
See the unpredicated version (llvm.vector.reduce.fadd) for more detail on the semantics of the reduction.
Examples:¶
%r = call float @llvm.vp.reduce.fadd.v4f32(float %start, <4 x float> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x float> %a, <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0> %also.r = call float @llvm.vector.reduce.fadd.v4f32(float %start, <4 x float> %masked.a)
‘llvm.vp.reduce.mul.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.mul.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.mul.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer MUL
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.mul
’ intrinsic performs the integer MUL
reduction (llvm.vector.reduce.mul) of the vector operand val
on each enabled lane, multiplying it by the
scalar start_value
. Disabled lanes are treated as containing the neutral value 1
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.mul.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 1, i32 1, i32 1, i32 1> %reduction = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %masked.a) %also.r = mul i32 %reduction, %start
‘llvm.vp.reduce.fmul.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare float @llvm.vp.reduce.fmul.v4f32(float <start_value>, <4 x float> <val>, <4 x i1> <mask>, i32 <vector_length>) declare double @llvm.vp.reduce.fmul.nxv8f64(double <start_value>, <vscale x 8 x double> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point MUL
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar floating-point type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of floating-point values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.fmul
’ intrinsic performs the floating-point MUL
reduction (llvm.vector.reduce.fmul) of the vector operand val
on each enabled lane, multiplying it by the scalar start_value`. Disabled lanes are treated as containing the neutral value 1.0
(i.e. having no effect on the reduction operation). If no lanes are enabled, the resulting value will
be equal to the starting value.
To ignore the start value, the neutral value can be used.
See the unpredicated version (llvm.vector.reduce.fmul) for more detail on the semantics.
Examples:¶
%r = call float @llvm.vp.reduce.fmul.v4f32(float %start, <4 x float> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x float> %a, <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0> %also.r = call float @llvm.vector.reduce.fmul.v4f32(float %start, <4 x float> %masked.a)
‘llvm.vp.reduce.and.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.and.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.and.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer AND
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.and
’ intrinsic performs the integer AND
reduction (llvm.vector.reduce.and) of the vector operand val
on each enabled lane, performing an ‘and
’ of that with with the scalar start_value
. Disabled lanes are treated as containing the neutral value UINT_MAX
, or -1
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start
value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.and.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1> %reduction = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %masked.a) %also.r = and i32 %reduction, %start
‘llvm.vp.reduce.or.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.or.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.or.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer OR
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.or
’ intrinsic performs the integer OR
reduction (llvm.vector.reduce.or) of the vector operand val
on each
enabled lane, performing an ‘or
’ of that with the scalar start_value
. Disabled lanes are treated as containing the neutral value 0
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.or.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 0, i32 0, i32 0, i32 0> %reduction = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %masked.a) %also.r = or i32 %reduction, %start
‘llvm.vp.reduce.xor.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.xor.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.xor.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated integer XOR
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.xor
’ intrinsic performs the integer XOR
reduction (llvm.vector.reduce.xor) of the vector operand val
on each enabled lane, performing an ‘xor
’ of that with the scalar start_value
. Disabled lanes are treated as containing the neutral value 0
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.xor.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 0, i32 0, i32 0, i32 0> %reduction = call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %masked.a) %also.r = xor i32 %reduction, %start
‘llvm.vp.reduce.smax.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.smax.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.smax.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated signed-integer MAX
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.smax
’ intrinsic performs the signed-integer MAX
reduction
(llvm.vector.reduce.smax) of the vector operand val
on each enabled lane, and taking the maximum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value INT_MIN
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i8 @llvm.vp.reduce.smax.v4i8(i8 %start, <4 x i8> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i8> %a, <4 x i8> <i8 -128, i8 -128, i8 -128, i8 -128> %reduction = call i8 @llvm.vector.reduce.smax.v4i8(<4 x i8> %masked.a) %also.r = call i8 @llvm.smax.i8(i8 %reduction, i8 %start)
‘llvm.vp.reduce.smin.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.smin.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.smin.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated signed-integer MIN
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.smin
’ intrinsic performs the signed-integer MIN
reduction (llvm.vector.reduce.smin) of the vector operand val
on each enabled lane, and taking the
minimum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value INT_MAX
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i8 @llvm.vp.reduce.smin.v4i8(i8 %start, <4 x i8> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i8> %a, <4 x i8> <i8 127, i8 127, i8 127, i8 127> %reduction = call i8 @llvm.vector.reduce.smin.v4i8(<4 x i8> %masked.a) %also.r = call i8 @llvm.smin.i8(i8 %reduction, i8 %start)
‘llvm.vp.reduce.umax.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.umax.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.umax.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated unsigned-integer MAX
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.umax
’ intrinsic performs the unsigned-integer MAX
reduction (llvm.vector.reduce.umax) of the vector operand val
on each enabled lane, and taking the maximum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value 0
(i.e.
having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.umax.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 0, i32 0, i32 0, i32 0> %reduction = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %masked.a) %also.r = call i32 @llvm.umax.i32(i32 %reduction, i32 %start)
‘llvm.vp.reduce.umin.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare i32 @llvm.vp.reduce.umin.v4i32(i32 <start_value>, <4 x i32> <val>, <4 x i1> <mask>, i32 <vector_length>) declare i16 @llvm.vp.reduce.umin.nxv8i16(i16 <start_value>, <vscale x 8 x i16> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated unsigned-integer MIN
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar integer type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of integer values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.umin
’ intrinsic performs the unsigned-integer MIN
reduction
(llvm.vector.reduce.umin) of the vector operand val
on each enabled lane, taking the minimum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value UINT_MAX
, or -1
(i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call i32 @llvm.vp.reduce.umin.v4i32(i32 %start, <4 x i32> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x i32> %a, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1> %reduction = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %masked.a) %also.r = call i32 @llvm.umin.i32(i32 %reduction, i32 %start)
‘llvm.vp.reduce.fmax.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare float @llvm.vp.reduce.fmax.v4f32(float <start_value>, <4 x float> <val>, <4 x i1> <mask>, float <vector_length>) declare double @llvm.vp.reduce.fmax.nxv8f64(double <start_value>, <vscale x 8 x double> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point MAX
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar floating-point type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of floating-point values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.fmax
’ intrinsic performs the floating-point MAX
reduction (llvm.vector.reduce.fmax) of the vector operand val
on each enabled lane,
taking the maximum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value (i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
The neutral value is dependent on the fast-math flags. If no flags are set, the neutral value is -QNAN
. If nnan
and ninf
are both set, then the neutral value is the
smallest floating-point value for the result type. If only nnan
is set then the neutral value is -Infinity
.
This instruction has the same comparison semantics as the llvm.vector.reduce.fmax intrinsic (and thus the ‘llvm.maxnum.*
’ intrinsic). That is, the result will always be a number unless all elements of the vector and the starting value are NaN
. For a vector with maximum element
magnitude 0.0
and containing both +0.0
and -0.0
elements, the sign of the result is unspecified.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call float @llvm.vp.reduce.fmax.v4f32(float %float, <4 x float> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x float> %a, <4 x float> <float QNAN, float QNAN, float QNAN, float QNAN> %reduction = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %masked.a) %also.r = call float @llvm.maxnum.f32(float %reduction, float %start)
‘llvm.vp.reduce.fmin.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare float @llvm.vp.reduce.fmin.v4f32(float <start_value>, <4 x float> <val>, <4 x i1> <mask>, float <vector_length>) declare double @llvm.vp.reduce.fmin.nxv8f64(double <start_value>, <vscale x 8 x double> <val>, <vscale x 8 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point MIN
reduction of a vector and a scalar starting value, returning the result as a scalar.
Arguments:¶
The first operand is the start value of the reduction, which must be a scalar floating-point type equal to the result type. The second operand is the vector on which the reduction is performed and must be a vector of floating-point values whose element type is the result/start type. The third operand is the vector mask and is a vector of boolean values with the same number of elements as the vector operand. The fourth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.reduce.fmin
’ intrinsic performs the floating-point MIN
reduction
(llvm.vector.reduce.fmin) of the vector operand val
on each enabled lane, taking the minimum of that and the scalar start_value
. Disabled lanes are treated as containing the neutral value (i.e. having no effect on the reduction operation). If the vector length is zero, the result is the start value.
The neutral value is dependent on the
fast-math flags. If no flags are set, the neutral value is +QNAN
. If nnan
and ninf
are both set, then the neutral value is the largest floating-point value for the result type. If only nnan
is set then the neutral value is +Infinity
.
This instruction has the same comparison semantics as the
llvm.vector.reduce.fmin intrinsic (and thus the ‘llvm.minnum.*
’ intrinsic). That is, the result will always be a number unless all elements of the vector and the starting value are NaN
. For a vector with maximum element magnitude 0.0
and containing both +0.0
and -0.0
elements, the sign of the result is unspecified.
To ignore the start value, the neutral value can be used.
Examples:¶
%r = call float @llvm.vp.reduce.fmin.v4f32(float %start, <4 x float> %a, <4 x i1> %mask, i32 %evl) ; %r is equivalent to %also.r, where lanes greater than or equal to %evl ; are treated as though %mask were false for those lanes. %masked.a = select <4 x i1> %mask, <4 x float> %a, <4 x float> <float QNAN, float QNAN, float QNAN, float QNAN> %reduction = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %masked.a) %also.r = call float @llvm.minnum.f32(float %reduction, float %start)
‘llvm.get.active.lane.mask.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <4 x i1> @llvm.get.active.lane.mask.v4i1.i32(i32 %base, i32 %n) declare <8 x i1> @llvm.get.active.lane.mask.v8i1.i64(i64 %base, i64 %n) declare <16 x i1> @llvm.get.active.lane.mask.v16i1.i64(i64 %base, i64 %n) declare <vscale x 16 x i1> @llvm.get.active.lane.mask.nxv16i1.i64(i64 %base, i64 %n)
Overview:¶
Create a mask representing active and inactive vector lanes.
Arguments:¶
Both operands have the same scalar integer type. The result is a vector with the i1 element type.
Semantics:¶
The ‘llvm.get.active.lane.mask.*
’ intrinsics are semantically equivalent to:
%m[i] = icmp ult (%base + i), %n
where %m
is a vector (mask) of
active/inactive lanes with its elements indexed by i
, and %base
, %n
are the two arguments to llvm.get.active.lane.mask.*
, %icmp
is an integer compare and ult
the unsigned less-than comparison operator. Overflow cannot occur in (%base + i)
and its comparison against %n
as it is performed in integer numbers and not in machine numbers. If %n
is 0
, then the result is a poison value. The above is equivalent to:
%m = @llvm.get.active.lane.mask(%base, %n)
This can, for example, be emitted by the loop
vectorizer in which case %base
is the first element of the vector induction variable (VIV) and %n
is the loop tripcount. Thus, these intrinsics perform an element-wise less than comparison of VIV with the loop tripcount, producing a mask of true/false values representing active/inactive vector lanes, except if the VIV overflows in which case they return false in the lanes where the VIV overflows. The arguments are scalar types to accommodate scalable vector types, for which it is
unknown what the type of the step vector needs to be that enumerate its lanes without overflow.
This mask %m
can e.g. be used in masked load/store instructions. These intrinsics provide a hint to the backend. I.e., for a vector loop, the back-edge taken count of the original scalar loop is explicit as the second argument.
Examples:¶
%active.lane.mask = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i64(i64 %elem0, i64 429) %wide.masked.load = call <4 x i32> @llvm.masked.load.v4i32.p0v4i32(<4 x i32>* %3, i32 4, <4 x i1> %active.lane.mask, <4 x i32> poison)
‘llvm.experimental.vp.splice
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <2 x double> @llvm.experimental.vp.splice.v2f64(<2 x double> %vec1, <2 x double> %vec2, i32 %imm, <2 x i1> %mask, i32 %evl1, i32 %evl2) declare <vscale x 4 x i32> @llvm.experimental.vp.splice.nxv4i32(<vscale x 4 x i32> %vec1, <vscale x 4 x i32> %vec2, i32 %imm, <vscale x 4 x i1> %mask, i32 %evl1, i32 %evl2)
Overview:¶
The ‘llvm.experimental.vp.splice.*
’ intrinsic is the vector length predicated version of the ‘llvm.experimental.vector.splice.*
’ intrinsic.
Arguments:¶
The result and the first two arguments vec1
and vec2
are vectors with the same type.
The third argument imm
is an immediate signed integer that indicates the offset index. The fourth argument mask
is a vector mask and has the same number of elements as the result. The last two arguments evl1
and evl2
are unsigned integers indicating the explicit vector lengths of vec1
and vec2
respectively. imm
, evl1
and evl2
should respect the following constraints: -evl1 <= imm < evl1
, 0 <= evl1 <= VL
and 0 <= evl2 <= VL
, where VL
is the runtime vector factor. If these
constraints are not satisfied the intrinsic has undefined behaviour.
Semantics:¶
Effectively, this intrinsic concatenates vec1[0..evl1-1]
and vec2[0..evl2-1]
and creates the result vector by selecting the elements in a window of size evl2
, starting at index imm
(for a positive immediate) of the concatenated vector. Elements in the result vector beyond
evl2
are undef
. If imm
is negative the starting index is evl1 + imm
. The result vector of active vector length evl2
contains evl1 - imm
(-imm
for negative imm
) elements from indices [imm..evl1 - 1]
([evl1 + imm..evl1 -1]
for negative imm
) of vec1
followed by the first evl2 - (evl1 - imm)
(evl2 + imm
for negative imm
) elements of vec2
. If evl1 - imm
(-imm
) >= evl2
, only the first evl2
elements are considered and the remaining are undef
. The lanes in the
result vector disabled by mask
are poison
.
Examples:¶
llvm.experimental.vp.splice(<A,B,C,D>, <E,F,G,H>, 1, 2, 3) ==> <B, E, F, poison> ; index llvm.experimental.vp.splice(<A,B,C,D>, <E,F,G,H>, -2, 3, 2) ==> <B, C, poison, poison> ; trailing elements
‘llvm.vp.load
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <4 x float> @llvm.vp.load.v4f32.p0(ptr %ptr, <4 x i1> %mask, i32 %evl) declare <vscale x 2 x i16> @llvm.vp.load.nxv2i16.p0(ptr %ptr, <vscale x 2 x i1> %mask, i32 %evl) declare <8 x float> @llvm.vp.load.v8f32.p1(ptr addrspace(1) %ptr, <8 x i1> %mask, i32 %evl) declare <vscale x 1 x i64> @llvm.vp.load.nxv1i64.p6(ptr addrspace(6) %ptr, <vscale x 1 x i1> %mask, i32 %evl)
Overview:¶
The ‘llvm.vp.load.*
’ intrinsic is the vector length predicated version of the
llvm.masked.load intrinsic.
Arguments:¶
The first operand is the base pointer for the load. The second operand is a vector of boolean values with the same number of elements as the return type. The third is the explicit vector length of the operation. The return type and underlying type of the base pointer are the same vector types.
The align parameter attribute can be provided for the first operand.
Semantics:¶
The ‘llvm.vp.load
’ intrinsic reads a vector from memory in the same way as the ‘llvm.masked.load
’ intrinsic, where the mask
is taken from the combination of the ‘mask
’ and ‘evl
’ operands in the usual VP way. Certain ‘llvm.masked.load
’ operands do not have corresponding operands in ‘llvm.vp.load
’: the ‘passthru
’ operand is implicitly poison
; the ‘alignment
’ operand is taken as the align
parameter attribute, if provided. The default alignment is taken as the ABI alignment of the return type as specified by the datalayout
string.
Examples:¶
%r = call <8 x i8> @llvm.vp.load.v8i8.p0(ptr align 2 %ptr, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %also.r = call <8 x i8> @llvm.masked.load.v8i8.p0(ptr %ptr, i32 2, <8 x i1> %mask, <8 x i8> poison)
‘llvm.vp.store
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare void @llvm.vp.store.v4f32.p0(<4 x float> %val, ptr %ptr, <4 x i1> %mask, i32 %evl) declare void @llvm.vp.store.nxv2i16.p0(<vscale x 2 x i16> %val, ptr %ptr, <vscale x 2 x i1> %mask, i32 %evl) declare void @llvm.vp.store.v8f32.p1(<8 x float> %val, ptr addrspace(1) %ptr, <8 x i1> %mask, i32 %evl) declare void @llvm.vp.store.nxv1i64.p6(<vscale x 1 x i64> %val, ptr addrspace(6) %ptr, <vscale x 1 x i1> %mask, i32 %evl)
Overview:¶
The ‘llvm.vp.store.*
’ intrinsic is the vector length predicated version of the llvm.masked.store
intrinsic.
Arguments:¶
The first operand is the vector value to be written to memory. The second operand is the base pointer for the store. It has the same underlying type as the value operand. The third operand is a vector of boolean values with the same number of elements as the return type. The fourth is the explicit vector length of the operation.
The align parameter attribute can be provided for the second operand.
Semantics:¶
The ‘llvm.vp.store
’ intrinsic reads a vector from memory in the same way as the ‘llvm.masked.store
’ intrinsic, where the mask is taken from the combination of the ‘mask
’ and ‘evl
’
operands in the usual VP way. The alignment of the operation (corresponding to the ‘alignment
’ operand of ‘llvm.masked.store
’) is specified by the align
parameter attribute (see above). If it is not provided then the ABI alignment of the type of the ‘value
’ operand as specified by the datalayout string is used instead.
Examples:¶
call void @llvm.vp.store.v8i8.p0(<8 x i8> %val, ptr align 4 %ptr, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, the call above is lane-wise equivalent to the call below. call void @llvm.masked.store.v8i8.p0(<8 x i8> %val, ptr %ptr, i32 4, <8 x i1> %mask)
‘llvm.experimental.vp.strided.load
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <4 x float> @llvm.experimental.vp.strided.load.v4f32.i64(ptr %ptr, i64 %stride, <4 x i1> %mask, i32 %evl) declare <vscale x 2 x i16> @llvm.experimental.vp.strided.load.nxv2i16.i64(ptr %ptr, i64 %stride, <vscale x 2 x i1> %mask, i32 %evl)
Overview:¶
The ‘llvm.experimental.vp.strided.load
’ intrinsic loads, into a vector, scalar values from memory locations evenly spaced apart by ‘stride
’ number of bytes, starting from ‘ptr
’.
Arguments:¶
The first operand is the base pointer for the load. The second operand is the stride value expressed in bytes. The third operand is a vector of boolean values with the same number of elements as the return type. The fourth is the explicit vector length of the operation. The base pointer underlying type matches the type of the scalar elements of the return operand.
The align parameter attribute can be provided for the first operand.
Semantics:¶
The ‘llvm.experimental.vp.strided.load
’ intrinsic loads, into a vector, multiple scalar values from memory in the same way as the
llvm.vp.gather intrinsic, where the vector of pointers is in the form:
%ptrs = <%ptr, %ptr + %stride, %ptr + 2 * %stride, ... >
,
with ‘ptr
’ previously casted to a pointer ‘i8
’, ‘stride
’ always interpreted as a signed integer and all arithmetic occurring in the pointer type.
Examples:¶
%r = call <8 x i64> @llvm.experimental.vp.strided.load.v8i64.i64(i64* %ptr, i64 %stride, <8 x i64> %mask, i32 %evl) ;; The operation can also be expressed like this: %addr = bitcast i64* %ptr to i8* ;; Create a vector of pointers %addrs in the form: ;; %addrs = <%addr, %addr + %stride, %addr + 2 * %stride, ...> %ptrs = bitcast <8 x i8* > %addrs to <8 x i64* > %also.r = call <8 x i64> @llvm.vp.gather.v8i64.v8p0i64(<8 x i64* > %ptrs, <8 x i64> %mask, i32 %evl)
‘llvm.experimental.vp.strided.store
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare void @llvm.experimental.vp.strided.store.v4f32.i64(<4 x float> %val, ptr %ptr, i64 %stride, <4 x i1> %mask, i32 %evl) declare void @llvm.experimental.vp.strided.store.nxv2i16.i64(<vscale x 2 x i16> %val, ptr %ptr, i64 %stride, <vscale x 2 x i1> %mask, i32 %evl)
Overview:¶
The ‘@llvm.experimental.vp.strided.store
’ intrinsic stores the elements of ‘val
’ into memory locations evenly spaced apart by ‘stride
’ number of bytes, starting from ‘ptr
’.
Arguments:¶
The first operand is the vector value to be written to memory. The second operand is the base pointer for the store. Its underlying type matches the scalar element type of the value operand. The third operand is the stride value expressed in bytes. The fourth operand is a vector of boolean values with the same number of elements as the return type. The fifth is the explicit vector length of the operation.
The align parameter attribute can be provided for the second operand.
Semantics:¶
The ‘llvm.experimental.vp.strided.store
’ intrinsic stores the elements of ‘val
’ in the same way as the
llvm.vp.scatter intrinsic, where the vector of pointers is in the form:
%ptrs = <%ptr, %ptr + %stride, %ptr + 2 * %stride, ... >
,
with ‘ptr
’ previously casted to a pointer ‘i8
’, ‘stride
’ always interpreted as a signed integer and all arithmetic occurring in the pointer type.
Examples:¶
call void @llvm.experimental.vp.strided.store.v8i64.i64(<8 x i64> %val, i64* %ptr, i64 %stride, <8 x i1> %mask, i32 %evl) ;; The operation can also be expressed like this: %addr = bitcast i64* %ptr to i8* ;; Create a vector of pointers %addrs in the form: ;; %addrs = <%addr, %addr + %stride, %addr + 2 * %stride, ...> %ptrs = bitcast <8 x i8* > %addrs to <8 x i64* > call void @llvm.vp.scatter.v8i64.v8p0i64(<8 x i64> %val, <8 x i64*> %ptrs, <8 x i1> %mask, i32 %evl)
‘llvm.vp.gather
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare <4 x double> @llvm.vp.gather.v4f64.v4p0(<4 x ptr> %ptrs, <4 x i1> %mask, i32 %evl) declare <vscale x 2 x i8> @llvm.vp.gather.nxv2i8.nxv2p0(<vscale x 2 x ptr> %ptrs, <vscale x 2 x i1> %mask, i32 %evl) declare <2 x float> @llvm.vp.gather.v2f32.v2p2(<2 x ptr addrspace(2)> %ptrs, <2 x i1> %mask, i32 %evl) declare <vscale x 4 x i32> @llvm.vp.gather.nxv4i32.nxv4p4(<vscale x 4 x ptr addrspace(4)> %ptrs, <vscale x 4 x i1> %mask, i32 %evl)
Overview:¶
The ‘llvm.vp.gather.*
’ intrinsic is the vector length predicated version of the llvm.masked.gather
intrinsic.
Arguments:¶
The first operand is a vector of pointers which holds all memory addresses to read. The second operand is a vector of boolean values with the same number of elements as the return type. The third is the explicit vector length of the operation. The return type and underlying type of the vector of pointers are the same vector types.
The align parameter attribute can be provided for the first operand.
Semantics:¶
The ‘llvm.vp.gather
’ intrinsic reads multiple scalar values from memory in the same way as the ‘llvm.masked.gather
’ intrinsic, where the mask is taken from the combination of the ‘mask
’ and
‘evl
’ operands in the usual VP way. Certain ‘llvm.masked.gather
’ operands do not have corresponding operands in ‘llvm.vp.gather
’: the ‘passthru
’ operand is implicitly poison
; the ‘alignment
’ operand is taken as the align
parameter, if provided. The default alignment is taken as the ABI alignment of the source addresses as specified by the datalayout string.
Examples:¶
%r = call <8 x i8> @llvm.vp.gather.v8i8.v8p0(<8 x ptr> align 8 %ptrs, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %also.r = call <8 x i8> @llvm.masked.gather.v8i8.v8p0(<8 x ptr> %ptrs, i32 8, <8 x i1> %mask, <8 x i8> poison)
‘llvm.vp.scatter
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic.
declare void @llvm.vp.scatter.v4f64.v4p0(<4 x double> %val, <4 x ptr> %ptrs, <4 x i1> %mask, i32 %evl) declare void @llvm.vp.scatter.nxv2i8.nxv2p0(<vscale x 2 x i8> %val, <vscale x 2 x ptr> %ptrs, <vscale x 2 x i1> %mask, i32 %evl) declare void @llvm.vp.scatter.v2f32.v2p2(<2 x float> %val, <2 x ptr addrspace(2)> %ptrs, <2 x i1> %mask, i32 %evl) declare void @llvm.vp.scatter.nxv4i32.nxv4p4(<vscale x 4 x i32> %val, <vscale x 4 x ptr addrspace(4)> %ptrs, <vscale x 4 x i1> %mask, i32 %evl)
Overview:¶
The ‘llvm.vp.scatter.*
’ intrinsic is the vector length predicated version of the
llvm.masked.scatter intrinsic.
Arguments:¶
The first operand is a vector value to be written to memory. The second operand is a vector of pointers, pointing to where the value elements should be stored. The third operand is a vector of boolean values with the same number of elements as the return type. The fourth is the explicit vector length of the operation.
The align parameter attribute can be provided for the second operand.
Semantics:¶
The ‘llvm.vp.scatter
’ intrinsic writes multiple scalar values to memory in the same way
as the ‘llvm.masked.scatter
’ intrinsic, where the mask is taken from the combination of the ‘mask
’ and ‘evl
’ operands in the usual VP way. The ‘alignment
’ operand of the ‘llvm.masked.scatter
’ does not have a corresponding operand in ‘llvm.vp.scatter
’: it is instead provided via the optional align
parameter attribute on the vector-of-pointers operand. Otherwise it is taken as the ABI alignment of the destination addresses as specified by the
datalayout string.
Examples:¶
call void @llvm.vp.scatter.v8i8.v8p0(<8 x i8> %val, <8 x ptr> align 1 %ptrs, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, the call above is lane-wise equivalent to the call below. call void @llvm.masked.scatter.v8i8.v8p0(<8 x i8> %val, <8 x ptr> %ptrs, i32 1, <8 x i1> %mask)
‘llvm.vp.trunc.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i16> @llvm.vp.trunc.v16i16.v16i32 (<16 x i32> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i16> @llvm.vp.trunc.nxv4i16.nxv4i32 (<vscale x 4 x i32> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.trunc
’
intrinsic truncates its first operand to the return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.trunc
’ intrinsic takes a value to cast as its first operand. The return type is the type to cast the value to. Both types must be vector of
integer type. The bit size of the value must be larger than the bit size of the return type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.trunc
’ intrinsic truncates the high order bits in value and converts the remaining bits to return type. Since the source size must be larger than the destination size, ‘llvm.vp.trunc
’ cannot be a no-op cast. It will always truncate bits. The conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are
poison
.
Examples:¶
%r = call <4 x i16> @llvm.vp.trunc.v4i16.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = trunc <4 x i32> %a to <4 x i16> %also.r = select <4 x i1> %mask, <4 x i16> %t, <4 x i16> poison
‘llvm.vp.zext.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.zext.v16i32.v16i16 (<16 x i16> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.zext.nxv4i32.nxv4i16 (<vscale x 4 x i16> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.zext
’ intrinsic zero extends its first operand to the return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.zext
’ intrinsic takes a value to cast as its first operand. The return type is the type to cast the value to. Both types must be vectors of integer type. The bit size of the value must be smaller than the bit size of the return type. The second operand is the vector mask. The return type,
the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.zext
’ intrinsic fill the high order bits of the value with zero bits until it reaches the size of the return type. When zero extending from i1, the result will always be either 0 or 1. The
conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x i32> @llvm.vp.zext.v4i32.v4i16(<4 x i16> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = zext <4 x i16> %a to <4 x i32> %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.sext.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.sext.v16i32.v16i16 (<16 x i16> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.sext.nxv4i32.nxv4i16 (<vscale x 4 x i16> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
Overview:¶
The
‘llvm.vp.sext
’ intrinsic sign extends its first operand to the return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.sext
’ intrinsic takes a value to cast as its first operand. The return type is the type to cast the value to. Both types must be vectors of
integer type. The bit size of the value must be smaller than the bit size of the return type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.sext
’ intrinsic performs a sign extension by copying the sign bit (highest order bit) of the value until it reaches the size of the return type. When sign extending from i1, the result will always be either -1 or 0. The conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x i32> @llvm.vp.sext.v4i32.v4i16(<4 x i16> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = sext <4 x i16> %a to <4 x i32> %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.fptrunc.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.fptrunc.v16f32.v16f64 (<16 x double> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.trunc.nxv4f32.nxv4f64 (<vscale x 4 x double> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.fptrunc
’ intrinsic truncates its first operand to the return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.fptrunc
’ intrinsic takes a value to cast as its first operand. The return type is the type to cast the value to. Both types must be vector of floating-point type. The bit size of the value must be larger than the bit size of the return type. This implies that ‘llvm.vp.fptrunc
’ cannot be used to
make a no-op cast. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fptrunc
’ intrinsic casts a value
from a larger
floating-point type to a smaller floating-point type. This instruction is assumed to execute in the default floating-point environment. The conversion is performed on lane positions below the explicit vector length and where the vector
mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x float> @llvm.vp.fptrunc.v4f32.v4f64(<4 x double> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fptrunc <4 x double> %a to <4 x float> %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.fpext.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x double> @llvm.vp.fpext.v16f64.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x double> @llvm.vp.fpext.nxv4f64.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.fpext
’ intrinsic extends its first operand to the return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.fpext
’ intrinsic takes a value to cast as its first operand. The return type is the type to cast the value to. Both types must be vector of floating-point type. The bit size of the value must be smaller than the bit size of the return type. This implies that
‘llvm.vp.fpext
’ cannot be used to make a no-op cast. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fpext
’ intrinsic extends the value
from a smaller
floating-point type to a larger floating-point type. The ‘llvm.vp.fpext
’ cannot be used to make a no-op cast because it always changes bits. Use bitcast
to make a no-op cast for a floating-point cast. The conversion is performed on lane positions below the explicit vector length and where the vector mask is
true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x double> @llvm.vp.fpext.v4f64.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fpext <4 x float> %a to <4 x double> %also.r = select <4 x i1> %mask, <4 x double> %t, <4 x double> poison
‘llvm.vp.fptoui.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.fptoui.v16i32.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.fptoui.nxv4i32.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.fptoui.v256i64.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.fptoui
’ intrinsic converts the floating-point operand to
the unsigned integer return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.fptoui
’ intrinsic takes a value to cast as its first operand. The value to cast must be a vector of floating-point type. The return type is the type
to cast the value to. The return type must be vector of integer type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fptoui
’ intrinsic converts its floating-point operand into the nearest (rounding towards zero) unsigned integer value where the lane position is below the explicit vector length and the vector mask is true. Masked-off lanes are poison
. On enabled lanes where conversion takes place and the
value cannot fit in the return type, the result on that lane is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.fptoui.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fptoui <4 x float> %a to <4 x i32> %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.fptosi.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.fptosi.v16i32.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.fptosi.nxv4i32.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.fptosi.v256i64.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The
‘llvm.vp.fptosi
’ intrinsic converts the floating-point operand to the signed integer return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.fptosi
’ intrinsic takes a value to cast as its first operand. The value to cast must be a
vector of floating-point type. The return type is the type to cast the value to. The return type must be vector of integer type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the
operation.
Semantics:¶
The ‘llvm.vp.fptosi
’ intrinsic converts its floating-point operand into the nearest (rounding towards zero) signed integer value where the lane position is below the explicit vector length and the vector mask is true. Masked-off lanes are poison
.
On enabled lanes where conversion takes place and the value cannot fit in the return type, the result on that lane is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.fptosi.v4i32.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fptosi <4 x float> %a to <4 x i32> %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
‘llvm.vp.uitofp.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.uitofp.v16f32.v16i32 (<16 x i32> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.uitofp.nxv4f32.nxv4i32 (<vscale x 4 x i32> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.uitofp.v256f64.v256i64 (<256 x i64> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.uitofp
’ intrinsic converts its unsigned integer operand to the floating-point return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.uitofp
’ intrinsic takes a value to cast as its first operand. The value to cast must be vector of integer type. The return type is the type to cast the value to. The return type must be a vector of floating-point type. The second operand is the vector mask. The return type, the value to cast,
and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.uitofp
’ intrinsic interprets its first operand as an unsigned integer quantity and converts it to the corresponding floating-point value. If the value cannot be exactly represented, it is rounded using the default
rounding mode. The conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x float> @llvm.vp.uitofp.v4f32.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = uitofp <4 x i32> %a to <4 x float> %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.sitofp.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.sitofp.v16f32.v16i32 (<16 x i32> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.sitofp.nxv4f32.nxv4i32 (<vscale x 4 x i32> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.sitofp.v256f64.v256i64 (<256 x i64> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The
‘llvm.vp.sitofp
’ intrinsic converts its signed integer operand to the floating-point return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.sitofp
’ intrinsic takes a value to cast as its first operand. The value to cast must be
vector of integer type. The return type is the type to cast the value to. The return type must be a vector of floating-point type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the
operation.
Semantics:¶
The ‘llvm.vp.sitofp
’ intrinsic interprets its first operand as a signed integer quantity and converts it to the corresponding floating-point value. If the value cannot be exactly represented, it is rounded using the default rounding mode. The conversion is performed on lane positions below the explicit vector length and where the vector
mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x float> @llvm.vp.sitofp.v4f32.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = sitofp <4 x i32> %a to <4 x float> %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.ptrtoint.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i8> @llvm.vp.ptrtoint.v16i8.v16p0(<16 x ptr> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i8> @llvm.vp.ptrtoint.nxv4i8.nxv4p0(<vscale x 4 x ptr> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.ptrtoint.v16i64.v16p0(<256 x ptr> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.ptrtoint
’ intrinsic converts its pointer to the integer return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.ptrtoint
’ intrinsic takes a value to cast as its first operand , which must be a vector of pointers, and a type to cast it to return type, which must be a vector of integer type. The second operand is the vector mask. The return type, the value to cast, and the
vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.ptrtoint
’ intrinsic converts value to return type by interpreting the pointer value as an integer and either truncating or zero extending that value to the size of the integer type. If value
is smaller than return type, then
a zero extension is done. If value
is larger than return type, then a truncation is done. If they are the same size, then nothing is done (no-op cast) other than a type change. The conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x i8> @llvm.vp.ptrtoint.v4i8.v4p0i32(<4 x ptr> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = ptrtoint <4 x ptr> %a to <4 x i8> %also.r = select <4 x i1> %mask, <4 x i8> %t, <4 x i8> poison
‘llvm.vp.inttoptr.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x ptr> @llvm.vp.inttoptr.v16p0.v16i32 (<16 x i32> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x ptr> @llvm.vp.inttoptr.nxv4p0.nxv4i32 (<vscale x 4 x i32> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x ptr> @llvm.vp.inttoptr.v256p0.v256i32 (<256 x i32> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.inttoptr
’ intrinsic converts its integer value to the point return type. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.inttoptr
’ intrinsic takes a value to cast as its first
operand , which must be a vector of integer type, and a type to cast it to return type, which must be a vector of pointers type. The second operand is the vector mask. The return type, the value to cast, and the vector mask have the same number of elements. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.inttoptr
’ intrinsic converts value
to return type by applying either a zero extension or a truncation depending on the size of the integer value
. If value
is larger than the size of a pointer, then a truncation is done. If value
is smaller than the size of a pointer, then a zero extension is done. If they are the same size, nothing is done (no-op cast). The
conversion is performed on lane positions below the explicit vector length and where the vector mask is true. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x ptr> @llvm.vp.inttoptr.v4p0i32.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = inttoptr <4 x i32> %a to <4 x ptr> %also.r = select <4 x i1> %mask, <4 x ptr> %t, <4 x ptr> poison
‘llvm.vp.fcmp.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i1> @llvm.vp.fcmp.v16f32(<16 x float> <left_op>, <16 x float> <right_op>, metadata <condition code>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i1> @llvm.vp.fcmp.nxv4f32(<vscale x 4 x float> <left_op>, <vscale x 4 x float> <right_op>, metadata <condition code>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i1> @llvm.vp.fcmp.v256f64(<256 x double> <left_op>, <256 x double> <right_op>, metadata <condition code>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
The
‘llvm.vp.fcmp
’ intrinsic returns a vector of boolean values based on the comparison of its operands. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.fcmp
’ intrinsic takes the two values to compare as its first and second operands. These two values must be vectors of
floating-point types. The return type is the result of the comparison. The return type must be a vector of i1 type. The fourth operand is the vector mask. The return type, the values to compare, and the vector mask have the same number of elements. The third operand is the condition code indicating the kind of comparison
to perform. It must be a metadata string with one of the supported floating-point condition code values. The fifth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.fcmp
’ compares its first two operands according to the condition code given
as the third operand. The operands are compared element by element on each enabled lane, where the the semantics of the comparison are defined according to the condition code. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x i1> @llvm.vp.fcmp.v4f32(<4 x float> %a, <4 x float> %b, metadata !"oeq", <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = fcmp oeq <4 x float> %a, %b %also.r = select <4 x i1> %mask, <4 x i1> %t, <4 x i1> poison
‘llvm.vp.icmp.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <32 x i1> @llvm.vp.icmp.v32i32(<32 x i32> <left_op>, <32 x i32> <right_op>, metadata <condition code>, <32 x i1> <mask>, i32 <vector_length>) declare <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> <left_op>, <vscale x 2 x i32> <right_op>, metadata <condition code>, <vscale x 2 x i1> <mask>, i32 <vector_length>) declare <128 x i1> @llvm.vp.icmp.v128i8(<128 x i8> <left_op>, <128 x i8> <right_op>, metadata <condition code>, <128 x i1> <mask>, i32 <vector_length>)
Overview:¶
The ‘llvm.vp.icmp
’ intrinsic returns a vector of boolean values based on the comparison of its operands. The operation has a mask and an explicit vector length parameter.
Arguments:¶
The ‘llvm.vp.icmp
’ intrinsic takes the two values to compare as its
first and second operands. These two values must be vectors of integer types. The return type is the result of the comparison. The return type must be a vector of i1 type. The fourth operand is the vector mask. The return type, the values to compare, and the vector mask have the same number of elements. The third operand
is the condition code indicating the kind of comparison to perform. It must be a metadata string with one of the supported integer condition code values. The fifth operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.icmp
’ compares its first
two operands according to the condition code given as the third operand. The operands are compared element by element on each enabled lane, where the the semantics of the comparison are defined according to the condition code. Masked-off lanes are poison
.
Examples:¶
%r = call <4 x i1> @llvm.vp.icmp.v4i32(<4 x i32> %a, <4 x i32> %b, metadata !"ne", <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = icmp ne <4 x i32> %a, %b %also.r = select <4 x i1> %mask, <4 x i1> %t, <4 x i1> poison
‘llvm.vp.ceil.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.ceil.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.ceil.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.ceil.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point ceiling of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.ceil
’ intrinsic performs floating-point ceiling (ceil) of the first vector operand on each enabled lane. The result on disabled
lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.ceil.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.ceil.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.floor.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.floor.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.floor.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.floor.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point floor of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.floor
’ intrinsic performs floating-point floor (floor) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.floor.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.floor.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.rint.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.rint.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.rint.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.rint.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point rint of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.rint
’ intrinsic performs floating-point rint (rint) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.rint.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.rint.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.nearbyint.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.nearbyint.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.nearbyint.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.nearbyint.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point nearbyint of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.nearbyint
’ intrinsic performs floating-point nearbyint (nearbyint) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.nearbyint.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.round.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.round.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.round.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.round.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point round of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.round
’ intrinsic performs floating-point round
(round) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.round.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.round.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.roundeven.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.roundeven.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.roundeven.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.roundeven.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point roundeven of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.roundeven
’ intrinsic performs floating-point roundeven (roundeven) of the first vector operand on each enabled lane. The result on disabled lanes is a
poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.roundeven.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.roundeven.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.roundtozero.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x float> @llvm.vp.roundtozero.v16f32 (<16 x float> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x float> @llvm.vp.roundtozero.nxv4f32 (<vscale x 4 x float> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x double> @llvm.vp.roundtozero.v256f64 (<256 x double> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated floating-point round-to-zero of a vector of floating-point values.
Arguments:¶
The first operand and the result have the same vector of floating-point type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.roundtozero
’ intrinsic performs floating-point roundeven (llvm.trunc) of the first vector operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x float> @llvm.vp.roundtozero.v4f32(<4 x float> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x float> @llvm.trunc.v4f32(<4 x float> %a) %also.r = select <4 x i1> %mask, <4 x float> %t, <4 x float> poison
‘llvm.vp.bswap.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic.
declare <16 x i32> @llvm.vp.bswap.v16i32 (<16 x i32> <op>, <16 x i1> <mask>, i32 <vector_length>) declare <vscale x 4 x i32> @llvm.vp.bswap.nxv4i32 (<vscale x 4 x i32> <op>, <vscale x 4 x i1> <mask>, i32 <vector_length>) declare <256 x i64> @llvm.vp.bswap.v256i64 (<256 x i64> <op>, <256 x i1> <mask>, i32 <vector_length>)
Overview:¶
Predicated bswap of two vectors of integers.
Arguments:¶
The first operand and the result have the same vector of integer type. The second operand is the vector mask and has the same number of elements as the result vector type. The third operand is the explicit vector length of the operation.
Semantics:¶
The ‘llvm.vp.bswap
’ intrinsic performs bswap (bswap) of the first operand on each enabled lane. The result on disabled lanes is a poison value.
Examples:¶
%r = call <4 x i32> @llvm.vp.bswap.v4i32(<4 x i32> %a, <4 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r %t = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %a) %also.r = select <4 x i1> %mask, <4 x i32> %t, <4 x i32> poison
Masked Vector Load and Store Intrinsics¶
LLVM provides intrinsics for predicated vector load and store operations. The predicate is specified by a mask operand, which holds one bit per vector element, switching the associated vector lane on or off. The memory addresses corresponding to the “off” lanes are not accessed. When all bits of the mask are on, the intrinsic is identical to a regular vector load or store. When all bits are off, no memory is accessed.
‘llvm.masked.load.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. The loaded data is a vector of any integer, floating-point or pointer data type.
declare <16 x float> @llvm.masked.load.v16f32.p0(ptr <ptr>, i32 <alignment>, <16 x i1> <mask>, <16 x float> <passthru>) declare <2 x double> @llvm.masked.load.v2f64.p0(ptr <ptr>, i32 <alignment>, <2 x i1> <mask>, <2 x double> <passthru>) ;; The data is a vector of pointers declare <8 x ptr> @llvm.masked.load.v8p0.p0(ptr <ptr>, i32 <alignment>, <8 x i1> <mask>, <8 x ptr> <passthru>)
Overview:¶
Reads a vector from memory according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes. The masked-off lanes in the result vector are taken from the corresponding lanes of the ‘passthru
’ operand.
Arguments:¶
The first operand is the base pointer for the load. The second operand is the alignment of the source location. It must be a power of two constant integer value. The third operand, mask, is a vector of boolean values with the same number of elements as the return type. The fourth is a pass-through value that is used to fill the masked-off lanes of the result. The return type,
underlying type of the base pointer and the type of the ‘passthru
’ operand are the same vector types.
Semantics:¶
The ‘llvm.masked.load
’ intrinsic is designed for conditional reading of selected vector elements in a single IR operation. It is useful for targets that support vector masked loads and allows vectorizing predicated basic blocks on these targets.
Other targets may support this intrinsic differently, for example by lowering it into a sequence of branches that guard scalar load operations. The result of this operation is equivalent to a regular vector load instruction followed by a ‘select’ between the loaded and the passthru values, predicated on the same mask. However, using this intrinsic prevents exceptions on memory access to masked-off lanes.
%res = call <16 x float> @llvm.masked.load.v16f32.p0(ptr %ptr, i32 4, <16 x i1>%mask, <16 x float> %passthru) ;; The result of the two following instructions is identical aside from potential memory access exception %loadlal = load <16 x float>, ptr %ptr, align 4 %res = select <16 x i1> %mask, <16 x float> %loadlal, <16 x float> %passthru
‘llvm.masked.store.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. The data stored in memory is a vector of any integer, floating-point or pointer data type.
declare void @llvm.masked.store.v8i32.p0 (<8 x i32> <value>, ptr <ptr>, i32 <alignment>, <8 x i1> <mask>) declare void @llvm.masked.store.v16f32.p0(<16 x float> <value>, ptr <ptr>, i32 <alignment>, <16 x i1> <mask>) ;; The data is a vector of pointers declare void @llvm.masked.store.v8p0.p0 (<8 x ptr> <value>, ptr <ptr>, i32 <alignment>, <8 x i1> <mask>)
Overview:¶
Writes a vector to memory according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes.
Arguments:¶
The first operand is the vector value to be written to memory. The second operand is the base pointer for the store, it has the same underlying type as the value operand. The third operand is the alignment of the destination location. It must be a power of two constant integer value. The fourth operand, mask, is a vector of boolean values. The types of the mask and the value operand must have the same number of vector elements.
Semantics:¶
The ‘llvm.masked.store
’ intrinsics is designed for conditional writing of selected vector elements in a single IR operation. It is useful for targets that support vector masked store and allows vectorizing predicated basic blocks on these targets. Other targets may support this intrinsic differently, for example by lowering it into a sequence of branches that guard scalar store operations. The
result of this operation is equivalent to a load-modify-store sequence. However, using this intrinsic prevents exceptions and data races on memory access to masked-off lanes.
call void @llvm.masked.store.v16f32.p0(<16 x float> %value, ptr %ptr, i32 4, <16 x i1> %mask) ;; The result of the following instructions is identical aside from potential data races and memory access exceptions %oldval = load <16 x float>, ptr %ptr, align 4 %res = select <16 x i1> %mask, <16 x float> %value, <16 x float> %oldval store <16 x float> %res, ptr %ptr, align 4
Masked Vector Gather and Scatter Intrinsics¶
LLVM provides intrinsics for vector gather and scatter operations. They are similar to Masked Vector Load and Store, except they are designed for arbitrary memory accesses, rather than sequential memory accesses. Gather and scatter also employ a mask operand, which holds one bit per vector element, switching the associated vector lane on or off. The memory addresses corresponding to the “off” lanes are not accessed. When all bits are off, no memory is accessed.
‘llvm.masked.gather.*
’
Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. The loaded data are multiple scalar values of any integer, floating-point or pointer data type gathered together into one vector.
declare <16 x float> @llvm.masked.gather.v16f32.v16p0(<16 x ptr> <ptrs>, i32 <alignment>, <16 x i1> <mask>, <16 x float> <passthru>) declare <2 x double> @llvm.masked.gather.v2f64.v2p1(<2 x ptr addrspace(1)> <ptrs>, i32 <alignment>, <2 x i1> <mask>, <2 x double> <passthru>) declare <8 x ptr> @llvm.masked.gather.v8p0.v8p0(<8 x ptr> <ptrs>, i32 <alignment>, <8 x i1> <mask>, <8 x ptr> <passthru>)
Overview:¶
Reads scalar
values from arbitrary memory locations and gathers them into one vector. The memory locations are provided in the vector of pointers ‘ptrs
’. The memory is accessed according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes. The masked-off lanes in the result vector are taken from the corresponding lanes of the ‘passthru
’ operand.
Arguments:¶
The first operand is a vector of pointers which holds all memory addresses to read. The second operand is an alignment of the source addresses. It must be 0 or a power of two constant integer value. The third operand, mask, is a vector of boolean values with the same number of elements as the return type. The fourth is a pass-through value that is used to fill the masked-off lanes of
the result. The return type, underlying type of the vector of pointers and the type of the ‘passthru
’ operand are the same vector types.
Semantics:¶
The ‘llvm.masked.gather
’ intrinsic is designed for conditional reading of multiple scalar values from arbitrary memory locations in a single IR operation. It is useful for targets that support vector masked gathers
and allows vectorizing basic blocks with data and control divergence. Other targets may support this intrinsic differently, for example by lowering it into a sequence of scalar load operations. The semantics of this operation are equivalent to a sequence of conditional scalar loads with subsequent gathering all loaded values into a single vector. The mask restricts memory access to certain lanes and facilitates vectorization of predicated basic blocks.
%res = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> %ptrs, i32 8, <4 x i1> <i1 true, i1 true, i1 true, i1 true>, <4 x double> poison) ;; The gather with all-true mask is equivalent to the following instruction sequence %ptr0 = extractelement <4 x ptr> %ptrs, i32 0 %ptr1 = extractelement <4 x ptr> %ptrs, i32 1 %ptr2 = extractelement <4 x ptr> %ptrs, i32 2 %ptr3 = extractelement <4 x ptr> %ptrs, i32 3 %val0 = load double, ptr %ptr0, align 8 %val1 = load double, ptr %ptr1, align 8 %val2 = load double, ptr %ptr2, align 8 %val3 = load double, ptr %ptr3, align 8 %vec0 = insertelement <4 x double> poison, %val0, 0 %vec01 = insertelement <4 x double> %vec0, %val1, 1 %vec012 = insertelement <4 x double> %vec01, %val2, 2 %vec0123 = insertelement <4 x double> %vec012, %val3, 3
‘llvm.masked.scatter.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. The data stored in memory is a vector of any integer, floating-point or pointer data type. Each vector element is stored in an arbitrary memory address. Scatter with overlapping addresses is guaranteed to be ordered from least-significant to most-significant element.
declare void @llvm.masked.scatter.v8i32.v8p0 (<8 x i32> <value>, <8 x ptr> <ptrs>, i32 <alignment>, <8 x i1> <mask>) declare void @llvm.masked.scatter.v16f32.v16p1(<16 x float> <value>, <16 x ptr addrspace(1)> <ptrs>, i32 <alignment>, <16 x i1> <mask>) declare void @llvm.masked.scatter.v4p0.v4p0 (<4 x ptr> <value>, <4 x ptr> <ptrs>, i32 <alignment>, <4 x i1> <mask>)
Overview:¶
Writes each element from the value vector to the corresponding memory address. The memory addresses are represented as a vector of pointers. Writing is done according to the provided mask. The mask holds a bit for each vector lane, and is used to prevent memory accesses to the masked-off lanes.
Arguments:¶
The first operand is a vector value to be written to memory. The second operand is a vector of pointers, pointing to where the value elements should be stored. It has the same underlying type as the value operand. The third operand is an alignment of the destination addresses. It must be 0 or a power of two constant integer value. The fourth operand, mask, is a vector of boolean values. The types of the mask and the value operand must have the same number of vector elements.
Semantics:¶
The ‘llvm.masked.scatter
’
intrinsics is designed for writing selected vector elements to arbitrary memory addresses in a single IR operation. The operation may be conditional, when not all bits in the mask are switched on. It is useful for targets that support vector masked scatter and allows vectorizing basic blocks with data and control divergence. Other targets may support this intrinsic differently, for example by lowering it into a sequence of branches that guard scalar store operations.
;; This instruction unconditionally stores data vector in multiple addresses call @llvm.masked.scatter.v8i32.v8p0(<8 x i32> %value, <8 x ptr> %ptrs, i32 4, <8 x i1> <true, true, .. true>) ;; It is equivalent to a list of scalar stores %val0 = extractelement <8 x i32> %value, i32 0 %val1 = extractelement <8 x i32> %value, i32 1 .. %val7 = extractelement <8 x i32> %value, i32 7 %ptr0 = extractelement <8 x ptr> %ptrs, i32 0 %ptr1 = extractelement <8 x ptr> %ptrs, i32 1 .. %ptr7 = extractelement <8 x ptr> %ptrs, i32 7 ;; Note: the order of the following stores is important when they overlap: store i32 %val0, ptr %ptr0, align 4 store i32 %val1, ptr %ptr1, align 4 .. store i32 %val7, ptr %ptr7, align 4
Masked Vector Expanding Load and Compressing Store Intrinsics¶
LLVM provides intrinsics for expanding load and compressing store operations. Data selected from a vector according to a mask is stored in consecutive memory addresses (compressed store), and vice-versa (expanding load). These operations effective map to “if (cond.i) a[j++] = v.i” and “if (cond.i) v.i = a[j++]” patterns, respectively. Note that when the mask starts with ‘1’ bits followed by ‘0’ bits, these operations are identical to llvm.masked.store and llvm.masked.load.
‘llvm.masked.expandload.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. Several values of integer, floating point or pointer data type are loaded from consecutive memory addresses and stored into the elements of a vector according to the mask.
declare <16 x float> @llvm.masked.expandload.v16f32 (ptr <ptr>, <16 x i1> <mask>, <16 x float> <passthru>) declare <2 x i64> @llvm.masked.expandload.v2i64 (ptr <ptr>, <2 x i1> <mask>, <2 x i64> <passthru>)
Overview:¶
Reads a
number of scalar values sequentially from memory location provided in ‘ptr
’ and spreads them in a vector. The ‘mask
’ holds a bit for each vector lane. The number of elements read from memory is equal to the number of ‘1’ bits in the mask. The loaded elements are positioned in the destination vector according to the sequence of ‘1’ and ‘0’ bits in the mask. E.g., if the mask vector is ‘10010001’, “expandload” reads 3 values from memory addresses ptr, ptr+1, ptr+2 and places them in lanes
0, 3 and 7 accordingly. The masked-off lanes are filled by elements from the corresponding lanes of the ‘passthru
’ operand.
Arguments:¶
The first operand is the base pointer for the load. It has the same underlying type as the element of the returned vector. The second operand, mask, is a vector of boolean values with the same number of elements as the
return type. The third is a pass-through value that is used to fill the masked-off lanes of the result. The return type and the type of the ‘passthru
’ operand have the same vector type.
Semantics:¶
The ‘llvm.masked.expandload
’ intrinsic is designed for reading multiple scalar values from adjacent memory addresses into possibly non-adjacent vector lanes. It is useful
for targets that support vector expanding loads and allows vectorizing loop with cross-iteration dependency like in the following example:
// In this loop we load from B and spread the elements into array A. double *A, B; int *C; for (int i = 0; i < size; ++i) { if (C[i] != 0) A[i] = B[j++]; }
; Load several elements from array B and expand them in a vector. ; The number of loaded elements is equal to the number of '1' elements in the Mask. %Tmp = call <8 x double> @llvm.masked.expandload.v8f64(ptr %Bptr, <8 x i1> %Mask, <8 x double> poison) ; Store the result in A call void @llvm.masked.store.v8f64.p0(<8 x double> %Tmp, ptr %Aptr, i32 8, <8 x i1> %Mask) ; %Bptr should be increased on each iteration according to the number of '1' elements in the Mask. %MaskI = bitcast <8 x i1> %Mask to i8 %MaskIPopcnt = call i8 @llvm.ctpop.i8(i8 %MaskI) %MaskI64 = zext i8 %MaskIPopcnt to i64 %BNextInd = add i64 %BInd, %MaskI64
Other targets may support this intrinsic differently, for example, by lowering it into a sequence of conditional scalar load operations and shuffles. If all mask elements are ‘1’, the intrinsic behavior is equivalent to the regular unmasked vector load.
‘llvm.masked.compressstore.*
’ Intrinsics¶
Syntax:¶
This is an overloaded intrinsic. A number of scalar values of integer, floating point or pointer data type are collected from an input vector and stored into adjacent memory addresses. A mask defines which elements to collect from the vector.
declare void @llvm.masked.compressstore.v8i32 (<8 x i32> <value>, ptr <ptr>, <8 x i1> <mask>) declare void @llvm.masked.compressstore.v16f32 (<16 x float> <value>, ptr <ptr>, <16 x i1> <mask>)
Overview:¶
Selects elements from input vector ‘value
’ according to the ‘mask
’. All selected elements are written into adjacent memory addresses starting at address ‘ptr’, from lower to
higher. The mask holds a bit for each vector lane, and is used to select elements to be stored. The number of elements to be stored is equal to the number of active bits in the mask.
Arguments:¶
The first operand is the input vector, from which elements are collected and written to memory. The second operand is the base pointer for the store, it has the same underlying type as the element of the input vector operand. The third operand is the mask, a vector of boolean values. The mask and the input vector must have the same number of vector elements.
Semantics:¶
The ‘llvm.masked.compressstore
’ intrinsic is designed for compressing data in memory. It allows to collect elements from possibly non-adjacent lanes of a vector
and store them contiguously in memory in one IR operation. It is useful for targets that support compressing store operations and allows vectorizing loops with cross-iteration dependences like in the following example:
// In this loop we load elements from A and store them consecutively in B double *A, B; int *C; for (int i = 0; i < size; ++i) { if (C[i] != 0) B[j++] = A[i] }
; Load elements from A. %Tmp = call <8 x double> @llvm.masked.load.v8f64.p0(ptr %Aptr, i32 8, <8 x i1> %Mask, <8 x double> poison) ; Store all selected elements consecutively in array B call <void> @llvm.masked.compressstore.v8f64(<8 x double> %Tmp, ptr %Bptr, <8 x i1> %Mask) ; %Bptr should be increased on each iteration according to the number of '1' elements in the Mask. %MaskI = bitcast <8 x i1> %Mask to i8 %MaskIPopcnt = call i8 @llvm.ctpop.i8(i8 %MaskI) %MaskI64 = zext i8 %MaskIPopcnt to i64 %BNextInd = add i64 %BInd, %MaskI64
Other targets may support this intrinsic differently, for example, by lowering it into a sequence of branches that guard scalar store operations.
Memory Use Markers¶
This class of intrinsics provides information about the lifetime of memory objects and ranges where variables are immutable.
‘llvm.lifetime.start
’ Intrinsic¶
Syntax:¶
declare void @llvm.lifetime.start(i64 <size>, ptr nocapture <ptr>)
Overview:¶
The ‘llvm.lifetime.start
’ intrinsic specifies the start of a memory object’s lifetime.
Arguments:¶
The first argument is a constant integer representing the size of the object, or -1 if it is variable sized. The second argument is a pointer to the object.
Semantics:¶
If ptr
is a stack-allocated object and it points to the first byte of the object, the object is initially marked as dead. ptr
is conservatively considered as a non-stack-allocated object if the stack coloring algorithm that is used in the optimization pipeline cannot conclude that ptr
is a stack-allocated object.
After
‘llvm.lifetime.start
’, the stack object that ptr
points is marked as alive and has an uninitialized value. The stack object is marked as dead when either llvm.lifetime.end to the alloca is executed or the function returns.
After llvm.lifetime.end is called, ‘llvm.lifetime.start
’ on the stack object can be called again. The second
‘llvm.lifetime.start
’ call marks the object as alive, but it does not change the address of the object.
If ptr
is a non-stack-allocated object, it does not point to the first byte of the object or it is a stack object that is already alive, it simply fills all bytes of the object with poison
.
‘llvm.lifetime.end
’
Intrinsic¶
Syntax:¶
declare void @llvm.lifetime.end(i64 <size>, ptr nocapture <ptr>)
Overview:¶
The ‘llvm.lifetime.end
’ intrinsic specifies the end
of a memory object’s lifetime.
Arguments:¶
The first argument is a constant integer representing the size of the object, or -1 if it is variable sized. The second argument is a pointer to the object.
Semantics:¶
If
ptr
is a stack-allocated object and it points to the first byte of the object, the object is dead. ptr
is conservatively considered as a non-stack-allocated object if the stack coloring algorithm that is used in the optimization pipeline cannot conclude that ptr
is a stack-allocated object.
Calling llvm.lifetime.end
on an already dead alloca is no-op.
If ptr
is a non-stack-allocated object or it does not point to the first byte of the object, it is equivalent to simply
filling all bytes of the object with poison
.
‘llvm.invariant.start
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. The memory object can belong to any address space.
declare ptr @llvm.invariant.start.p0(i64 <size>, ptr nocapture <ptr>)
Overview:¶
The ‘llvm.invariant.start
’ intrinsic specifies that the contents of a memory object will not change.
Arguments:¶
The first argument is a constant integer representing the size of the object, or -1 if it is variable sized. The second argument is a pointer to the object.
Semantics:¶
This intrinsic indicates that until an llvm.invariant.end
that uses the return value, the referenced memory location is constant and unchanging.
‘llvm.invariant.end
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. The memory object can belong to any address space.
declare void @llvm.invariant.end.p0(ptr <start>, i64 <size>, ptr nocapture <ptr>)
Overview:¶
The ‘llvm.invariant.end
’ intrinsic specifies that the contents of a memory object are mutable.
Arguments:¶
The first argument is the matching llvm.invariant.start
intrinsic. The second argument is a constant integer representing the size of the object, or -1 if it
is variable sized and the third argument is a pointer to the object.
Semantics:¶
This intrinsic indicates that the memory is mutable again.
‘llvm.launder.invariant.group
’
Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. The memory object can belong to any address space. The returned pointer must belong to the same address space as the argument.
declare ptr @llvm.launder.invariant.group.p0(ptr <ptr>)
Overview:¶
The ‘llvm.launder.invariant.group
’ intrinsic can be used when an invariant established by invariant.group
metadata no longer holds, to obtain a new pointer value that carries fresh invariant group information. It is an experimental intrinsic, which means that its semantics might change in the future.
Arguments:¶
The llvm.launder.invariant.group
takes only one argument, which is a pointer to the memory.
Semantics:¶
Returns another pointer that aliases its argument but which is considered different for the purposes of load
/store
invariant.group
metadata. It does not read
any accessible memory and the execution can be speculated.
‘llvm.strip.invariant.group
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. The memory object can belong to any address space. The returned pointer must belong to the same address space as the argument.
declare ptr @llvm.strip.invariant.group.p0(ptr <ptr>)
Overview:¶
The ‘llvm.strip.invariant.group
’ intrinsic can be used when an invariant established by invariant.group
metadata no longer holds, to obtain a new pointer value that does not carry the
invariant information. It is an experimental intrinsic, which means that its semantics might change in the future.
Arguments:¶
The llvm.strip.invariant.group
takes only one argument, which is a pointer to the memory.
Semantics:¶
Returns
another pointer that aliases its argument but which has no associated invariant.group
metadata. It does not read any memory and can be speculated.
Constrained Floating-Point Intrinsics¶
These intrinsics are used to provide special handling of floating-point operations when specific rounding mode or floating-point exception behavior is required. By default, LLVM optimization passes assume that the rounding mode is round-to-nearest and that floating-point exceptions will not be monitored. Constrained FP intrinsics are used to support non-default rounding modes and accurately preserve exception behavior without compromising LLVM’s ability to optimize FP code when the default behavior is used.
If any FP operation in a function is constrained then they all must be constrained. This is required for correct LLVM IR. Optimizations that move code around can create miscompiles if mixing of constrained and normal operations is done. The correct way to mix constrained and less constrained operations is to use the rounding mode and exception handling metadata to mark constrained intrinsics as having LLVM’s default behavior.
Each of these intrinsics corresponds to a normal floating-point operation. The data arguments and the return value are the same as the corresponding FP operation.
The rounding mode argument is a metadata string specifying what assumptions, if any, the optimizer can make when transforming constant values. Some constrained FP intrinsics omit this argument. If required by the intrinsic, this argument must be one of the following strings:
"round.dynamic" "round.tonearest" "round.downward" "round.upward" "round.towardzero" "round.tonearestaway"
If this argument is “round.dynamic” optimization passes must assume that the rounding mode is unknown and may change at runtime. No transformations that depend on rounding mode may be performed in this case.
The other possible values for the rounding mode argument correspond to the similarly named IEEE rounding modes. If the argument is any of these values optimization passes may perform transformations as long as they are consistent with the specified rounding mode.
For example, ‘x-0’->’x’ is not a valid transformation if the rounding mode is “round.downward” or “round.dynamic” because if the value of ‘x’ is +0 then ‘x-0’ should evaluate to ‘-0’ when rounding downward. However, this transformation is legal for all other rounding modes.
For values other than “round.dynamic” optimization passes may assume that the actual runtime rounding mode (as defined in a target-specific manner) matches the specified rounding mode, but this is not guaranteed. Using a specific non-dynamic rounding mode which does not match the actual rounding mode at runtime results in undefined behavior.
The exception behavior argument is a metadata string describing the floating point exception semantics that required for the intrinsic. This argument must be one of the following strings:
"fpexcept.ignore" "fpexcept.maytrap" "fpexcept.strict"
If this argument is “fpexcept.ignore” optimization passes may assume that the exception status flags will not be read and that floating-point exceptions will be masked. This allows transformations to be performed that may change the exception semantics of the original code. For example, FP operations may be speculatively executed in this case whereas they must not be for either of the other possible values of this argument.
If the exception behavior argument is “fpexcept.maytrap” optimization passes must avoid transformations that may raise exceptions that would not have been raised by the original code (such as speculatively executing FP operations), but passes are not required to preserve all exceptions that are implied by the original code. For example, exceptions may be potentially hidden by constant folding.
If the exception behavior argument is “fpexcept.strict” all transformations must strictly preserve the floating-point exception semantics of the original code. Any FP exception that would have been raised by the original code must be raised by the transformed code, and the transformed code must not raise any FP exceptions that would not have been raised by the original code. This is the exception behavior argument that will be used if the code being compiled reads the FP exception status flags, but this mode can also be used with code that unmasks FP exceptions.
The number and order of floating-point exceptions is NOT guaranteed. For example, a series of FP operations that each may raise exceptions may be vectorized into a single instruction that raises each unique exception a single time.
Proper function attributes usage is required for the constrained intrinsics to function correctly.
All function calls done in a function that uses constrained floating point intrinsics must have the strictfp
attribute.
All function definitions that use constrained floating point intrinsics must have the strictfp
attribute.
‘llvm.experimental.constrained.fadd
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fadd(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fadd
’ intrinsic
returns the sum of its two operands.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.fadd
’ intrinsic must be floating-point or vector of floating-point values. Both arguments must
have identical types.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The value produced is the floating-point sum of the two value operands and has the same type as the operands.
‘llvm.experimental.constrained.fsub
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fsub(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fsub
’ intrinsic returns the difference of its two operands.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.fsub
’ intrinsic must be
floating-point or vector of floating-point values. Both arguments must have identical types.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The value produced is the floating-point difference of the two value operands and has the same type as the operands.
‘llvm.experimental.constrained.fmul
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fmul(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fmul
’ intrinsic returns the product of its two operands.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.fmul
’ intrinsic must be floating-point or vector of floating-point values. Both arguments must have identical types.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The value produced is the floating-point product of the two value operands and has the same type as the operands.
‘llvm.experimental.constrained.fdiv
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fdiv(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fdiv
’ intrinsic returns the quotient of its two operands.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.fdiv
’ intrinsic must be floating-point or vector of floating-point values. Both arguments must have identical types.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The value produced is the floating-point quotient of the two value operands and has the same type as the operands.
‘llvm.experimental.constrained.frem
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.frem(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.frem
’ intrinsic
returns the remainder from the division of its two operands.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.frem
’ intrinsic must be floating-point or vector of floating-point
values. Both arguments must have identical types.
The third and fourth arguments specify the rounding mode and exception behavior as described above. The rounding mode argument has no effect, since the result of frem is never rounded, but the argument is included for consistency with the other constrained floating-point intrinsics.
Semantics:¶
The value produced is the floating-point remainder from the division of the two value operands and has the same type as the operands. The remainder has the same sign as the dividend.
‘llvm.experimental.constrained.fma
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fma(<type> <op1>, <type> <op2>, <type> <op3>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fma
’ intrinsic returns the result of a fused-multiply-add operation on its operands.
Arguments:¶
The first three arguments to the ‘llvm.experimental.constrained.fma
’ intrinsic must be floating-point or vector of floating-point values. All arguments must have identical types.
The fourth and fifth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The result produced is the product of the first two operands added to the third operand computed with infinite precision, and then rounded to the target precision.
‘llvm.experimental.constrained.fptoui
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.fptoui(<type> <value>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fptoui
’ intrinsic converts a floating-point value
to its unsigned integer equivalent of type ty2
.
Arguments:¶
The first argument to the ‘llvm.experimental.constrained.fptoui
’ intrinsic must be
floating point or vector of floating point values.
The second argument specifies the exception behavior as described above.
Semantics:¶
The result produced is an unsigned integer converted from the floating point operand. The value is truncated, so it is rounded towards zero.
‘llvm.experimental.constrained.fptosi
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.fptosi(<type> <value>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fptosi
’ intrinsic converts floating-point value
to type ty2
.
Arguments:¶
The first argument to the ‘llvm.experimental.constrained.fptosi
’ intrinsic must be floating point or vector of floating point values.
The second argument specifies the exception behavior as described above.
Semantics:¶
The result produced is a signed integer converted from the floating point operand. The value is truncated, so it is rounded towards zero.
‘llvm.experimental.constrained.uitofp
’
Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.uitofp(<type> <value>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.uitofp
’
intrinsic converts an unsigned integer value
to a floating-point of type ty2
.
Arguments:¶
The first argument to the ‘llvm.experimental.constrained.uitofp
’ intrinsic must be an integer or vector of
integer values.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
An inexact floating-point exception will be raised if rounding is required. Any result produced is a floating point value converted from the input integer operand.
‘llvm.experimental.constrained.sitofp
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.sitofp(<type> <value>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.sitofp
’ intrinsic converts a signed integer value
to a floating-point of type ty2
.
Arguments:¶
The first argument to the ‘llvm.experimental.constrained.sitofp
’ intrinsic must be an
integer or vector of integer values.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
An inexact floating-point exception will be raised if rounding is required. Any result produced is a floating point value converted from the input integer operand.
‘llvm.experimental.constrained.fptrunc
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.fptrunc(<type> <value>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fptrunc
’ intrinsic truncates value
to type ty2
.
Arguments:¶
The
first argument to the ‘llvm.experimental.constrained.fptrunc
’ intrinsic must be floating point or vector of floating point values. This argument must be larger in size than the result.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The result produced is a floating point value truncated to be smaller in size than the operand.
‘llvm.experimental.constrained.fpext
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.fpext(<type> <value>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fpext
’ intrinsic extends a floating-point value
to a larger floating-point value.
Arguments:¶
The first argument to the ‘llvm.experimental.constrained.fpext
’ intrinsic must be floating point or vector of floating point values. This argument must be smaller in size than the result.
The second argument specifies the exception behavior as described above.
Semantics:¶
The result produced is a floating point value extended to be larger in size than the operand. All restrictions that apply to the fpext instruction also apply to this intrinsic.
‘llvm.experimental.constrained.fcmp
’ and ‘llvm.experimental.constrained.fcmps
’ Intrinsics¶
Syntax:¶
declare <ty2> @llvm.experimental.constrained.fcmp(<type> <op1>, <type> <op2>, metadata <condition code>, metadata <exception behavior>) declare <ty2> @llvm.experimental.constrained.fcmps(<type> <op1>, <type> <op2>, metadata <condition code>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fcmp
’ and ‘llvm.experimental.constrained.fcmps
’ intrinsics return a boolean value or vector of boolean values based on comparison of its operands.
If the operands are floating-point scalars, then the result type is a boolean (i1).
If the operands are floating-point vectors, then the result type is a vector of boolean with the same number of elements as the operands being compared.
The ‘llvm.experimental.constrained.fcmp
’ intrinsic performs a quiet comparison operation while the ‘llvm.experimental.constrained.fcmps
’ intrinsic performs a signaling comparison operation.
Arguments:¶
The first two arguments to the ‘llvm.experimental.constrained.fcmp
’ and ‘llvm.experimental.constrained.fcmps
’ intrinsics must be
floating-point or vector of floating-point values. Both arguments must have identical types.
The third argument is the condition code indicating the kind of comparison to perform. It must be a metadata string with one of the following values:
- “
oeq
”: ordered and equal - “
ogt
”: ordered and greater than - “
oge
”: ordered and greater than or equal - “
olt
”: ordered and less than - “
ole
”: ordered and less than or equal - “
one
”: ordered and not equal - “
ord
”: ordered (no nans) - “
ueq
”: unordered or equal - “
ugt
”: unordered or greater than - “
uge
”: unordered or greater than or equal - “
ult
”: unordered or less than - “
ule
”: unordered or less than or equal - “
une
”: unordered or not equal - “
uno
”: unordered (either nans)
Ordered means that neither operand is a NAN while unordered means that either operand may be a NAN.
The fourth argument specifies the exception behavior as described above.
Semantics:¶
op1
and op2
are compared according to the condition code
given as the third argument. If the operands are vectors, then the vectors are compared element by element. Each comparison performed always yields an i1 result, as follows:
- “
oeq
”: yieldstrue
if both operands are not a NAN andop1
is equal toop2
. - “
ogt
”: yieldstrue
if both operands are not a NAN andop1
is greater thanop2
. - “
oge
”: yieldstrue
if both operands are not a NAN andop1
is greater than or equal toop2
. - “
olt
”: yieldstrue
if both operands are not a NAN andop1
is less thanop2
. - “
ole
”: yieldstrue
if both operands are not a NAN andop1
is less than or equal toop2
. - “
one
”: yieldstrue
if both operands are not a NAN andop1
is not equal toop2
. - “
ord
”: yieldstrue
if both operands are not a NAN. - “
ueq
”: yieldstrue
if either operand is a NAN orop1
is equal toop2
. - “
ugt
”: yieldstrue
if either operand is a NAN orop1
is greater thanop2
. - “
uge
”: yieldstrue
if either operand is a NAN orop1
is greater than or equal toop2
. - “
ult
”: yieldstrue
if either operand is a NAN orop1
is less thanop2
. - “
ule
”: yieldstrue
if either operand is a NAN orop1
is less than or equal toop2
. - “
une
”: yieldstrue
if either operand is a NAN orop1
is not equal toop2
. - “
uno
”: yieldstrue
if either operand is a NAN.
The quiet comparison operation performed by ‘llvm.experimental.constrained.fcmp
’ will only raise an exception if either operand is a SNAN. The signaling comparison operation performed by ‘llvm.experimental.constrained.fcmps
’ will raise an exception if either operand is a NAN (QNAN or SNAN). Such an exception does not preclude a result being
produced (e.g. exception might only set a flag), therefore the distinction between ordered and unordered comparisons is also relevant for the ‘llvm.experimental.constrained.fcmps
’ intrinsic.
‘llvm.experimental.constrained.fmuladd
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.fmuladd(<type> <op1>, <type> <op2>, <type> <op3>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.fmuladd
’ intrinsic represents multiply-add expressions that can be fused if the code generator determines that (a) the target instruction set has support for a fused operation, and (b)
that the fused operation is more efficient than the equivalent, separate pair of mul and add instructions.
Arguments:¶
The first three arguments to the ‘llvm.experimental.constrained.fmuladd
’ intrinsic must be floating-point or vector of floating-point values. All three arguments must have identical types.
The fourth and fifth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
The expression:
%0 = call float @llvm.experimental.constrained.fmuladd.f32(%a, %b, %c, metadata <rounding mode>, metadata <exception behavior>)
is equivalent to the expression:
%0 = call float @llvm.experimental.constrained.fmul.f32(%a, %b, metadata <rounding mode>, metadata <exception behavior>) %1 = call float @llvm.experimental.constrained.fadd.f32(%0, %c, metadata <rounding mode>, metadata <exception behavior>)
except that it is unspecified whether rounding will be performed between the multiplication and addition steps. Fusion is not guaranteed, even if the target platform supports it. If a fused multiply-add is required,
the corresponding llvm.experimental.constrained.fma intrinsic function should be used instead. This never sets errno, just as ‘llvm.experimental.constrained.fma.*
’.
Constrained libm-equivalent Intrinsics¶
In addition to the basic floating-point operations for which constrained intrinsics are described above, there are constrained versions of various operations which provide equivalent behavior to a corresponding libm function. These intrinsics allow the precise behavior of these operations with respect to rounding mode and exception behavior to be controlled.
As with the basic constrained floating-point intrinsics, the rounding mode and exception behavior arguments only control the behavior of the optimizer. They do not change the runtime floating-point environment.
‘llvm.experimental.constrained.sqrt
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.sqrt(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.sqrt
’ intrinsic
returns the square root of the specified value, returning the same value as the libm ‘sqrt
’ functions would, but without setting errno
.
Arguments:¶
The first argument and the return type are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the nonnegative square root of the specified value. If the value is less than negative zero, a floating-point exception occurs and the return value is architecture specific.
‘llvm.experimental.constrained.pow
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.pow(<type> <op1>, <type> <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.pow
’ intrinsic
returns the first operand raised to the (positive or negative) power specified by the second operand.
Arguments:¶
The first two arguments and the return value are floating-point numbers of the same type. The second argument specifies the power to which the first argument should be raised.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the first value raised to the second power, returning the same values as the libm pow
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.powi
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.powi(<type> <op1>, i32 <op2>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.powi
’ intrinsic returns the first operand raised to the (positive or negative) power specified by the second operand. The order of evaluation of multiplications is not defined. When a vector of floating-point type is used, the second argument remains a scalar integer value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type. The second argument is a 32-bit signed integer specifying the power to which the first argument should be raised.
The third and fourth arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the first value raised to the second power with an unspecified sequence of rounding operations.
‘llvm.experimental.constrained.sin
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.sin(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.sin
’ intrinsic
returns the sine of the first operand.
Arguments:¶
The first argument and the return type are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the sine of the specified operand, returning the same values as the libm sin
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.cos
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.cos(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.cos
’ intrinsic
returns the cosine of the first operand.
Arguments:¶
The first argument and the return type are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the cosine of the specified operand, returning the same values as the libm cos
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.exp
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.exp(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.exp
’ intrinsic
computes the base-e exponential of the specified value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm exp
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.exp2
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.exp2(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.exp2
’ intrinsic
computes the base-2 exponential of the specified value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm exp2
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.log
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.log(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.log
’ intrinsic
computes the base-e logarithm of the specified value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm log
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.log10
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.log10(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.log10
’ intrinsic
computes the base-10 logarithm of the specified value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm log10
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.log2
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.log2(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.log2
’ intrinsic
computes the base-2 logarithm of the specified value.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm log2
functions would, and handles error conditions in the same way.
‘llvm.experimental.constrained.rint
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.rint(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.rint
’ intrinsic
returns the first operand rounded to the nearest integer. It may raise an inexact floating-point exception if the operand is not an integer.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm rint
functions would, and handles error conditions in the same way. The rounding mode is described, not determined, by the rounding mode argument. The actual rounding mode is determined by the runtime floating-point environment. The rounding mode argument is only intended as information to the
compiler.
‘llvm.experimental.constrained.lrint
’ Intrinsic¶
Syntax:¶
declare <inttype> @llvm.experimental.constrained.lrint(<fptype> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.lrint
’ intrinsic returns the first operand rounded to the nearest integer. An inexact floating-point exception will be raised if the operand is not an integer. An invalid exception is raised if the result is too large to fit into a supported integer type, and in this case the result is undefined.
Arguments:¶
The first argument is a floating-point number. The return value is an integer type. Not all types are supported on all targets. The supported types are the same as the llvm.lrint
intrinsic and the lrint
libm functions.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm lrint
functions would, and handles error conditions in the same way.
The rounding mode is described, not determined, by the rounding mode argument. The actual rounding mode is determined by the runtime floating-point environment. The rounding mode argument is only intended as information to the compiler.
If the runtime floating-point environment is using the default rounding mode then the results will be the same as the llvm.lrint intrinsic.
‘llvm.experimental.constrained.llrint
’ Intrinsic¶
Syntax:¶
declare <inttype> @llvm.experimental.constrained.llrint(<fptype> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.llrint
’ intrinsic returns the first operand rounded to the nearest integer. An inexact floating-point exception will be raised if the operand is not an integer. An invalid exception is raised if the result is too
large to fit into a supported integer type, and in this case the result is undefined.
Arguments:¶
The first argument is a floating-point number. The return value is an integer type. Not all types are supported on all targets. The supported types are the same as the llvm.llrint
intrinsic and the llrint
libm functions.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm llrint
functions would, and handles error conditions in the same way.
The rounding mode is described, not determined, by the rounding mode argument. The actual rounding mode is determined by the runtime floating-point environment. The rounding mode argument is only intended as information to the compiler.
If the runtime floating-point environment is using the default rounding mode then the results will be the same as the llvm.llrint intrinsic.
‘llvm.experimental.constrained.nearbyint
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.nearbyint(<type> <op1>, metadata <rounding mode>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.nearbyint
’
intrinsic returns the first operand rounded to the nearest integer. It will not raise an inexact floating-point exception if the operand is not an integer.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second and third arguments specify the rounding mode and exception behavior as described above.
Semantics:¶
This function returns the same values as the libm nearbyint
functions would, and handles error conditions in the same way. The rounding mode is described, not determined, by the rounding mode argument. The actual rounding mode is determined by the runtime floating-point environment. The rounding mode argument is only intended as
information to the compiler.
‘llvm.experimental.constrained.maxnum
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.maxnum(<type> <op1>, <type> <op2> metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.maxnum
’ intrinsic returns the maximum of the two arguments.
Arguments:¶
The first two arguments and the return value are floating-point numbers of the same type.
The third argument specifies the exception behavior as described above.
Semantics:¶
This function follows the IEEE-754 semantics for maxNum.
‘llvm.experimental.constrained.minnum
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.minnum(<type> <op1>, <type> <op2> metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.minnum
’
intrinsic returns the minimum of the two arguments.
Arguments:¶
The first two arguments and the return value are floating-point numbers of the same type.
The third argument specifies the exception behavior as described above.
Semantics:¶
This function follows the IEEE-754 semantics for minNum.
‘llvm.experimental.constrained.maximum
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.maximum(<type> <op1>, <type> <op2> metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.maximum
’ intrinsic returns the maximum of the two arguments, propagating NaNs and treating -0.0 as less than +0.0.
Arguments:¶
The first two arguments and the return value are floating-point numbers of the same type.
The third argument specifies the exception behavior as described above.
Semantics:¶
This function follows semantics specified in the draft of IEEE 754-2018.
‘llvm.experimental.constrained.minimum
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.minimum(<type> <op1>, <type> <op2> metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.minimum
’ intrinsic returns the minimum of the two arguments, propagating NaNs and treating -0.0 as less than +0.0.
Arguments:¶
The first two arguments and the return value are floating-point numbers of the same type.
The third argument specifies the exception behavior as described above.
Semantics:¶
This function follows semantics specified in the draft of IEEE 754-2018.
‘llvm.experimental.constrained.ceil
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.ceil(<type> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.ceil
’ intrinsic
returns the ceiling of the first operand.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm ceil
functions would and handles error conditions in the same way.
‘llvm.experimental.constrained.floor
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.floor(<type> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.floor
’ intrinsic
returns the floor of the first operand.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm floor
functions would and handles error conditions in the same way.
‘llvm.experimental.constrained.round
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.round(<type> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.round
’ intrinsic
returns the first operand rounded to the nearest integer.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm round
functions would and handles error conditions in the same way.
‘llvm.experimental.constrained.roundeven
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.roundeven(<type> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.roundeven
’
intrinsic returns the first operand rounded to the nearest integer in floating-point format, rounding halfway cases to even (that is, to the nearest value that is an even integer), regardless of the current rounding direction.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function implements IEEE-754 operation roundToIntegralTiesToEven
. It also behaves in the same way as C standard function roundeven
and can signal the invalid operation exception for a SNAN operand.
‘llvm.experimental.constrained.lround
’ Intrinsic¶
Syntax:¶
declare <inttype> @llvm.experimental.constrained.lround(<fptype> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.lround
’ intrinsic returns the first operand rounded to the nearest integer with ties away from zero. It will raise an inexact floating-point exception if the operand is not an integer. An invalid exception is raised if the result is too large to fit into a supported integer type, and in this case the result is undefined.
Arguments:¶
The first argument is a floating-point number. The return value is an integer type. Not all types are supported on all targets. The supported types are the same as the llvm.lround
intrinsic and the lround
libm functions.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm lround
functions would and handles error conditions in the same way.
‘llvm.experimental.constrained.llround
’
Intrinsic¶
Syntax:¶
declare <inttype> @llvm.experimental.constrained.llround(<fptype> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.llround
’
intrinsic returns the first operand rounded to the nearest integer with ties away from zero. It will raise an inexact floating-point exception if the operand is not an integer. An invalid exception is raised if the result is too large to fit into a supported integer type, and in this case the result is undefined.
Arguments:¶
The first argument is a
floating-point number. The return value is an integer type. Not all types are supported on all targets. The supported types are the same as the llvm.llround
intrinsic and the llround
libm functions.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm llround
functions
would and handles error conditions in the same way.
‘llvm.experimental.constrained.trunc
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.experimental.constrained.trunc(<type> <op1>, metadata <exception behavior>)
Overview:¶
The ‘llvm.experimental.constrained.trunc
’ intrinsic returns the first operand rounded to the nearest integer not larger in magnitude than the operand.
Arguments:¶
The first argument and the return value are floating-point numbers of the same type.
The second argument specifies the exception behavior as described above.
Semantics:¶
This function returns the same values as the libm trunc
functions would and handles error conditions in the same way.
‘llvm.experimental.noalias.scope.decl
’ Intrinsic¶
Syntax:¶
declare void @llvm.experimental.noalias.scope.decl(metadata !id.scope.list)
Overview:¶
The llvm.experimental.noalias.scope.decl
intrinsic identifies where a noalias scope is declared. When the intrinsic is duplicated, a decision must also be made about the scope: depending on the reason of the duplication, the scope might need to be duplicated as well.
Arguments:¶
The !id.scope.list
argument is metadata that is a list of noalias
metadata references. The format is identical to that required for noalias
metadata. This list must have exactly one element.
Semantics:¶
The llvm.experimental.noalias.scope.decl
intrinsic identifies where a
noalias scope is declared. When the intrinsic is duplicated, a decision must also be made about the scope: depending on the reason of the duplication, the scope might need to be duplicated as well.
For example, when the intrinsic is used inside a loop body, and that loop is unrolled, the associated noalias scope must also be duplicated. Otherwise, the noalias property it signifies would spill across loop iterations, whereas it was only valid within a single iteration.
; This examples shows two possible positions for noalias.decl and how they impact the semantics: ; If it is outside the loop (Version 1), then %a and %b are noalias across *all* iterations. ; If it is inside the loop (Version 2), then %a and %b are noalias only within *one* iteration. declare void @decl_in_loop(ptr %a.base, ptr %b.base) { entry: ; call void @llvm.experimental.noalias.scope.decl(metadata !2) ; Version 1: noalias decl outside loop br label %loop loop: %a = phi ptr [ %a.base, %entry ], [ %a.inc, %loop ] %b = phi ptr [ %b.base, %entry ], [ %b.inc, %loop ] ; call void @llvm.experimental.noalias.scope.decl(metadata !2) ; Version 2: noalias decl inside loop %val = load i8, ptr %a, !alias.scope !2 store i8 %val, ptr %b, !noalias !2 %a.inc = getelementptr inbounds i8, ptr %a, i64 1 %b.inc = getelementptr inbounds i8, ptr %b, i64 1 %cond = call i1 @cond() br i1 %cond, label %loop, label %exit exit: ret void } !0 = !{!0} ; domain !1 = !{!1, !0} ; scope !2 = !{!1} ; scope list
Multiple calls to @llvm.experimental.noalias.scope.decl for the same scope are possible, but one should never dominate another. Violations are pointed out by the verifier as they indicate a problem in either a transformation pass or the input.
Floating Point Environment Manipulation intrinsics¶
These functions read or write floating point environment, such as rounding mode or state of floating point exceptions. Altering the floating point environment requires special care. See Floating Point Environment.
‘llvm.flt.rounds
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.flt.rounds()
Overview:¶
The ‘llvm.flt.rounds
’ intrinsic reads the current rounding mode.
Semantics:¶
The ‘llvm.flt.rounds
’ intrinsic returns the current rounding mode. Encoding of the returned values is same as the result of FLT_ROUNDS
, specified by C standard:
0 - toward zero 1 - to nearest, ties to even 2 - toward positive infinity 3 - toward negative infinity 4 - to nearest, ties away from zero
Other values may be used to represent additional rounding modes, supported by a target. These values are target-specific.
‘llvm.set.rounding
’ Intrinsic¶
Syntax:¶
declare void @llvm.set.rounding(i32 <val>)
Overview:¶
The ‘llvm.set.rounding
’ intrinsic sets current rounding mode.
Arguments:¶
The
argument is the required rounding mode. Encoding of rounding mode is the same as used by ‘llvm.flt.rounds
’.
Semantics:¶
The ‘llvm.set.rounding
’ intrinsic sets the current rounding mode. It is similar to C library function ‘fesetround’, however this intrinsic does not return any value and uses platform-independent representation of IEEE rounding modes.
Floating-Point Test Intrinsics¶
These functions get properties of floating-point values.
‘llvm.is.fpclass
’
Intrinsic¶
Syntax:¶
declare i1 @llvm.is.fpclass(<fptype> <op>, i32 <test>) declare <N x i1> @llvm.is.fpclass(<vector-fptype> <op>, i32 <test>)
Overview:¶
The ‘llvm.is.fpclass
’ intrinsic returns a boolean
value or vector of boolean values depending on whether the first argument satisfies the test specified by the second argument.
If the first argument is a floating-point scalar, then the result type is a boolean (i1).
If the first argument is a floating-point vector, then the result type is a vector of boolean with the same number of elements as the first argument.
Arguments:¶
The first argument to the ‘llvm.is.fpclass
’ intrinsic must be floating-point or vector of floating-point values.
The second argument specifies, which tests to perform. It must be a compile-time integer constant, each bit in which specifies floating-point class:
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 |
Semantics:¶
The function checks if op
belongs to any of the floating-point classes specified by test
. If op
is a vector, then the check is made element by element. Each check yields an i1 result, which is true
, if the element
value satisfies the specified test. The argument test
is a bit mask where each bit specifies floating-point class to test. For example, the value 0x108 makes test for normal value, - bits 3 and 8 in it are set, which means that the function returns true
if op
is a positive or negative normal value. The function never raises floating-point exceptions.
General Intrinsics¶
This class of intrinsics is designed to be generic and has no specific purpose.
‘llvm.var.annotation
’ Intrinsic¶
Syntax:¶
declare void @llvm.var.annotation(ptr <val>, ptr <str>, ptr <str>, i32 <int>)
Overview:¶
The ‘llvm.var.annotation
’ intrinsic.
Arguments:¶
The first argument is a pointer to a value, the second is a pointer to a global string, the third is a pointer to a global string which is the source file name, and the last argument is the line number.
Semantics:¶
This intrinsic allows annotation of local variables with arbitrary strings. This can be useful for special purpose optimizations that want to look for these annotations. These have no other defined use; they are ignored by code generation and optimization.
‘llvm.ptr.annotation.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use ‘llvm.ptr.annotation
’ on a pointer to an integer of any width. NOTE you must specify an address space for the pointer. The identifier for the default address space is the integer ‘0
’.
declare ptr @llvm.ptr.annotation.p0(ptr <val>, ptr <str>, ptr <str>, i32 <int>) declare ptr @llvm.ptr.annotation.p1(ptr addrspace(1) <val>, ptr <str>, ptr <str>, i32 <int>)
Overview:¶
The ‘llvm.ptr.annotation
’ intrinsic.
Arguments:¶
The first argument is a pointer to an integer value of arbitrary bitwidth (result of some expression), the second is a pointer to a global string, the third is a pointer to a global string which is the source file name, and the last argument is the line number. It returns the value of the first argument.
Semantics:¶
This intrinsic allows annotation of a pointer to an integer with arbitrary strings. This can be useful for special purpose optimizations that want to look for these annotations. These have no other defined use; transformations preserve annotations on a best-effort basis but are allowed to replace the intrinsic with its first argument without breaking semantics and the intrinsic is completely dropped during instruction selection.
‘llvm.annotation.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use ‘llvm.annotation
’ on any integer bit width.
declare i8 @llvm.annotation.i8(i8 <val>, ptr <str>, ptr <str>, i32 <int>) declare i16 @llvm.annotation.i16(i16 <val>, ptr <str>, ptr <str>, i32 <int>) declare i32 @llvm.annotation.i32(i32 <val>, ptr <str>, ptr <str>, i32 <int>) declare i64 @llvm.annotation.i64(i64 <val>, ptr <str>, ptr <str>, i32 <int>) declare i256 @llvm.annotation.i256(i256 <val>, ptr <str>, ptr <str>, i32 <int>)
Overview:¶
The ‘llvm.annotation
’ intrinsic.
Arguments:¶
The first argument is an integer value (result of some expression), the second is a pointer to a global string, the third is a pointer to a global string which is the source file name, and the last argument is the line number. It returns the value of the first argument.
Semantics:¶
This intrinsic allows annotations to be put on arbitrary expressions with arbitrary strings. This can be useful for special purpose optimizations that want to look for these annotations. These have no other defined use; transformations preserve annotations on a best-effort basis but are allowed to replace the intrinsic with its first argument without breaking semantics and the intrinsic is completely dropped during instruction selection.
‘llvm.codeview.annotation
’ Intrinsic¶
Syntax:¶
This annotation emits a label at its program point and an associated S_ANNOTATION
codeview record with some additional string metadata. This is used to implement MSVC’s __annotation
intrinsic. It is marked noduplicate
, so calls to this intrinsic prevent inlining and should be considered expensive.
declare void @llvm.codeview.annotation(metadata)
Arguments:¶
The argument should be an MDTuple containing any number of MDStrings.
‘llvm.trap
’ Intrinsic¶
Syntax:¶
declare void @llvm.trap() cold noreturn nounwind
Overview:¶
The ‘llvm.trap
’ intrinsic.
Semantics:¶
This intrinsic is lowered to the target dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to a call of the abort()
function.
‘llvm.debugtrap
’ Intrinsic¶
Syntax:¶
declare void @llvm.debugtrap() nounwind
Overview:¶
The ‘llvm.debugtrap
’ intrinsic.
Semantics:¶
This intrinsic is lowered to code which is intended to cause an execution trap with the intention of requesting the attention of a debugger.
‘llvm.ubsantrap
’ Intrinsic¶
Syntax:¶
declare void @llvm.ubsantrap(i8 immarg) cold noreturn nounwind
Overview:¶
The ‘llvm.ubsantrap
’ intrinsic.
Arguments:¶
An integer describing the kind of failure detected.
Semantics:¶
This intrinsic is lowered to code which is intended to cause an execution trap, embedding the argument into encoding of that trap somehow to discriminate crashes if possible.
Equivalent to @llvm.trap
for targets that do not support this behaviour.
‘llvm.stackprotector
’ Intrinsic¶
Syntax:¶
declare void @llvm.stackprotector(ptr <guard>, ptr <slot>)
Overview:¶
The llvm.stackprotector
intrinsic takes the guard
and stores it onto the stack at slot
. The stack slot is adjusted to ensure that it is placed on the stack before local variables.
Arguments:¶
The llvm.stackprotector
intrinsic requires two pointer arguments. The first argument is the value loaded from the stack guard @__stack_chk_guard
. The second variable is an alloca
that has enough space to hold the value of the guard.
Semantics:¶
This intrinsic
causes the prologue/epilogue inserter to force the position of the AllocaInst
stack slot to be before local variables on the stack. This is to ensure that if a local variable on the stack is overwritten, it will destroy the value of the guard. When the function exits, the guard on the stack is checked against the original guard by llvm.stackprotectorcheck
. If they are different, then llvm.stackprotectorcheck
causes the program to abort by calling the __stack_chk_fail()
function.
‘llvm.stackguard
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.stackguard()
Overview:¶
The llvm.stackguard
intrinsic returns the system stack guard value.
It should not be generated by frontends, since it is only for internal usage. The reason why we create this intrinsic is that we still support IR form Stack Protector in FastISel.
Semantics:¶
On some platforms, the value returned by this intrinsic remains unchanged between loads in the same thread. On other platforms, it returns the same global variable value, if any, e.g. @__stack_chk_guard
.
Currently some platforms have IR-level customized stack guard loading (e.g. X86 Linux) that is not handled by llvm.stackguard()
, while they should be in the future.
‘llvm.objectsize
’ Intrinsic¶
Syntax:¶
declare i32 @llvm.objectsize.i32(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>) declare i64 @llvm.objectsize.i64(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
Overview:¶
The llvm.objectsize
intrinsic 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.
Arguments:¶
The llvm.objectsize
intrinsic takes four arguments. The first argument is a pointer to or into the object
. The second argument determines whether llvm.objectsize
returns 0 (if true) or -1 (if false) when the object size is unknown. The third argument controls how llvm.objectsize
acts when null
in address space 0 is used as its pointer argument. If it’s false
, llvm.objectsize
reports 0 bytes available
when given null
. Otherwise, if the null
is in a non-zero address space or if true
is given for the third argument of llvm.objectsize
, we assume its size is unknown. The fourth argument to llvm.objectsize
determines if the value should be evaluated at runtime.
The second, third, and fourth arguments only accept constants.
Semantics:¶
The llvm.objectsize
intrinsic is lowered to a value representing the size of the object concerned. If the size cannot be determined, llvm.objectsize
returns i32/i64 -1 or 0
(depending on the min
argument).
‘llvm.expect
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.expect
on any integer bit width.
declare i1 @llvm.expect.i1(i1 <val>, i1 <expected_val>) declare i32 @llvm.expect.i32(i32 <val>, i32 <expected_val>) declare i64 @llvm.expect.i64(i64 <val>, i64 <expected_val>)
Overview:¶
The llvm.expect
intrinsic provides information about expected (the most probable) value of val
, which can be used by optimizers.
Arguments:¶
The llvm.expect
intrinsic takes two arguments. The first argument is a value. The second argument is an expected value.
Semantics:¶
This intrinsic is lowered to the val
.
‘llvm.expect.with.probability
’ Intrinsic¶
Syntax:¶
This intrinsic is similar to llvm.expect
. This is an overloaded intrinsic.
You can use llvm.expect.with.probability
on any integer bit width.
declare i1 @llvm.expect.with.probability.i1(i1 <val>, i1 <expected_val>, double <prob>) declare i32 @llvm.expect.with.probability.i32(i32 <val>, i32 <expected_val>, double <prob>) declare i64 @llvm.expect.with.probability.i64(i64 <val>, i64 <expected_val>, double <prob>)
Overview:¶
The llvm.expect.with.probability
intrinsic provides information about expected value of val
with probability(or confidence) prob
, which can be used by optimizers.
Arguments:¶
The llvm.expect.with.probability
intrinsic takes three arguments. The first argument is a value. The second argument is an expected value. The third argument is a probability.
Semantics:¶
This intrinsic is lowered to the val
.
‘llvm.assume
’ Intrinsic¶
Syntax:¶
declare void @llvm.assume(i1 %cond)
Overview:¶
The llvm.assume
allows the optimizer to assume that the provided condition is true. This information can then be used in simplifying other parts of the code.
More complex assumptions can be encoded as assume operand bundles.
Arguments:¶
The argument of the call is the condition which the optimizer may assume is always true.
Semantics:¶
The intrinsic allows the optimizer to assume that the provided condition is always true whenever the control flow reaches the intrinsic call. No code is generated for this intrinsic, and instructions that contribute only to the provided condition are not used for code generation. If the condition is violated during execution, the behavior is undefined.
Note that the optimizer might limit the transformations performed on values used by the llvm.assume
intrinsic in order to preserve the instructions only used to form the intrinsic’s input argument. This might prove undesirable if the extra information provided by the llvm.assume
intrinsic does not cause sufficient overall improvement in code quality. For this reason, llvm.assume
should not be
used to document basic mathematical invariants that the optimizer can otherwise deduce or facts that are of little use to the optimizer.
‘llvm.ssa.copy
’ Intrinsic¶
Syntax:¶
declare type @llvm.ssa.copy(type %operand) returned(1) readnone
Arguments:¶
The first argument is an operand which is used as the returned value.
Overview:¶
The llvm.ssa.copy
intrinsic can be used to attach information to operations by copying them and giving them new names. For example, the PredicateInfo utility uses it to build Extended SSA form, and attach various forms of information to operands that dominate specific uses. It is not meant for general use, only for building temporary renaming forms that require value splits at certain points.
‘llvm.type.test
’ Intrinsic¶
Syntax:¶
declare i1 @llvm.type.test(ptr %ptr, metadata %type) nounwind readnone
Arguments:¶
The first argument is a pointer to be tested. The second argument is a metadata object representing a type identifier.
Overview:¶
The llvm.type.test
intrinsic tests
whether the given pointer is associated with the given type identifier.
‘llvm.type.checked.load
’ Intrinsic¶
Syntax:¶
declare {ptr, i1} @llvm.type.checked.load(ptr %ptr, i32 %offset, metadata %type) argmemonly nounwind readonly
Arguments:¶
The first argument is a pointer from which to load a function pointer. The second argument is the byte offset from which to load the function pointer. The third argument is a metadata object representing a type identifier.
Overview:¶
The llvm.type.checked.load
intrinsic safely loads a function pointer from a virtual table pointer using type metadata. This intrinsic is used to implement control flow integrity in conjunction with virtual call optimization. The virtual call optimization pass
will optimize away llvm.type.checked.load
intrinsics associated with devirtualized calls, thereby removing the type check in cases where it is not needed to enforce the control flow integrity constraint.
If the given pointer is associated with a type metadata identifier, this function returns true as the second element of its return value. (Note that the function may also return true if the given pointer is not associated with a type metadata identifier.) If the function’s return value’s second element is true, the following rules apply to the first element:
- If the given pointer is associated with the given type metadata identifier, it is the function pointer loaded from the given byte offset from the given pointer.
- If the given pointer is not associated with the given type metadata identifier, it is one of the following (the choice of which is unspecified):
- The function pointer that would have been loaded from an arbitrarily chosen (through an unspecified mechanism) pointer associated with the type metadata.
- If the function has a non-void return type, a pointer to a function that returns an unspecified value without causing side effects.
If the function’s return value’s second element is false, the value of the first element is undefined.
‘llvm.arithmetic.fence
’
Intrinsic¶
Syntax:¶
declare <type> @llvm.arithmetic.fence(<type> <op>)
Overview:¶
The purpose of the llvm.arithmetic.fence
intrinsic
is to prevent the optimizer from performing fast-math optimizations, particularly reassociation, between the argument and the expression that contains the argument. It can be used to preserve the parentheses in the source language.
Arguments:¶
The llvm.arithmetic.fence
intrinsic takes only one argument. The argument and the return value are floating-point numbers, or
vector floating-point numbers, of the same type.
Semantics:¶
This intrinsic returns the value of its operand. The optimizer can optimize the argument, but the optimizer cannot hoist any component of the operand to the containing context, and the optimizer cannot move the calculation of any expression in the containing context into the operand.
‘llvm.donothing
’ Intrinsic¶
Syntax:¶
declare void @llvm.donothing() nounwind readnone
Overview:¶
The llvm.donothing
intrinsic doesn’t perform any operation. It’s one of only three intrinsics (besides llvm.experimental.patchpoint
and llvm.experimental.gc.statepoint
) that can be called with an invoke instruction.
Semantics:¶
This intrinsic does nothing, and it’s removed by optimizers and ignored by codegen.
‘llvm.experimental.deoptimize
’ Intrinsic¶
Syntax:¶
declare type @llvm.experimental.deoptimize(...) [ "deopt"(...) ]
Overview:¶
This intrinsic, together with deoptimization operand bundles, allow frontends to express transfer of control and frame-local state from the currently executing (typically more specialized, hence faster) version of a function into another (typically more generic, hence slower) version.
In languages with a fully integrated managed runtime like Java and JavaScript this intrinsic can be used to implement “uncommon trap” or “side exit” like functionality. In unmanaged languages like C and C++, this intrinsic can be used to represent the slow paths of specialized functions.
Arguments:¶
The intrinsic takes an arbitrary number of arguments, whose meaning is decided by the lowering strategy.
Semantics:¶
The @llvm.experimental.deoptimize
intrinsic executes an attached deoptimization continuation (denoted using a
deoptimization operand bundle) and returns the value returned by the deoptimization continuation. Defining the semantic properties of the continuation itself is out of scope of the language reference – as far as LLVM is concerned, the deoptimization continuation can invoke arbitrary side effects, including reading from and writing to the entire heap.
Deoptimization continuations expressed using
"deopt"
operand bundles always continue execution to the end of the physical frame containing them, so all calls to @llvm.experimental.deoptimize
must be in “tail position”:
@llvm.experimental.deoptimize
cannot be invoked.- The call must immediately precede a ret instruction.
- The
ret
instruction must return the value produced by the@llvm.experimental.deoptimize
call if there is one, or void.
Note that the above restrictions imply that the return type for a call to @llvm.experimental.deoptimize
will match the return type of its immediate caller.
The inliner composes the "deopt"
continuations of the caller into the "deopt"
continuations present in the inlinee, and also updates calls to this intrinsic to return directly from the frame of the function it inlined into.
All declarations of @llvm.experimental.deoptimize
must share the same calling convention.
Lowering:¶
Calls to @llvm.experimental.deoptimize
are lowered to calls to the symbol __llvm_deoptimize
(it is the frontend’s responsibility to ensure that this symbol is defined). The call arguments to @llvm.experimental.deoptimize
are lowered as if they were formal arguments of the specified types, and not as varargs.
‘llvm.experimental.guard
’ Intrinsic¶
Syntax:¶
declare void @llvm.experimental.guard(i1, ...) [ "deopt"(...) ]
Overview:¶
This intrinsic, together with deoptimization operand bundles, allows frontends to express guards or checks on optimistic assumptions made during compilation. The semantics of @llvm.experimental.guard
is defined in terms of @llvm.experimental.deoptimize
– its body is defined to be equivalent to:
define void @llvm.experimental.guard(i1 %pred, <args...>) { %realPred = and i1 %pred, undef br i1 %realPred, label %continue, label %leave [, !make.implicit !{}] leave: call void @llvm.experimental.deoptimize(<args...>) [ "deopt"() ] ret void continue: ret void }
with the
optional [, !make.implicit !{}]
present if and only if it is present on the call site. For more details on !make.implicit
, see FaultMaps and implicit checks.
In words, @llvm.experimental.guard
executes the attached "deopt"
continuation if (but not only if) its first argument is false
. Since the optimizer is allowed to replace the undef
with an arbitrary value, it can optimize guard to fail “spuriously”, i.e. without the
original condition being false (hence the “not only if”); and this allows for “check widening” type optimizations.
@llvm.experimental.guard
cannot be invoked.
After @llvm.experimental.guard
was first added, a more general formulation was found in @llvm.experimental.widenable.condition
. Support for @llvm.experimental.guard
is slowly being rephrased in terms of this alternate.
‘llvm.experimental.widenable.condition
’ Intrinsic¶
Syntax:¶
declare i1 @llvm.experimental.widenable.condition()
Overview:¶
This intrinsic represents a “widenable condition” which is boolean expressions with the following property: whether this expression is true or false, the program is correct and well-defined.
Together with deoptimization operand bundles, @llvm.experimental.widenable.condition
allows frontends to express guards or checks on optimistic assumptions made during compilation and represent them as branch instructions on special conditions.
While this may appear similar in semantics to undef, it is very different in that an invocation produces a particular, singular value. It is also intended to be lowered late, and remain available for specific optimizations and transforms that can benefit from its special properties.
Semantics:¶
The intrinsic @llvm.experimental.widenable.condition()
returns either true or
false. For each evaluation of a call to this intrinsic, the program must be valid and correct both if it returns true and if it returns false. This allows transformation passes to replace evaluations of this intrinsic with either value whenever one is beneficial.
When used in a branch condition, it allows us to choose between two alternative correct solutions for the same problem, like in example below:
%cond = call i1 @llvm.experimental.widenable.condition() br i1 %cond, label %solution_1, label %solution_2 label %fast_path: ; Apply memory-consuming but fast solution for a task. label %slow_path: ; Cheap in memory but slow solution.
Whether the result of
intrinsic’s call is true or false, it should be correct to pick either solution. We can switch between them by replacing the result of @llvm.experimental.widenable.condition
with different i1 expressions.
This is how it can be used to represent guards as widenable branches:
block: ; Unguarded instructions call void @llvm.experimental.guard(i1 %cond, <args...>) ["deopt"(<deopt_args...>)] ; Guarded instructions
Can be expressed in an alternative equivalent form of explicit branch using @llvm.experimental.widenable.condition
:
block: ; Unguarded instructions %widenable_condition = call i1 @llvm.experimental.widenable.condition() %guard_condition = and i1 %cond, %widenable_condition br i1 %guard_condition, label %guarded, label %deopt guarded: ; Guarded instructions deopt: call type @llvm.experimental.deoptimize(<args...>) [ "deopt"(<deopt_args...>) ]
So the block guarded is only reachable when %cond is true, and it should be valid to go to the block deopt whenever %cond is true or false.
@llvm.experimental.widenable.condition
will never throw, thus it cannot be invoked.
Guard widening:¶
When @llvm.experimental.widenable.condition()
is used in condition of a guard represented as explicit branch, it is legal to widen the
guard’s condition with any additional conditions.
Guard widening looks like replacement of
%widenable_cond = call i1 @llvm.experimental.widenable.condition() %guard_cond = and i1 %cond, %widenable_cond br i1 %guard_cond, label %guarded, label %deopt
with
%widenable_cond = call i1 @llvm.experimental.widenable.condition() %new_cond = and i1 %any_other_cond, %widenable_cond %new_guard_cond = and i1 %cond, %new_cond br i1 %new_guard_cond, label %guarded, label %deopt
for this branch. Here %any_other_cond is an arbitrarily chosen well-defined i1 value. By making guard widening, we may impose stricter conditions on guarded block and bail to the deopt when the new condition is not met.
Lowering:¶
Default lowering strategy is replacing the result of call of @llvm.experimental.widenable.condition
with constant true. However it is always correct to replace it with any other i1 value. Any pass can freely do it if it can benefit from non-default lowering.
‘llvm.load.relative
’ Intrinsic¶
Syntax:¶
declare ptr @llvm.load.relative.iN(ptr %ptr, iN %offset) argmemonly nounwind readonly
Overview:¶
This intrinsic loads a 32-bit value from the address %ptr + %offset
, adds %ptr
to that value and returns it. The constant folder specifically recognizes the form of this intrinsic and the constant initializers it may load from; if a loaded constant initializer is known to have the form i32 trunc(x - %ptr)
, the intrinsic call is folded to x
.
LLVM provides that the calculation of such a
constant initializer will not overflow at link time under the medium code model if x
is an unnamed_addr
function. However, it does not provide this guarantee for a constant initializer folded into a function body. This intrinsic can be used to avoid the possibility of overflows when loading from such a constant.
‘llvm.sideeffect
’
Intrinsic¶
Syntax:¶
declare void @llvm.sideeffect() inaccessiblememonly nounwind willreturn
Overview:¶
The llvm.sideeffect
intrinsic doesn’t perform any
operation. Optimizers treat it as having side effects, so it can be inserted into a loop to indicate that the loop shouldn’t be assumed to terminate (which could potentially lead to the loop being optimized away entirely), even if it’s an infinite loop with no other side effects.
Semantics:¶
This intrinsic actually does nothing, but optimizers must assume that it has externally observable side effects.
‘llvm.is.constant.*
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.is.constant with any argument type.
declare i1 @llvm.is.constant.i32(i32 %operand) nounwind readnone declare i1 @llvm.is.constant.f32(float %operand) nounwind readnone declare i1 @llvm.is.constant.TYPENAME(TYPE %operand) nounwind readnone
Overview:¶
The ‘llvm.is.constant
’ intrinsic will return true if the argument is known to be a manifest compile-time constant. It is guaranteed to fold to either true or false before generating machine code.
Semantics:¶
This intrinsic generates no code. If its argument is known to be a manifest compile-time constant value, then the intrinsic will be converted to a constant true value. Otherwise, it will be converted to a constant false value.
In particular, note that 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.
The result also intentionally depends on the result of optimization passes – e.g., the result can change depending on whether a function gets inlined or not. A function’s parameters are obviously not constant. However, a call like llvm.is.constant.i32(i32 %param)
can return true after the function is inlined, if the value passed to the function parameter was a constant.
On the other hand, if constant folding is not run, it will never evaluate to true, even in simple cases.
‘llvm.ptrmask
’ Intrinsic¶
Syntax:¶
declare ptrty llvm.ptrmask(ptrty %ptr, intty %mask) readnone speculatable
Arguments:¶
The first argument is a pointer. The second argument is an integer.
Overview:¶
The llvm.ptrmask
intrinsic masks out bits of the pointer according to a mask. This allows stripping data from tagged pointers without converting them to an integer
(ptrtoint/inttoptr). As a consequence, we can preserve more information to facilitate alias analysis and underlying-object detection.
Semantics:¶
The result of ptrmask(ptr, mask)
is equivalent to getelementptr ptr, (ptrtoint(ptr) & mask) - ptrtoint(ptr)
. Both the returned pointer and the first argument are based on the same underlying object (for more information on the based on terminology see
the pointer aliasing rules). If the bitwidth of the mask argument does not match the pointer size of the target, the mask is zero-extended or truncated accordingly.
‘llvm.threadlocal.address
’
Intrinsic¶
Syntax:¶
declare ptr @llvm.threadlocal.address(ptr) nounwind readnone willreturn
Arguments:¶
The first argument is a pointer, which refers to a thread local global.
Semantics:¶
The address of a thread local global is not a constant, since it depends on the calling thread. The llvm.threadlocal.address intrinsic returns the address of the given thread local global in the calling thread.
‘llvm.vscale
’ Intrinsic¶
Syntax:¶
declare i32 llvm.vscale.i32() declare i64 llvm.vscale.i64()
Overview:¶
The llvm.vscale
intrinsic returns the value for vscale
in scalable vectors such as <vscale x 16 x i8>
.
Semantics:¶
vscale
is a positive value that is constant throughout program execution, but is unknown at compile time. If the result value does not fit in the result type, then the result is a
poison value.
Element Wise Atomic Memory Intrinsics¶
These intrinsics are similar to the standard library memory intrinsics except that they perform memory transfer as a sequence of atomic memory accesses.
‘llvm.memcpy.element.unordered.atomic
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memcpy.element.unordered.atomic
on any integer bit width and for different address spaces. Not all targets support all bit widths however.
declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i32(ptr <dest>, ptr <src>, i32 <len>, i32 <element_size>) declare void @llvm.memcpy.element.unordered.atomic.p0.p0.i64(ptr <dest>, ptr <src>, i64 <len>, i32 <element_size>)
Overview:¶
The ‘llvm.memcpy.element.unordered.atomic.*
’ intrinsic is a specialization of the
‘llvm.memcpy.*
’
intrinsic. It differs in that the dest
and src
are treated as arrays with elements that are exactly element_size
bytes, and the copy between buffers uses a sequence of unordered atomic load/store operations that are a positive integer multiple of the element_size
in size.
Arguments:¶
The first three arguments are the same as they are in the @llvm.memcpy intrinsic, with the added constraint that len
is required to be a positive integer multiple of the element_size
. If len
is not a positive integer multiple of element_size
, then the behaviour of the intrinsic is undefined.
element_size
must be a compile-time constant positive power of two no greater than target-specific atomic access size limit.
For each of the input pointers align
parameter attribute must be specified. It must be a power of two no less than the element_size
. Caller guarantees that both the source and destination pointers are aligned to that boundary.
Semantics:¶
The ‘llvm.memcpy.element.unordered.atomic.*
’ intrinsic copies len
bytes of memory from the source location to the destination location. These locations are not allowed to overlap. The memory copy is performed as a sequence of load/store operations where each access is guaranteed to be a multiple of element_size
bytes wide and aligned at an element_size
boundary.
The order of the copy is unspecified. The same value may be read from the source buffer many times, but only one write is issued to the destination buffer per element. It is well defined to have concurrent reads and writes to both source and destination provided those reads and writes are unordered atomic when specified.
This intrinsic does not provide any additional ordering guarantees over those provided by a set of unordered loads from the source location and stores to the destination.
Lowering:¶
In the most general case call to the ‘llvm.memcpy.element.unordered.atomic.*
’ is lowered to a call to the symbol __llvm_memcpy_element_unordered_atomic_*
. Where ‘*’ is replaced with an actual element size. See RewriteStatepointsForGC intrinsic lowering for details on GC specific lowering.
Optimizer is allowed to inline memory copy when it’s profitable to do so.
‘llvm.memmove.element.unordered.atomic
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memmove.element.unordered.atomic
on any integer bit width and for different address spaces. Not all targets support all bit widths however.
declare void @llvm.memmove.element.unordered.atomic.p0.p0.i32(ptr <dest>, ptr <src>, i32 <len>, i32 <element_size>) declare void @llvm.memmove.element.unordered.atomic.p0.p0.i64(ptr <dest>, ptr <src>, i64 <len>, i32 <element_size>)
Overview:¶
The ‘llvm.memmove.element.unordered.atomic.*
’ intrinsic is a specialization of the ‘llvm.memmove.*
’
intrinsic. It differs in that the dest
and src
are treated as arrays with elements that are exactly element_size
bytes, and the copy between buffers uses a sequence of unordered atomic load/store operations that are a positive integer multiple of the element_size
in size.
Arguments:¶
The first three arguments are the same as they are in the @llvm.memmove intrinsic, with the added constraint that len
is required to be a positive integer multiple of the element_size
. If len
is not a positive integer multiple of element_size
, then the behaviour of the intrinsic is undefined.
element_size
must be a compile-time constant positive power of two no greater than a target-specific atomic access size limit.
For each of the input pointers the align
parameter attribute must be specified. It must be a power of two no less than the element_size
. Caller guarantees that both the source and destination pointers are aligned to that boundary.
Semantics:¶
The ‘llvm.memmove.element.unordered.atomic.*
’ intrinsic copies len
bytes of memory from the source location to the destination location. These locations are allowed to overlap. The memory copy is performed as a sequence of load/store operations where each access is guaranteed to be a multiple of element_size
bytes wide and aligned at an element_size
boundary.
The order of the copy is unspecified. The same value may be read from the source buffer many times, but only one write is issued to the destination buffer per element. It is well defined to have concurrent reads and writes to both source and destination provided those reads and writes are unordered atomic when specified.
This intrinsic does not provide any additional ordering guarantees over those provided by a set of unordered loads from the source location and stores to the destination.
Lowering:¶
In the most general case call to the ‘llvm.memmove.element.unordered.atomic.*
’ is lowered to a call to the symbol __llvm_memmove_element_unordered_atomic_*
. Where ‘*’ is replaced with an actual element size. See RewriteStatepointsForGC intrinsic lowering for details on GC specific lowering.
The optimizer is allowed to inline the memory copy when it’s profitable to do so.
‘llvm.memset.element.unordered.atomic
’ Intrinsic¶
Syntax:¶
This is an overloaded intrinsic. You can use llvm.memset.element.unordered.atomic
on any integer bit width and for different address spaces. Not all targets support all bit widths however.
declare void @llvm.memset.element.unordered.atomic.p0.i32(ptr <dest>, i8 <value>, i32 <len>, i32 <element_size>) declare void @llvm.memset.element.unordered.atomic.p0.i64(ptr <dest>, i8 <value>, i64 <len>, i32 <element_size>)
Overview:¶
The ‘llvm.memset.element.unordered.atomic.*
’ intrinsic is a specialization of the
‘llvm.memset.*
’
intrinsic. It differs in that the dest
is treated as an array with elements that are exactly element_size
bytes, and the assignment to that array uses uses a sequence of unordered atomic store operations that are a positive integer multiple of the element_size
in size.
Arguments:¶
The first three arguments are the same as they are in the @llvm.memset intrinsic, with the added constraint that len
is required to be a positive integer multiple of the element_size
. If len
is not a positive integer multiple of element_size
, then the behaviour of the intrinsic is undefined.
element_size
must be a compile-time constant positive power of two no greater than target-specific atomic access size limit.
The dest
input pointer must have the align
parameter attribute specified. It must be a power of two no less than the element_size
. Caller guarantees that the destination pointer is aligned to that boundary.
Semantics:¶
The
‘llvm.memset.element.unordered.atomic.*
’ intrinsic sets the len
bytes of memory starting at the destination location to the given value
. The memory is set with a sequence of store operations where each access is guaranteed to be a multiple of element_size
bytes wide and aligned at an element_size
boundary.
The order of the assignment is unspecified. Only one write is issued to the destination buffer per element. It is well defined to have concurrent reads and writes to the destination provided those reads and writes are unordered atomic when specified.
This intrinsic does not provide any additional ordering guarantees over those provided by a set of unordered stores to the destination.
Lowering:¶
In the most general case call to the ‘llvm.memset.element.unordered.atomic.*
’ is lowered to a call to the symbol __llvm_memset_element_unordered_atomic_*
. Where ‘*’ is replaced with an actual element size.
The optimizer is allowed to inline the memory assignment when it’s profitable to do so.
Objective-C ARC Runtime Intrinsics¶
LLVM provides intrinsics that lower to Objective-C ARC runtime entry points. LLVM is aware of the semantics of these functions, and optimizes based on that knowledge. You can read more about the details of Objective-C ARC here.
Preserving Debug Information Intrinsics¶
These intrinsics are used to carry certain debuginfo together with IR-level operations. For example, it may be desirable to know the structure/union name and the original user-level field indices. Such information got lost in IR GetElementPtr instruction since the IR types are different from debugInfo types and unions are converted to structs in IR.
‘llvm.preserve.array.access.index
’ Intrinsic¶
Syntax:¶
declare <ret_type> @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(<type> base, i32 dim, i32 index)
Overview:¶
The ‘llvm.preserve.array.access.index
’ intrinsic returns the getelementptr address based on array base base
, array dimension dim
and the last access index index
into the array. The return type ret_type
is a pointer type to the array element. The array dim
and index
are preserved which is more robust than getelementptr instruction which may be subject to compiler transformation. The
llvm.preserve.access.index
type of metadata is attached to this call instruction to provide array or pointer debuginfo type. The metadata is a DICompositeType
or DIDerivedType
representing the debuginfo version of type
.
Arguments:¶
The base
is the array base address. The dim
is the array dimension. The base
is a pointer if
dim
equals 0. The index
is the last access index into the array or pointer.
The base
argument must be annotated with an elementtype attribute at the call-site. This attribute specifies the getelementptr element type.
Semantics:¶
The ‘llvm.preserve.array.access.index
’
intrinsic produces the same result as a getelementptr with base base
and access operands {dim's 0's, index}
.
‘llvm.preserve.union.access.index
’ Intrinsic¶
Syntax:¶
declare <type> @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(<type> base, i32 di_index)
Overview:¶
The ‘llvm.preserve.union.access.index
’ intrinsic carries the debuginfo field index di_index
and returns the base
address. The llvm.preserve.access.index
type of metadata is attached to this call instruction to provide union debuginfo type. The metadata is a
DICompositeType
representing the debuginfo version of type
. The return type type
is the same as the base
type.
Arguments:¶
The base
is the union base address. The di_index
is the field index in debuginfo.
Semantics:¶
The ‘llvm.preserve.union.access.index
’ intrinsic returns the base
address.
‘llvm.preserve.struct.access.index
’ Intrinsic¶
Syntax:¶
declare <ret_type> @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(<type> base, i32 gep_index, i32 di_index)
Overview:¶
The ‘llvm.preserve.struct.access.index
’ intrinsic returns the getelementptr address based on struct base base
and IR struct member index gep_index
. The llvm.preserve.access.index
type of metadata is attached to this call instruction to provide
struct debuginfo type. The metadata is a DICompositeType
representing the debuginfo version of type
. The return type ret_type
is a pointer type to the structure member.
Arguments:¶
The base
is the structure base address. The gep_index
is the struct member index based on IR structures. The di_index
is the struct member index based on debuginfo.
The
base
argument must be annotated with an elementtype attribute at the call-site. This attribute specifies the getelementptr element type.
Semantics:¶
The ‘llvm.preserve.struct.access.index
’ intrinsic produces the same result as a getelementptr with base base
and access operands
{0, gep_index}
.
‘llvm.fptrunc.round
’ Intrinsic¶
Syntax:¶
declare <ty2> @llvm.fptrunc.round(<type> <value>, metadata <rounding mode>)
Overview:¶
The ‘llvm.fptrunc.round
’ intrinsic truncates floating-point value
to type ty2
with a specified rounding mode.
Arguments:¶
The ‘llvm.fptrunc.round
’ intrinsic takes a
floating-point value to cast and a floating-point type to cast it to. This argument must be larger in size than the result.
The second argument specifies the rounding mode as described in the constrained intrinsics section. For this intrinsic, the “round.dynamic” mode is not supported.
Semantics:¶
The ‘llvm.fptrunc.round
’ intrinsic casts a value
from a larger floating-point type to a smaller floating-point type. This intrinsic is assumed to execute in the default
floating-point environment except for the rounding mode. This intrinsic is not supported on all targets. Some targets may not support all rounding modes.