3 ms·
I find it sad that you need to use inline asm for this. Why isn't GCC providing a built-in to reliably use cmov? Every time I use ?: it's a lottery whether I g
by mgaunard 5y ago
I find it sad that you need to use inline asm for this.
Why isn't GCC providing a built-in to reliably use cmov? Every time I use ?: it's a lottery whether I get it or not. I've had to resort to using the slower bitwise logic to get branch-free code reliably.
- mananaysiempre 5y agoI think I’ve observed reliably-emitted CMOVs when using equivalent (but contrived) arithmetic branchless idioms, e.g. instead of (a ? b : c) write (-!!a & b | -!a & c) (yes, this is rather repulsive, but less so if you think about the negation as turning C-style booleans into Forth/BASIC/mask-style booleans). It should just be a builtin.
- mgaunard 5y agothat is what I meant by "the slower bitwise logic". I didn't know GCC was able to optimize that down to cmov.
- mananaysiempre 5y agoIt’s not, it turns out, I misremembered :( Clang 13 does compile this down to a CMOV in my tests, but GCC 11.1 just translates it as is even with -mtune=native (on Haswell).
- jpegqs 5y agoIt would be great to have builtin for CMOV. But I also want GCC to utilize the hack with the SBB instruction when I write something like: (unsigned)a < (unsigned)b ? ~0 : 0 Instead of three instructions what it generates.
- account42 5y agoIt does use cmp + sbb? https://godbolt.org/z/hnvqrcTcW https://godbolt.org/z/hnvqrcTcW
- jpegqs 5y agoCool, but it doesn't generate SBB in real code, but instead gives me something like this: xorl %r11d, %r11d cmpl %r12d, %eax seta %r11b And if I do both of these, side by side: tmp = rc.code < rc_bound ? ~0 : 0; if (rc.code < rc_bound) rc.range = rc_bound; Then GCC generates an if-else branch. Thus, inline assembly is the only option so far to prevent the compiler from doing something dumb.