https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59874

--- Comment #13 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Allan Jensen from comment #8)
> Thanks that looks good. I will test it when I have a chance. I am changing
> the Qt sources to not assume the presence of __builtin_clzs when __BMI__ is
> defined. It can use __builtin_clz() and __builtin_ctz()-16U instead, but for
> general compatibility it is nice that GCC also keeps it around. 

There are now several possibilities:

a) Use apparently de-facto standard __builtin_clzs and __builtin_ctzs.

b) (gcc-7+) You can use documented __builtin_clz/__builtin_ctz builtins with
operand casted to (unsigned short). When instruction is available, the compiler
synthesizes 16bit insn variant from 32bit insn and zero-extension, as evident
from gcc.target/i386/pr59874-?.c test cases. This is the most portable
solution.

c) (gcc-6.3+) Figure out how to use __lzcnt16/__tzcnt_u16, as suggested in
Comment #3. This is the optimal solution, as checks for zero operand are not
needed.

> Note, it would be even better though if GCC could support the short forms as
> generic builtins. That changes the semantics slightly, but they are named so
> similarly to the clz, clzl and clzll it would be easy to assume they also
> are generics, with similar semantics, and can work across all targets.
> 
> Btw. I assume __builtin_clzs being a target specific builtin, that GCC never
> had the capability of resolving it at compile-time? If that is the case, it
> might actually be a bug that GCC allowed it at all in a constexpr function.

Hm, I'm not versed in c++, but the provided headers that define various
intrinsics are used in various c++ projects. In gcc-6.3+, the compiler folds
these two builtins with constant operand at compile time, so please retry your
tests with a newer compiler version.

Reply via email to