Inline-asm poll.

GCC is looking how to improve __builtin_unreachable behavior by maybe expanding it to a trap instruction instead of following through to the next function.

So the original reason why __builtin_unreachable[https://gcc.gnu.org/PR39252] was added was to mark inline-asm as not "returning" for use inside the Linux Kernel.
There was an old patch (https://gcc.gnu.org/legacy-ml/gcc-patches/2000-01/msg00190.html) which adds "pc" as a clobber to do it too.
Though with the raise of attributes, maybe it is better to use an attribute on the inline-asm.

So the poll is what syntax would be better.

Please spread this wide. I will doing a more formal poll on both GCC's mailing list and LLVM discourse next week after this informal poll is finished but I want to get some ideas/inputs here first before I submit a RFC. I will implementing the GCC side of things and hope someone on the LLVM will pickup the LLVM side.

[[gnu::return]] volatile asm (...)
23.9%
asm("":::"pc")
30.4%
keep __builtin_unreachable the same
41.3%
Other: reply with what you think.
4.3%
Poll ended at .
Making sure you're not a bot!

I should mention a few things, __builtin_unreachable will still work after an inline-asm as saying the inline-asm does not return. Just there will be an extra trap instruction added.

The attribute idea goes towards how other things are handled in c/C++ these days.

The clobbering of pc is the old patch from 2000 which implements most of it already for GCC (just the gimple semantics need some change).

One thing I should mention when it comes to __builtin_unreachable change that is being proposed is that the semantics of doing:
```
if (xyz)
__builtin_unreachable();
```
is not going to change and there will NOT be a branch there still. (likewise for __builtin_unreachable() for switch statements).
It is only for the case of doing:
```
func(); // or other side effects like asm
__builtin_unreachable();
```
Which will be changed to a trap. This is the reason why I asking what is the best way to represent __builtin_unreachable after an inline-asm.
@pinskia I'd find it strange if e.g.
x += 1;
__builtin_unreachable();
were to emit code that increments x. If I wanted that I'd use __builtin_trap. E.g. https://compiler-explorer.com/z/rcMGMf65h should not be translated differently. (except maybe via an opt-in via compiler flag?) However, I would certainly appreciate a warning about f(). But that's a more general feature request: If the compiler hits unconditional UB (also via const-prop) that code path must be guarded by a precondition check or diagnosed.
Compiler Explorer - C++

int x = 0; void f() { x += 1; __builtin_unreachable(); } void g() { x += 1; __builtin_trap(); }

@pinskia That said, I might have voted incorrectly on the poll (keep … the same). From what I wrote above, __builtin_unreachable after inline-asm should lead to a warning, unless the compiler knows that the inline-asm cannot return. From the suggested "pc" clobber vs attribute I find the "pc" clobber solution too subtle/clever. I'd prefer a clearer "asm_doesnt_return" notation.
@pinskia should that be [[gnu::noreturn]] volatile asm or am I misunderstanding the intention of the attribute?

@pinskia I recall writing a bootloader for a Cortex M3 (TI CC2538) that did this…

I'd have to look at the actual code to recall exactly what I did, but I do remember trying function pointers and other tricks to no avail. An inline assembly routine that copied the address of the application's reset vector to %pc wound up working so I left it.

I'm more interested in know how I'm *supposed* to do it.

@stuartl That is the correct way just you should have placed a `__builtin_unreachable();` after the inline-asm to sign that the inline-asm does not return which was added in 4.5.0. The idea here is GCC wants to change the semantics of __builtin_unreachable slightly to improve the QOI situtation with respect to undefined behaviors. This work was originally drive because a function with just unreachable would be empty which breaks things, e.g. exceptions, pointer equality. And at the same time LLVM was started to do some use of undefined behavior should be isolated to unreachables (https://github.com/llvm/llvm-project/pull/137741) and I thought it was a good time to push forward on this cross compiler idea since it was coming up more and go foward on the inline-asm change.

@pinskia Another option would be to create a new __builtin_unreachable_notrap() which never emits a trap instruction (and which can easily be defined to __builtin_unreachable, for compatibility with older compilers).

Then, a few years later, when someone decides to make that also emit a trap, we could create a new __builtin_unreachable_really_notrap() which never emits a trap instruction. And so on.

@pinskia both syntaxes suck imo.

btw, i think replacing UB with an int3 on unreachable/noreturn type code-paths is a great idea, no need to do it just for inline asm.

@pinskia

I think [[gnu::return]] is confusing. Maybe [[gnu::noreturn]] will be better, like noreturn function attribute? Reads as inline assembly that never return control.

Rust lang uses similar option noreturn.

Common Function Attributes (Using the GNU Compiler Collection (GCC))

Common Function Attributes (Using the GNU Compiler Collection (GCC))

@pinskia I've used __builtin_unreachable() to clue gcc into some codepaths not being executable, for better codegen. And i'm certainly not the only one. Won't suddenly emitting a trap cause issues with plenty existing code?
@pinskia oh I like clobbering pc
@pinskia I like it more than an attribute because there’s already a “noreturn” attribute for functions and I don’t think there should be a competing attribute doing the same thing but called “return” (but if you proposed an “asm noreturn” syntax I would be OK with that too)
@pinskia i thought builtin_unreachable is for telling the compiler what it can't know
https://github.com/DO3RB/WirelessNetworkTransceiver/blob/master/samd21g18a/syscalls.c#L104
WirelessNetworkTransceiver/samd21g18a/syscalls.c at master · DO3RB/WirelessNetworkTransceiver

Reliable Radio Communications using run-length limited Golaycodes over ISM Transceivers at maximum baudrate, all packaged as USB Ethernet adapter - DO3RB/WirelessNetworkTransceiver

GitHub