Conversation

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.

23% [[gnu::return]] volatile asm (...)
30% asm("":::"pc")
41% keep __builtin_unreachable the same
4% Other: reply with what you think.
0
15
0
@pinskia should that be [[gnu::noreturn]] volatile asm or am I misunderstanding the intention of the attribute?
1
0
4

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

1
0
0

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

0
0
0

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

0
0
0

@pinskia @osandov 'return' would be very confusing because it is the exact opposite of what happens. If these are various trap representations that GCC doesn't know about, how about 'gnu::trap'? Although perhaps 'gnu::asm-noreturn' or something like that would be more natural (so you can place these inside a no return static inline)

1
0
0

@pinskia I want it kept the same because I have used it a bunch already. It's just too out of the bag at this point. That's a selfish choice in that respect, but also, I think generally a more responsible choice for the ecosystem. I also think that as it is it feels very natural as an extension of a popular compiler, just to make it look like some plain old ANSI 89 call. Adding yet more subtle crap I'll 100% tire of looking up to my `__asm__` blocks would be super annoying to me (I already get whiny about the GAS docs, it's probably an attitude problem on my end). I also just don't use the double square brackets notation because I'm working on a hyper portable subset most of the time.

1
0
0

@somebody I did clearify (though after you write the above) about __builtin_unreachable can be still used after an inline-asm and it will act in a similar fashion. just there will be an extra trap instruction added. The idea is how to save on the trap instruction being added; because in the past the kernel folks don't want the extra instruction.

0
0
0

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

1
0
0

@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?

1
0
0

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.

0
0
0