Clang’s extension of “asm goto” to support output constraints prompted GCC to
do the same. However, there are some differences between the two
implementations. In particular, GCC allows output constraints to be used on the
indirect branches, while Clang doesn’t.
GCC’s implementation of inline assembly is typically seen as the definitive
implementation. So I believe that we should sync our implementation to align
with GCC’s implementation.
The main difference between Clang’s and GCC’s implementations is how C labels
are handled. Clang allows them to be treated as data. GCC does to a certain
extent, but doesn’t guarantee that the value for a specific label will be the
same in all cases. This was the main reason why Clang chose not to support
output constraints on indirect branches.
Here’s a simple example.
$ cat asm-goto.c
int foo(int a)
{
int b = 0;
if (a)
asm goto ("mov %l1, %0" : "=r" (b) : : : err);
else
asm goto ("mov %l1, %0" : "=r" (b) : : : err);
return b;
err:
return b;
}
GCC emits this:
$ gcc -o - -S asm-goto.c -O2
.file "asm-goto.c"
.text
.p2align 4
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
testl %edi, %edi
je .L2
#APP
# 6 "asm-goto.c" 1
mov .L3, %eax
# 0 "" 2
#NO_APP
.L3:
ret
.p2align 4,,10
.p2align 3
.L2:
#APP
# 8 "asm-goto.c" 1
mov .L5, %eax
# 0 "" 2
#NO_APP
.L5:
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.ident "GCC: (Debian 12.2.0-1) 12.2.0"
.section .note.GNU-stack,"",@progbits
Note that even though the original “asm goto” statements refer to the same C
label, the values stored in “b” aren’t the same.
Implementation
Clang doesn’t have a restriction from using the output of an asm goto on the
indirect branch. I.e., there’s nothing that checks and warns about doing so.
The bulk of the implementation work will be in verifying that the code Clang
emits is correct for all situations. Given how asm goto is implemented in LLVM,
most changes will be in the back-end. (I know this is a bit hand-wavy, but it’s
difficult to estimate how much work it will take until implementation starts.)
-bw