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

Bill Wendling via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 27 13:33:39 PDT 2019

On Thu, Jun 27, 2019 at 1:15 PM Reid Kleckner <rnk at google.com> wrote:

> 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.
> Wouldn't it be unnecessarily restrictive though to limit the valid return
values only to the normal edge? (This is more for the generality of the
callbr instruction and not necessarily related to the initial inspiration
for "asm goto".)

> 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.

I haven't touched EH stuff for awhile so things have probably changed. It's
an intriguing notion and may help alleviate the issues James mentioned.
Could you write some pseudo-IR to show more what you're thinking?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190627/833ccc7d/attachment-0001.html>

More information about the llvm-dev mailing list