[llvm-dev] [cfe-dev] [RFC] ASM Goto With Output Constraints

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 27 13:15:39 PDT 2019

On Thu, Jun 27, 2019 at 12:18 PM Nick Desaulniers via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> + CBL mailing list
> On Thu, Jun 27, 2019 at 11:08 AM Bill Wendling <isanbard at gmail.com> wrote:
>> [Adding the correct cfe-dev mailing list address.]
>> On Thu, Jun 27, 2019 at 11:06 AM Bill Wendling <isanbard at gmail.com>
>> wrote:
>>> <source>:2:30: error: 'asm goto' cannot have output constraints
>>>   asm goto("poetry %0, %1" : "=r"(a), "=r"(b) : : : error);
>>> However, LLVM doesn't restrict control transfer instructions from having
>>> outputs (e.g. the invoke instruction
>>> <https://llvm.org/docs/LangRef.html#invoke-instruction>). We propose
>>> changing LLVM's callbr instruction
>>> <https://llvm.org/docs/LangRef.html#callbr-instruction> to allow return
>>> values, similar to how LLVM's implementation of inline assembly (via the
>>> call instruction <https://llvm.org/docs/LangRef.html#call-instruction>)
>>> allows return values. Since there can potentially be zero to many output
>>> constraints, callbr would now return an aggregate which contains an
>>> element for each output constraint.  These values would then be extracted
>>> via extractvalue. With our proposal, the above C example will be
>>> converted to LLVM IR like this:
>>> define i32 @vogon(i32 %a, i32 %b) {
>>> entry:
>>>   %0 = callbr { i32, i32 } asm sideeffect "poetry $0, $1", "=r,=r,X"
>>>       (i8* blockaddress(@vogon, %error))
>>>           to label %asm.fallthrough [label %error]
>>> asm.fallthrough:
>>>   %asmresult.a = extractvalue { i32, i32 } %0, 0
>>>   %asmresult.b = extractvalue { i32, i32 } %0, 1
>>>   %result = add i32 %asmresult.a, %asmresult.b
>>>   ret i32 %result
>>> error:
>>>   ret i32 -1
>>> }
>>> Note that unlike the invoke instruction, callbr's return values are
>>> assumed valid on all branches. The assumption is that the programmer
>>> knows what their inline assembly is doing and where its output constraints
>>> are valid. If the value isn't valid on a particular branch but is used
>>> there anyway, then the result is a poison value. (Also, if a callbr's
>>> return values affect a branch, it will be handled similarly to the
>>> invoke instruction's implementation.) Here's an example of how this
>>> would work:
Generally, I'd prefer if we didn't keep designing new features that assume
the programmer knows what they're doing. Personally, I had been considering
reworking LLVM's Windows EH representation to eliminate the catchswith
instruction, which just exists to multiplex invoke unwind edges to multiple
catch blocks. Instead, we'd use callbr, and I had been assuming it would
have the normal behavior of producing the return value only along the
normal path.

Do you think landingpad offers alternative inspiration for how to handle
this? i.e. you could have a special EHPad-like instruction (must be first
non-PHI instruction) that produces a value along abnormal paths.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190627/efde325a/attachment.html>

More information about the llvm-dev mailing list