https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89670
--- Comment #13 from Jörn Engel <joern at purestorage dot com> --- None of those examples convince me. If you or I know that a zero-argument is impossible, but the compiler doesn't know, wouldn't that still be UB? And if the compiler knows, it can remove the branch either way. Similar for architectures returning 64 or -1, code could be asm(...); if (ret == 64) return 32; return ret; Again, if a null-argument is impossible, the branch can be removed. And if the programmer wants to get 64 or -1, that either requires a conditional or invokes UB. So far, whichever way I look at it, moving the conditional inside of __builtin_ctz() and making the result well-defined for any input doesn't have any downsides. I cannot even think of existing code that would break unless it already invoked UB and depended on a lucky roll of the dice to work correctly.