On Tue, Oct 13, 2026 at 10:20 AM <[email protected]> wrote: > > From: Kyrylo Tkachov <[email protected]> > > A GIMPLE FE test with a .CLZ or .CTZ call needs the clz or ctz > instruction pattern for the mode of the call, because the expansion of > these internal functions has no fallback. The clz and ctz effective > targets only check that __builtin_clz and __builtin_ctz do not become > library calls. They are also true when the expander makes the count > from other patterns, for example ctz on s390 before z17. > > Add clz_ifn and ctz_ifn. They check that niter analysis turns a > counting loop on unsigned int into a .CLZ or .CTZ call, which it does > only if the target has the instruction pattern.
I'd like to see these kind of effective target checks to be named after the respective optabs, so clz (without _ifn) or when for a specific mode, clzsi. I realize this clashes with the existing targets but can you check what they were introduced for and see whether your variant would be a better match? Note targets can also chose to implement ctz with a series of other operations, like generic expansion does, so even having an optab doesn't mean it is a "native" instruction supported by the target. > Bootstrapped and tested on aarch64-none-linux-gnu and x86_64-linux. > > gcc/ChangeLog: > > * doc/sourcebuild.texi (clz_ifn, ctz_ifn): Document. > > gcc/testsuite/ChangeLog: > > * lib/target-supports.exp (check_effective_target_clz_ifn) > (check_effective_target_ctz_ifn): New procedures. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/doc/sourcebuild.texi | 8 ++++++ > gcc/testsuite/lib/target-supports.exp | 38 +++++++++++++++++++++++++++ > 2 files changed, 46 insertions(+) > > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi > index 3aa9fcbb577..822e4df53a4 100644 > --- a/gcc/doc/sourcebuild.texi > +++ b/gcc/doc/sourcebuild.texi > @@ -2774,6 +2774,10 @@ Target supports a clz optab on long. > @item clzll > Target supports a clz optab on long long. > > +@item clz_ifn > +Target expands a @code{.CLZ} internal function call on @code{unsigned int} > +with an instruction pattern. > + > @item ctz > Target supports a ctz optab on int. > > @@ -2783,6 +2787,10 @@ Target supports a ctz optab on long. > @item ctzll > Target supports a ctz optab on long long. > > +@item ctz_ifn > +Target expands a @code{.CTZ} internal function call on @code{unsigned int} > +with an instruction pattern. > + > @item cmpccxadd > Target supports the execution of @code{cmpccxadd} instructions. > > diff --git a/gcc/testsuite/lib/target-supports.exp > b/gcc/testsuite/lib/target-supports.exp > index ae04b6a8daa..ad27992c6db 100644 > --- a/gcc/testsuite/lib/target-supports.exp > +++ b/gcc/testsuite/lib/target-supports.exp > @@ -10726,6 +10726,44 @@ proc check_effective_target_ctzll { } { > } "" ] > } > > +# Return 1 if the target expands a .CLZ call on unsigned int with an > +# instruction pattern. Niter analysis turns the loop into such a call > +# only in that case. > + > +proc check_effective_target_clz_ifn { } { > + return [check_no_messages_and_pattern clz_ifn "\\.CLZ \\(" > tree-optimized { > + int foo (unsigned int b) > + { > + int c = 0; > + while (b) > + { > + b >>= 1; > + c++; > + } > + return c; > + } > + } "-O2" ] > +} > + > +# Return 1 if the target expands a .CTZ call on unsigned int with an > +# instruction pattern. Niter analysis turns the loop into such a call > +# only in that case. > + > +proc check_effective_target_ctz_ifn { } { > + return [check_no_messages_and_pattern ctz_ifn "\\.CTZ \\(" > tree-optimized { > + int foo (unsigned int b) > + { > + int c = 0; > + while (b) > + { > + b <<= 1; > + c++; > + } > + return c; > + } > + } "-O2" ] > +} > + > # Return 1 if the target supports atomic operations on "long long" > # and can execute them. > # > -- > 2.54.0 (Apple Git-157) >
