Re: 'Call clzl check' breaks cross compilation (was: PATCH 13/22] Coarray caf_shmem final patch set)
Richard Biener <[email protected]>
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <CAFiYyc3SynpZbNBSncZe-L-Oa0+N7A48_+Nfj1Tz=odN4HAzbw@mail.gmail.com> |
On Fri, Feb 27, 2026 at 1:40 PM Andre Vehreschild <[email protected]> wrote: > > Hi Richard, > > > > > > > --- a/libgfortran/acinclude.m4 > > > > > > +++ b/libgfortran/acinclude.m4 > > > > > ... > > > > > > +AC_DEFUN([LIBGFOR_CHECK_SANE_BUILTIN_CLZL], [ > > > > > > + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ > > > > > > + int main() > > > > > > + { > > > > > > + return __builtin_clzl(256) != 8; > > > > > > + }]], [[]])], > > > > > > + AC_DEFINE(HAVE_SANE_BUILTIN_CLZL, 1, > > > > > > + [Define if __builtin_clzl behaves as expected.]) > > > > > > + AM_CONDITIONAL([HAVE_SANE_BUILTIN_CLZL],true), > > > > > > + [AM_CONDITIONAL([HAVE_SANE_BUILTIN_CLZL],false)]) > > > > > > +]) > > > > > > > > What does this test anyway? clzl (256) should not return 8 but 55. > > > > Did you want to check c_T_zl here? I suggest to simply drop this given > > > > it's broken? > > At the point of use of clzl we want to sort requests for memory blocks into > buckets by size. The clzl is intended to give the most significant bit the size > requested fits into. To my understanding of the mnenonic clzl does exactly > that. And using __builtin_clzl was my way to prevent me from using an asm {} > block. > > Therefore clzl(256) should deliver 8 because 1<<8 is 256. On some platforms > clzl delivers 55 like you pointed out, but that is of no use to use. No, clzl (256ul) should be 55, because 1 << (64 - 55 - 1) is 256. > > > I'm also not convinced by > > > > > > static size_t > > > next_power_of_two (size_t size) > > > { > > > #ifdef HAVE_SANE_BUILTIN_CLZL > > > assert (size); > > > #if (__INTPTR_WIDTH__ == 64) > > > return 1 << (VOIDP_BITS - __builtin_clzl (size - 1)); > > > #else > > > > > > which uses VOIDP_BITS, not 'unsigned long' bits, and it seems to > > > correlate size_t width with unsigned long width by using INTPTR_WIDTH. > > > What do you do for long == 32bits targets (windows) which have 64bit > > > pointers? You want to use __builtin_clzll there I think. > > Er. INTPTR_WIDTH is the with of a pointer on the platform in question. Is it > not? I could have used VOIDPTR_WIDTH or REALPTR_WIDTH, right? Or to put it the > other way around: For platforms that have 64 bit pointer width, how do I detect > them in a portable way? > > > > > > > Of course the FP fallback > > > > > > #else > > > return 1 << (int)ceil(log2(size)); > > > #endif > > > > > > is also a bit questionable. See gcc/hwint.{h,cc} for ceil_log2 on > > > uint64_t. > > > > That said, libgfortran is always built by the just built GCC, so > > __builtin_clzll should always be available and correct. Just use it. > > That would be nice, but is not the case on windows, where clzl (256) returns 55 > which is why we do all this fuss. Which is correct. So the fuss must be because of sth else. > So what would be the best way to resolve this? As said, simply do static size_t next_power_of_two (size_t size) { return (size_t)1 << (__SIZEOF_LONG_LONG__ * 8 - __builtin_clzll (size - 1)); } Richard. > Regards, > Andre > > > > > Richard. > > > > > > > > Richard. > > > > > > > > > > > Richard. > > > > > > > > > This fails with: > > > > > > > > > > configure: error: in > > > > > build-gcc-trunk-offload-amdgcn/amdgcn-amdhsa/libgfortran' configure: > > > > > error: cannot run test program while cross compiling > > > > > > > > > > Namely, the generated configure file contains: > > > > > > # Check if __builtin_clzl behaves (it doesn't on Msys2/ucrt64). > > > > > > > > > > > > if test "$cross_compiling" = yes; then : > > > > > > { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" > > > > > > >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} > > > > > > as_fn_error $? "cannot run test program while cross compiling > > > > > > See \`config.log' for more details" "$LINENO" 5; } > > > > > > else > > > > > > > > > > In the code, you can either use code like: > > > > > if test "$cross_compiling" != no; then > > > > > for the current code and the following in an else branch. > > > > > Or just the following: > > > > > > > > > > case "${host}" in > > > > > *-*-mingw32*) > > > > > .... > > > > > ;; > > > > > *) > > > > > .... > > > > > ;; > > > > > esac > > > > > > > > > > In any case, AC_RUN_IFELSE is wrong for cross compilation, > > > > > AC_COMPILE_IFELSE is fine. > > > > > > > > > > Tobias > > > > > > > > -- > Andre Vehreschild * Email: vehre ad gmx dot de