Implementation of asm-goto support in LLVM
This patch accompanies the RFC posted here:
http://lists.llvm.org/pipermail/llvm-dev/2018-October/127239.html
This patch adds a new CallBr IR instruction to support asm-goto
inline assembly like gcc as used by the linux kernel. This
instruction is both a call instruction and a terminator
instruction with multiple successors. Only inline assembly
usage is supported today.
This also adds a new INLINEASM_BR opcode to SelectionDAG and
MachineIR to represent an INLINEASM block that is also
considered a terminator instruction.
There will likely be more bug fixes and optimizations to follow
this, but we felt it had reached a point where we would like to
switch to an incremental development model.
Patch by Craig Topper, Alexander Ivchenko, Mikhail Dvoretckii
Differential Revision: https://reviews.llvm.org/D53765
llvm-svn: 353563
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 776271d..ea941eb 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6513,6 +6513,7 @@
The terminator instructions are: ':ref:`ret <i_ret>`',
':ref:`br <i_br>`', ':ref:`switch <i_switch>`',
':ref:`indirectbr <i_indirectbr>`', ':ref:`invoke <i_invoke>`',
+':ref:`callbr <i_callbr>`'
':ref:`resume <i_resume>`', ':ref:`catchswitch <i_catchswitch>`',
':ref:`catchret <i_catchret>`',
':ref:`cleanupret <i_cleanupret>`',
@@ -6837,6 +6838,85 @@
%retval = invoke coldcc i32 %Testfnptr(i32 15) to label %Continue
unwind label %TestCleanup ; i32:retval set
+.. _i_callbr:
+
+'``callbr``' Instruction
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+::
+
+ <result> = callbr [cconv] [ret attrs] [addrspace(<num>)] [<ty>|<fnty> <fnptrval>(<function args>) [fn attrs]
+ [operand bundles] to label <normal label> or jump [other labels]
+
+Overview:
+"""""""""
+
+The '``callbr``' instruction causes control to transfer to a specified
+function, with the possibility of control flow transfer to either the
+'``normal``' label or one of the '``other``' labels.
+
+This instruction should only be used to implement the "goto" feature of gcc
+style inline assembly. Any other usage is an error in the IR verifier.
+
+Arguments:
+""""""""""
+
+This instruction requires several arguments:
+
+#. The optional "cconv" marker indicates which :ref:`calling
+ convention <callingconv>` the call should use. If none is
+ specified, the call defaults to using C calling conventions.
+#. The optional :ref:`Parameter Attributes <paramattrs>` 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 :ref:`datalayout string<langref_datalayout>` 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 marked
+ ``void``.
+#. '``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
+ indirect ``callbr``'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 :ref:`first class <t_firstclass>` type. If the function signature
+ indicates the function accepts a variable number of arguments, the
+ extra arguments can be specified.
+#. '``normal label``': the label reached when the called function
+ executes a '``ret``' instruction.
+#. '``other labels``': the labels reached when a callee transfers control
+ to a location other than the normal '``normal label``'
+#. The optional :ref:`function attributes <fnattrs>` list.
+#. The optional :ref:`operand bundles <opbundles>` list.
+
+Semantics:
+""""""""""
+
+This instruction is designed to operate as a standard '``call``'
+instruction in most regards. The primary difference is that it
+establishes an association with additional labels to define where control
+flow goes after the call.
+
+The only use of this today is to implement the "goto" feature of gcc inline
+assembly where additional labels can be provided as locations for the inline
+assembly to jump to.
+
+Example:
+""""""""
+
+.. code-block:: llvm
+
+ callbr void asm "", "r,x"(i32 %x, i8 *blockaddress(@foo, %fail))
+ to label %normal or jump [label %fail]
+
.. _i_resume:
'``resume``' Instruction