https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78037
--- Comment #9 from Uroš Bizjak <ubizjak at gmail dot com> --- Created attachment 39845 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39845&action=edit Patch that introduces new builtins with UNSPEC_LZCNT and UNSPEC_TZCNT RTX patterns This patch introduces new builtins with UNSPEC_LZCNT and UNSPEC_TZCNT RTX patterns. The patch fails following tests: FAIL: gcc.target/i386/bmi-4.c (test for excess errors) FAIL: gcc.target/i386/bmi-5.c (test for excess errors) FAIL: gcc.target/i386/bmi-6.c (test for excess errors) These tests check that: /* Test that a constant operand 0 to tzcnt gets folded. */ extern void link_error(void); int main() { if (__tzcnt_u32(0) != 32) link_error(); return 0; } But unpatched gcc simply calls generic __builtin_ctz in the above case. This is undefined behaviour, so it looks that the test works only by luck... OTOH, we know that __tzcnt_* and __lzcnt_* builtin functions implement CTZ and CLZ functionality with defined output for all input arguments. Instead of simply removing mentioned tests, we can introduce certain constant-folding functionality to ix86_fold_builtin that would handle constant arguments in a __builtin_ctz/__builtin_clz way. The patch is thoroughly tested and works OK (modulo testsuite failures mentioned above), but I have no idea on how to implement tree-folding stuff. So, some kind soul that would take the patch from this point is most welcome.