https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113764
Roger Sayle <roger at nextmovesoftware dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |roger at nextmovesoftware dot com Status|UNCONFIRMED |NEW Ever confirmed|0 |1 Last reconfirmed| |2024-02-08 --- Comment #1 from Roger Sayle <roger at nextmovesoftware dot com> --- Confirmed. This issue has two parts. The first is that the bsr_1 pattern (and variants) is (are) conditional on !TARGET_LZCNT, so the bsrl instruction isn't currently available with -mlzcnt. The second is that the middle-end doesn't have a preferred canonical RTL representation for this idiom, but all three of the following equivalent functions should generate identical code: unsigned bsr1(unsigned x) { return __builtin_clz(x) ^ 31; } unsigned bsr2(unsigned x) { return 31 - __builtin_clz(x); } unsigned bsr3(unsigned x) { return ~__builtin_clz(x) & 31; } [Note that the tree-ssa optimizers do transform bsr3 into bsr1]. A suitable fix would be to add the equivalent clz(x)^31 variant pattern to i386.md as a "synonymous" define_insn pattern.