.. code-block:: llvm
- %0 = add i32 %X, %X ; yields {i32}:%0
- %1 = add i32 %0, %0 ; yields {i32}:%1
+ %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 ``%X`` by 8 illustrates several important
exists for defining a dll interface, the compiler, assembler and linker know
it is externally referenced and must refrain from deleting the symbol.
+.. _tls_model:
+
+Thread Local Storage Models
+---------------------------
+
+A variable may be defined as ``thread_local``, which means that it will
+not be shared by threads (each thread will have a separated copy of the
+variable). Not all targets support thread-local variables. Optionally, a
+TLS model may be specified:
+
+``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 <http://people.redhat.com/drepper/tls.pdf>`_ 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 a alias, but then it only governs how
+the alias is accessed. It will not have any effect in the aliasee.
+
.. _namedtypes:
Structure Types
Global variables define regions of memory allocated at compilation time
instead of run-time.
-Global variables definitions must be initialized, may have an explicit section
-to be placed in, and may have an optional explicit alignment specified.
+Global variables definitions must be initialized.
Global variables in other translation units can also be declared, in which
case they don't have an initializer.
-A variable may be defined as ``thread_local``, which means that it will
-not be shared by threads (each thread will have a separated copy of the
-variable). Not all targets support thread-local variables. Optionally, a
-TLS model may be specified:
-
-``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.
-
-The models correspond to the ELF TLS models; see `ELF Handling For
-Thread-Local Storage <http://people.redhat.com/drepper/tls.pdf>`_ 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.
+Either global variable definitions or declarations may have an explicit section
+to be placed in and may have an optional explicit alignment specified.
A variable may be defined as a global ``constant``, which indicates that
the contents of the variable will **never** be modified (enabling better
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.
By default, global initializers are optimized by assuming that global
variables defined within the module are not modified from their
Globals can also have a :ref:`DLL storage class <dllstorageclass>`.
+Variables and aliasaes can have a
+:ref:`Thread Local Storage Model <tls_model>`.
+
Syntax::
[@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
- [AddrSpace] [unnamed_addr] [ExternallyInitialized]
- <global | constant> <Type>
+ [unnamed_addr] [AddrSpace] [ExternallyInitialized]
+ <global | constant> <Type> [<InitializerConstant>]
[, section "name"] [, align <Alignment>]
For example, the following defines a global in a numbered address space
:ref:`parameter attribute <paramattrs>` for the return type, a function
name, a (possibly empty) argument list (each with optional :ref:`parameter
attributes <paramattrs>`), optional :ref:`function attributes <fnattrs>`,
-an optional section, an optional alignment, an optional :ref:`garbage
-collector name <gc>`, an optional :ref:`prefix <prefixdata>`, an opening
+an optional section, an optional alignment,
+an optional :ref:`comdat <langref_comdats>`,
+an optional :ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`, an opening
curly brace, a list of basic blocks, and a closing curly brace.
LLVM function declarations consist of the "``declare``" keyword, an
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 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
define [linkage] [visibility] [DLLStorageClass]
[cconv] [ret attrs]
<ResultType> @<FunctionName> ([argument list])
- [unnamed_addr] [fn Attrs] [section "name"] [align N]
- [gc] [prefix Constant] { ... }
+ [unnamed_addr] [fn Attrs] [section "name"] [comdat $<ComdatName>]
+ [align N] [gc] [prefix Constant] { ... }
.. _langref_aliases:
Aliases
-------
-Aliases act as "second name" for the aliasee value (which can be either
-function, global variable, another alias or bitcast of global value).
+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 :ref:`linkage type <linkage>`, an optional
-:ref:`visibility style <visibility>`, and an optional :ref:`DLL storage class
-<dllstorageclass>`.
+:ref:`visibility style <visibility>`, an optional :ref:`DLL storage class
+<dllstorageclass>` and an optional :ref:`tls model <tls_model>`.
Syntax::
- @<Name> = [Visibility] [DLLStorageClass] alias [Linkage] <AliaseeTy> @<Aliasee>
+ @<Name> = [Visibility] [DLLStorageClass] [ThreadLocal] [unnamed_addr] alias [Linkage] <AliaseeTy> @<Aliasee>
The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
-might not correctly handle dropping a weak symbol that is aliased by a non-weak
-alias.
+might not correctly handle dropping a weak symbol that is aliased.
Alias that are not ``unnamed_addr`` are guaranteed to have the same address as
-the aliasee.
+the aliasee expression. ``unnamed_addr`` ones are only guaranteed to point
+to the same content.
+
+Since aliases are only a second name, some restrictions apply, of which
+some can only be checked when producing an object file:
+
+* The expression defining the aliasee must be computable at assembly
+ time. Since it is just a name, no relocations can be used.
+
+* No alias in the expression can be weak as the possibility of the
+ intermediate alias being overridden cannot be represented in an
+ object file.
-The aliasee must be a definition.
+* No global value in the expression can be a declaration, since that
+ would require a relocation, which is not possible.
-Aliases are not allowed to point to aliases with linkages that can be
-overridden. Since they are only a second name, the possibility of the
-intermediate alias being overridden cannot be represented in an object file.
+.. _langref_comdats:
+
+Comdats
+-------
+
+Comdat IR provides access to COFF and ELF object file COMDAT functionality.
+
+Comdats have a name which represents the COMDAT key. All global objects which
+specify this key will only end up in the final object file if the linker chooses
+that key over some other key. Aliases are placed in the same COMDAT that their
+aliasee computes to, if any.
+
+Comdats have a selection kind to provide input on how the linker should
+choose between keys in two different object files.
+
+Syntax::
+
+ $<Name> = comdat SelectionKind
+
+The selection kind must be one of the following:
+
+``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.
+``noduplicates``
+ The linker requires that only section with this COMDAT key exist.
+``samesize``
+ The linker may choose any COMDAT key but the sections must contain the
+ same amount of data.
+
+Note that the Mach-O platform doesn't support COMDATs and ELF only supports
+``any`` as a selection kind.
+
+Here is an example of a COMDAT group where a function will only be selected if
+the COMDAT key's section is the largest:
+
+.. code-block:: llvm
+
+ $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
+``IMAGE_COMDAT_SELECT_LARGEST`` containing the contents of the ``@foo`` symbol
+and another COMDAT section with selection kind
+``IMAGE_COMDAT_SELECT_ASSOCIATIVE`` which is associated with the first COMDAT
+section and contains the contents of the ``@baz`` symbol.
+
+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:
+
+.. code-block:: llvm
+
+ $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, for example, when a global variable has linkonce_odr linkage.
.. _namedmetadatastructure:
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``.
``minsize``
This attribute suggests that optimization passes and code generator
passes make choices that keep the code size of this function as small
'``range``' Metadata
^^^^^^^^^^^^^^^^^^^^
-``range`` metadata may be attached only to loads of integer types. It
-expresses the possible ranges the loaded value is in. The ranges are
-represented with a flattened list of integers. The loaded value is known
-to be in the union of the ranges defined by each consecutive pair. Each
-pair has the following properties:
+``range`` metadata may be attached only to ``load``, ``call`` and ``invoke`` of
+integer types. It expresses the possible ranges the loaded value or the value
+returned by the called function at this call site is in. The ranges are
+represented with a flattened list of integers. The loaded value or the value
+returned is known to be in the union of the ranges defined by each consecutive
+pair. Each pair has the following properties:
- The type must match the type loaded by the instruction.
- The pair ``a,b`` represents the range ``[a,b)``.
%a = load i8* %x, align 1, !range !0 ; Can only be 0 or 1
%b = load i8* %y, align 1, !range !1 ; Can only be 255 (-1), 0 or 1
- %c = load i8* %z, align 1, !range !2 ; Can only be 0, 1, 3, 4 or 5
- %d = load i8* %z, align 1, !range !3 ; Can only be -2, -1, 3, 4 or 5
+ %c = call i8 @foo(), !range !2 ; Can only be 0, 1, 3, 4 or 5
+ %d = invoke i8 @bar() to label %cont
+ unwind label %lpad, !range !3 ; Can only be -2, -1, 3, 4 or 5
...
!0 = metadata !{ i8 0, i8 2 }
!1 = metadata !{ i8 255, i8 2 }
The loop identifier metadata can be used to specify additional per-loop
metadata. Any operands after the first operand can be treated as user-defined
-metadata. For example the ``llvm.vectorizer.unroll`` metadata is understood
+metadata. For example the ``llvm.loop.vectorize.unroll`` metadata is understood
by the loop vectorizer to indicate how many times to unroll the loop:
.. code-block:: llvm
br i1 %exitcond, label %._crit_edge, label %.lr.ph, !llvm.loop !0
...
!0 = metadata !{ metadata !0, metadata !1 }
- !1 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 2 }
+ !1 = metadata !{ metadata !"llvm.loop.vectorize.unroll", i32 2 }
'``llvm.mem``'
^^^^^^^^^^^^^^^
Precisely, given two instructions ``m1`` and ``m2`` that both have the
``llvm.mem.parallel_loop_access`` metadata, with ``L1`` and ``L2`` being the
set of loops associated with that metadata, respectively, then there is no loop
-carried dependence between ``m1`` and ``m2`` for loops ``L1`` or
+carried dependence between ``m1`` and ``m2`` for loops in both ``L1`` and
``L2``.
As a special case, if all memory accessing instructions in a loop have
!1 = metadata !{ metadata !1 } ; an identifier for the inner loop
!2 = metadata !{ metadata !2 } ; an identifier for the outer loop
-'``llvm.vectorizer``'
-^^^^^^^^^^^^^^^^^^^^^
+'``llvm.loop.vectorize``'
+^^^^^^^^^^^^^^^^^^^^^^^^^
-Metadata prefixed with ``llvm.vectorizer`` is used to control per-loop
+Metadata prefixed with ``llvm.loop.vectorize`` is used to control per-loop
vectorization parameters such as vectorization factor and unroll factor.
-``llvm.vectorizer`` metadata should be used in conjunction with ``llvm.loop``
-loop identification metadata.
+``llvm.loop.vectorize`` metadata should be used in conjunction with
+``llvm.loop`` loop identification metadata.
-'``llvm.vectorizer.unroll``' Metadata
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+'``llvm.loop.vectorize.unroll``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This metadata instructs the loop vectorizer to unroll the specified
loop exactly ``N`` times.
-The first operand is the string ``llvm.vectorizer.unroll`` and the second
+The first operand is the string ``llvm.loop.vectorize.unroll`` and the second
operand is an integer specifying the unroll factor. For example:
.. code-block:: llvm
- !0 = metadata !{ metadata !"llvm.vectorizer.unroll", i32 4 }
+ !0 = metadata !{ metadata !"llvm.loop.vectorize.unroll", i32 4 }
-Note that setting ``llvm.vectorizer.unroll`` to 1 disables unrolling of the
-loop.
+Note that setting ``llvm.loop.vectorize.unroll`` to 1 disables
+unrolling of the loop.
-If ``llvm.vectorizer.unroll`` is set to 0 then the amount of unrolling will be
-determined automatically.
+If ``llvm.loop.vectorize.unroll`` is set to 0 then the amount of
+unrolling will be determined automatically.
-'``llvm.vectorizer.width``' Metadata
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+'``llvm.loop.vectorize.width``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This metadata sets the target width of the vectorizer to ``N``. Without
this metadata, the vectorizer will choose a width automatically.
Regardless of this metadata, the vectorizer will only vectorize loops if
it believes it is valid to do so.
-The first operand is the string ``llvm.vectorizer.width`` and the second
-operand is an integer specifying the width. For example:
+The first operand is the string ``llvm.loop.vectorize.width`` and the
+second operand is an integer specifying the width. For example:
.. code-block:: llvm
- !0 = metadata !{ metadata !"llvm.vectorizer.width", i32 4 }
+ !0 = metadata !{ metadata !"llvm.loop.vectorize.width", i32 4 }
-Note that setting ``llvm.vectorizer.width`` to 1 disables vectorization of the
-loop.
+Note that setting ``llvm.loop.vectorize.width`` to 1 disables
+vectorization of the loop.
-If ``llvm.vectorizer.width`` is set to 0 then the width will be determined
-automatically.
+If ``llvm.loop.vectorize.width`` is set to 0 then the width will be
+determined automatically.
Module Flags Metadata
=====================
linker, or an option that is reserved by the target specific assembly writer or
object file emitter. No other aspect of these options is defined by the IR.
+C type width Module Flags Metadata
+----------------------------------
+
+The ARM backend emits a section into each generated object file describing the
+options that it was compiled with (in a compiler-independent way) to prevent
+linking incompatible objects, and to allow automatic library selection. Some
+of these options are not visible at the IR level, namely wchar_t width and enum
+width.
+
+To pass this information to the backend, these options are encoded in module
+flags metadata, using the following key-value pairs:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Key
+ - Value
+
+ * - short_wchar
+ - * 0 --- sizeof(wchar_t) == 4
+ * 1 --- sizeof(wchar_t) == 2
+
+ * - short_enum
+ - * 0 --- Enums are at least as large as an ``int``.
+ * 1 --- Enums are stored in the smallest integer type which can
+ represent all of its values.
+
+For example, the following metadata section specifies that the module was
+compiled with a ``wchar_t`` width of 4 bytes, and the underlying type of an
+enum is the smallest type which can represent all of its values::
+
+ !llvm.module.flags = !{!0, !1}
+ !0 = metadata !{i32 1, metadata !"short_wchar", i32 1}
+ !1 = metadata !{i32 1, metadata !"short_enum", i32 0}
+
.. _intrinsicglobalvariables:
Intrinsic Global Variables
.. code-block:: llvm
%retval = invoke i32 @Test(i32 15) to label %Continue
- unwind label %TestCleanup ; {i32}:retval set
+ unwind label %TestCleanup ; i32:retval set
%retval = invoke coldcc i32 %Testfnptr(i32 15) to label %Continue
- unwind label %TestCleanup ; {i32}:retval set
+ unwind label %TestCleanup ; i32:retval set
.. _i_resume:
::
- <result> = add <ty> <op1>, <op2> ; yields {ty}:result
- <result> = add nuw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = add nsw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = add nuw nsw <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = add <ty> <op1>, <op2> ; yields ty:result
+ <result> = add nuw <ty> <op1>, <op2> ; yields ty:result
+ <result> = add nsw <ty> <op1>, <op2> ; yields ty:result
+ <result> = add nuw nsw <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = add i32 4, %var ; yields {i32}:result = 4 + %var
+ <result> = add i32 4, %var ; yields i32:result = 4 + %var
.. _i_fadd:
::
- <result> = fadd [fast-math flags]* <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = fadd [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = fadd float 4.0, %var ; yields {float}:result = 4.0 + %var
+ <result> = fadd float 4.0, %var ; yields float:result = 4.0 + %var
'``sub``' Instruction
^^^^^^^^^^^^^^^^^^^^^
::
- <result> = sub <ty> <op1>, <op2> ; yields {ty}:result
- <result> = sub nuw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = sub nsw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = sub nuw nsw <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = sub <ty> <op1>, <op2> ; yields ty:result
+ <result> = sub nuw <ty> <op1>, <op2> ; yields ty:result
+ <result> = sub nsw <ty> <op1>, <op2> ; yields ty:result
+ <result> = sub nuw nsw <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = sub i32 4, %var ; yields {i32}:result = 4 - %var
- <result> = sub i32 0, %val ; yields {i32}:result = -%var
+ <result> = sub i32 4, %var ; yields i32:result = 4 - %var
+ <result> = sub i32 0, %val ; yields i32:result = -%var
.. _i_fsub:
::
- <result> = fsub [fast-math flags]* <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = fsub [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = fsub float 4.0, %var ; yields {float}:result = 4.0 - %var
- <result> = fsub float -0.0, %val ; yields {float}:result = -%var
+ <result> = fsub float 4.0, %var ; yields float:result = 4.0 - %var
+ <result> = fsub float -0.0, %val ; yields float:result = -%var
'``mul``' Instruction
^^^^^^^^^^^^^^^^^^^^^
::
- <result> = mul <ty> <op1>, <op2> ; yields {ty}:result
- <result> = mul nuw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = mul nsw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = mul nuw nsw <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = mul <ty> <op1>, <op2> ; yields ty:result
+ <result> = mul nuw <ty> <op1>, <op2> ; yields ty:result
+ <result> = mul nsw <ty> <op1>, <op2> ; yields ty:result
+ <result> = mul nuw nsw <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = mul i32 4, %var ; yields {i32}:result = 4 * %var
+ <result> = mul i32 4, %var ; yields i32:result = 4 * %var
.. _i_fmul:
::
- <result> = fmul [fast-math flags]* <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = fmul [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = fmul float 4.0, %var ; yields {float}:result = 4.0 * %var
+ <result> = fmul float 4.0, %var ; yields float:result = 4.0 * %var
'``udiv``' Instruction
^^^^^^^^^^^^^^^^^^^^^^
::
- <result> = udiv <ty> <op1>, <op2> ; yields {ty}:result
- <result> = udiv exact <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = udiv <ty> <op1>, <op2> ; yields ty:result
+ <result> = udiv exact <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = udiv i32 4, %var ; yields {i32}:result = 4 / %var
+ <result> = udiv i32 4, %var ; yields i32:result = 4 / %var
'``sdiv``' Instruction
^^^^^^^^^^^^^^^^^^^^^^
::
- <result> = sdiv <ty> <op1>, <op2> ; yields {ty}:result
- <result> = sdiv exact <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = sdiv <ty> <op1>, <op2> ; yields ty:result
+ <result> = sdiv exact <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = sdiv i32 4, %var ; yields {i32}:result = 4 / %var
+ <result> = sdiv i32 4, %var ; yields i32:result = 4 / %var
.. _i_fdiv:
::
- <result> = fdiv [fast-math flags]* <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = fdiv [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = fdiv float 4.0, %var ; yields {float}:result = 4.0 / %var
+ <result> = fdiv float 4.0, %var ; yields float:result = 4.0 / %var
'``urem``' Instruction
^^^^^^^^^^^^^^^^^^^^^^
::
- <result> = urem <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = urem <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = urem i32 4, %var ; yields {i32}:result = 4 % %var
+ <result> = urem i32 4, %var ; yields i32:result = 4 % %var
'``srem``' Instruction
^^^^^^^^^^^^^^^^^^^^^^
::
- <result> = srem <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = srem <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = srem i32 4, %var ; yields {i32}:result = 4 % %var
+ <result> = srem i32 4, %var ; yields i32:result = 4 % %var
.. _i_frem:
::
- <result> = frem [fast-math flags]* <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = frem [fast-math flags]* <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = frem float 4.0, %var ; yields {float}:result = 4.0 % %var
+ <result> = frem float 4.0, %var ; yields float:result = 4.0 % %var
.. _bitwiseops:
::
- <result> = shl <ty> <op1>, <op2> ; yields {ty}:result
- <result> = shl nuw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = shl nsw <ty> <op1>, <op2> ; yields {ty}:result
- <result> = shl nuw nsw <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = shl <ty> <op1>, <op2> ; yields ty:result
+ <result> = shl nuw <ty> <op1>, <op2> ; yields ty:result
+ <result> = shl nsw <ty> <op1>, <op2> ; yields ty:result
+ <result> = shl nuw nsw <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = shl i32 4, %var ; yields {i32}: 4 << %var
- <result> = shl i32 4, 2 ; yields {i32}: 16
- <result> = shl i32 1, 10 ; yields {i32}: 1024
+ <result> = shl i32 4, %var ; yields i32: 4 << %var
+ <result> = shl i32 4, 2 ; yields i32: 16
+ <result> = shl i32 1, 10 ; yields i32: 1024
<result> = shl i32 1, 32 ; undefined
<result> = shl <2 x i32> < i32 1, i32 1>, < i32 1, i32 2> ; yields: result=<2 x i32> < i32 2, i32 4>
::
- <result> = lshr <ty> <op1>, <op2> ; yields {ty}:result
- <result> = lshr exact <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = lshr <ty> <op1>, <op2> ; yields ty:result
+ <result> = lshr exact <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = lshr i32 4, 1 ; yields {i32}:result = 2
- <result> = lshr i32 4, 2 ; yields {i32}:result = 1
- <result> = lshr i8 4, 3 ; yields {i8}:result = 0
- <result> = lshr i8 -2, 1 ; yields {i8}:result = 0x7F
+ <result> = lshr i32 4, 1 ; yields i32:result = 2
+ <result> = lshr i32 4, 2 ; yields i32:result = 1
+ <result> = lshr i8 4, 3 ; yields i8:result = 0
+ <result> = lshr i8 -2, 1 ; yields i8:result = 0x7F
<result> = lshr i32 1, 32 ; undefined
<result> = lshr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 2> ; yields: result=<2 x i32> < i32 0x7FFFFFFF, i32 1>
::
- <result> = ashr <ty> <op1>, <op2> ; yields {ty}:result
- <result> = ashr exact <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = ashr <ty> <op1>, <op2> ; yields ty:result
+ <result> = ashr exact <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <result> = ashr i32 4, 1 ; yields {i32}:result = 2
- <result> = ashr i32 4, 2 ; yields {i32}:result = 1
- <result> = ashr i8 4, 3 ; yields {i8}:result = 0
- <result> = ashr i8 -2, 1 ; yields {i8}:result = -1
+ <result> = ashr i32 4, 1 ; yields i32:result = 2
+ <result> = ashr i32 4, 2 ; yields i32:result = 1
+ <result> = ashr i8 4, 3 ; yields i8:result = 0
+ <result> = ashr i8 -2, 1 ; yields i8:result = -1
<result> = ashr i32 1, 32 ; undefined
<result> = ashr <2 x i32> < i32 -2, i32 4>, < i32 1, i32 3> ; yields: result=<2 x i32> < i32 -1, i32 0>
::
- <result> = and <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = and <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <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
+ <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
^^^^^^^^^^^^^^^^^^^^
::
- <result> = or <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = or <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
::
- <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
+ <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
^^^^^^^^^^^^^^^^^^^^^
::
- <result> = xor <ty> <op1>, <op2> ; yields {ty}:result
+ <result> = xor <ty> <op1>, <op2> ; yields ty:result
Overview:
"""""""""
.. code-block:: llvm
- <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
+ <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
-----------------
::
- <result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] ; yields {type*}:result
+ <result> = alloca [inalloca] <type> [, <ty> <NumElements>] [, align <alignment>] ; yields type*:result
Overview:
"""""""""
.. code-block:: llvm
- %ptr = alloca i32 ; yields {i32*}:ptr
- %ptr = alloca i32, i32 4 ; yields {i32*}:ptr
- %ptr = alloca i32, i32 4, align 1024 ; yields {i32*}:ptr
- %ptr = alloca i32, align 1024 ; yields {i32*}:ptr
+ %ptr = alloca i32 ; yields i32*:ptr
+ %ptr = alloca i32, i32 4 ; yields i32*:ptr
+ %ptr = alloca i32, i32 4, align 1024 ; yields i32*:ptr
+ %ptr = alloca i32, align 1024 ; yields i32*:ptr
.. _i_load:
.. code-block:: llvm
- %ptr = alloca i32 ; yields {i32*}:ptr
- store i32 3, i32* %ptr ; yields {void}
- %val = load i32* %ptr ; yields {i32}:val = i32 3
+ %ptr = alloca i32 ; yields i32*:ptr
+ store i32 3, i32* %ptr ; yields void
+ %val = load i32* %ptr ; yields i32:val = i32 3
.. _i_store:
::
- store [volatile] <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>] ; yields {void}
- store atomic [volatile] <ty> <value>, <ty>* <pointer> [singlethread] <ordering>, align <alignment> ; yields {void}
+ store [volatile] <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>] ; yields void
+ store atomic [volatile] <ty> <value>, <ty>* <pointer> [singlethread] <ordering>, align <alignment> ; yields void
Overview:
"""""""""
.. code-block:: llvm
- %ptr = alloca i32 ; yields {i32*}:ptr
- store i32 3, i32* %ptr ; yields {void}
- %val = load i32* %ptr ; yields {i32}:val = i32 3
+ %ptr = alloca i32 ; yields i32*:ptr
+ store i32 3, i32* %ptr ; yields void
+ %val = load i32* %ptr ; yields i32:val = i32 3
.. _i_fence:
::
- fence [singlethread] <ordering> ; yields {void}
+ fence [singlethread] <ordering> ; yields void
Overview:
"""""""""
.. code-block:: llvm
- fence acquire ; yields {void}
- fence singlethread seq_cst ; yields {void}
+ fence acquire ; yields void
+ fence singlethread seq_cst ; yields void
.. _i_cmpxchg:
::
- cmpxchg [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <success ordering> <failure ordering> ; yields {ty}
+ cmpxchg [weak] [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <success ordering> <failure ordering> ; 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 stores a new value into the memory.
+equal, it tries to store a new value into the memory.
Arguments:
""""""""""
other :ref:`volatile operations <volatile>`.
The success and failure :ref:`ordering <ordering>` arguments specify how this
-``cmpxchg`` synchronizes with other atomic operations. The both ordering
-parameters must be at least ``monotonic``, the ordering constraint on failure
-must be no stronger than that on success, and the failure ordering cannot be
-either ``release`` or ``acq_rel``.
+``cmpxchg`` synchronizes with other atomic operations. Both ordering parameters
+must be at least ``monotonic``, the ordering constraint on failure must be no
+stronger than that on success, and the failure ordering cannot be either
+``release`` or ``acq_rel``.
The optional "``singlethread``" argument declares that the ``cmpxchg``
is only atomic with respect to code (usually signal handlers) running in
Semantics:
""""""""""
-The contents of memory at the location specified by the '``<pointer>``'
-operand is read and compared to '``<cmp>``'; if the read value is the
-equal, '``<new>``' is written. The original value at the location is
-returned.
+The contents of memory at the location specified by the '``<pointer>``' operand
+is read and compared to '``<cmp>``'; if the read value is the equal, the
+'``<new>``' is written. 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
.. code-block:: llvm
entry:
- %orig = atomic load i32* %ptr unordered ; yields {i32}
+ %orig = atomic load i32* %ptr unordered ; yields i32
br label %loop
loop:
%cmp = phi i32 [ %orig, %entry ], [%old, %loop]
%squared = mul i32 %cmp, %cmp
- %old = cmpxchg i32* %ptr, i32 %cmp, i32 %squared acq_rel monotonic ; yields {i32}
- %success = icmp eq i32 %cmp, %old
+ %val_success = cmpxchg i32* %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 [volatile] <operation> <ty>* <pointer>, <ty> <value> [singlethread] <ordering> ; yields {ty}
+ atomicrmw [volatile] <operation> <ty>* <pointer>, <ty> <value> [singlethread] <ordering> ; yields ty
Overview:
"""""""""
.. code-block:: llvm
- %old = atomicrmw add i32* %ptr, i32 1 acquire ; yields {i32}
+ %old = atomicrmw add i32* %ptr, i32 1 acquire ; yields i32
.. _i_getelementptr:
::
- <result> = icmp <cond> <ty> <op1>, <op2> ; yields {i1} or {<N x i1>}:result
+ <result> = icmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
Overview:
"""""""""
::
- <result> = fcmp <cond> <ty> <op1>, <op2> ; yields {i1} or {<N x i1>}:result
+ <result> = fcmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
Overview:
"""""""""
uses value of call or is void).
- Option ``-tailcallopt`` is enabled, or
``llvm::GuaranteedTailCallOpt`` is ``true``.
- - `Platform specific constraints are
+ - `Platform-specific constraints are
met. <CodeGenerator.html#tailcallopt>`_
#. The optional "cconv" marker indicates which :ref:`calling
call void %foo(i8 97 signext)
%struct.A = type { i32, i8 }
- %r = call %struct.A @foo() ; yields { 32, 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
.. code-block:: llvm
- %r2 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) ; yields {float}:r2 = (a * b) + c
+ %r2 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) ; yields float:r2 = (a * b) + c
Half Precision Floating Point Intrinsics
----------------------------------------
::
- declare i16 @llvm.convert.to.fp16(f32 %a)
+ declare i16 @llvm.convert.to.fp16(float %a)
Overview:
"""""""""
.. code-block:: llvm
- %res = call i16 @llvm.convert.to.fp16(f32 %a)
+ %res = call i16 @llvm.convert.to.fp16(float %a)
store i16 %res, i16* @x, align 2
.. _int_convert_from_fp16:
::
- declare f32 @llvm.convert.from.fp16(i16 %a)
+ declare float @llvm.convert.from.fp16(i16 %a)
Overview:
"""""""""
.. code-block:: llvm
%a = load i16* @x, align 2
- %res = call f32 @llvm.convert.from.fp16(i16 %a)
+ %res = call float @llvm.convert.from.fp16(i16 %a)
Debugger Intrinsics
-------------------
""""""""""
On some architectures the address of the code to be executed needs to be
-different to the address where the trampoline is actually stored. This
+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 :ref:`bitcast and executed <int_trampoline>`.
Memory Use Markers
------------------
-This class of intrinsics exists to information about the lifetime of
+This class of intrinsics provides information about the lifetime of
memory objects and ranges where variables are immutable.
.. _int_lifestart: