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.