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.

> > 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. 

So what would be the best way to resolve this?

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 

Reply via email to