Jakub Jelinek <ja...@redhat.com> writes: > On Fri, Mar 10, 2023 at 11:50:39AM +0000, Richard Sandiford wrote: >> > Will test it momentarily (including the patch it depends on): > > Note, testing still pending, I'm testing in a Fedora scratch build > and that is quite slow (lto bootstrap and the like). > >> A naive question: >> >> > --- libgcc/config/aarch64/t-softfp.jj 2022-11-14 13:35:34.527155682 >> > +0100 >> > +++ libgcc/config/aarch64/t-softfp 2023-03-10 12:19:58.668882041 +0100 >> > @@ -1,9 +1,10 @@ >> > softfp_float_modes := tf >> > softfp_int_modes := si di ti >> > -softfp_extensions := sftf dftf hftf >> > -softfp_truncations := tfsf tfdf tfhf >> > +softfp_extensions := sftf dftf hftf bfsf >> > +softfp_truncations := tfsf tfdf tfhf tfbf dfbf sfbf hfbf >> >> Is bfsf used for conversions in which sf is the ultimate target, >> as opposed to operations that convert bf to sf and then do something >> with the sf? And so the libfunc is needed to raise exceptions, which in >> more complex operations can be left to the following sf operation? >> >> Do we still optimise to a shift for -ffinite-math-only? > > Reminds me I should have added testcase coverage for PR107703, will post > it momentarily. > > But, consider say: > template <typename T, typename F> > [[gnu::noipa]] T cvt (F f) > { > return T (F (f)); > } > > void > foo () > { > cvt <_Float32, __bf16> (0.0bf16); > cvt <_Float64, __bf16> (0.0bf16); > cvt <_Float128, __bf16> (0.0bf16); > cvt <signed char, __bf16> (0.0bf16); > cvt <signed short, __bf16> (0.0bf16); > cvt <int, __bf16> (0.0bf16); > cvt <long long, __bf16> (0.0bf16); > cvt <__int128, __bf16> (0.0bf16); > } > > This emits on x86_64 -O2: > /usr/src/gcc/obj/gcc/cc1plus -quiet -O2 1111.C; grep call.*__ 1111.s > call __extendbfsf2 > call __extendbfsf2 > call __extendbfsf2 > call __extendsftf2 > call __fixsfti > where the first call is in cvt <_Float32, __bf16> is really needed, > admittedly the second 2 calls could be replaced by shifts but aren't right > now (we expand BF -> DF as BF -> SF -> DF and because sNaN would be already > diagnosed on the SF -> DF conversion if BF -> SF is done with shift, I think > it would be ok; similarly for BF -> TF). All the others (BF -> ?I) are > expanded as BF -> SF using shift and then SF -> ?I. With -O2 -ffast-math > /usr/src/gcc/obj/gcc/cc1plus -quiet -O2 -ffast-math 1111.C; grep call.*__ > 1111.s > call __extendsftf2 > call __fixsfti > so all the BF -> SF conversions are then done using shifts. > And aarch64 is exactly the same: > ./cc1plus -quiet -nostdinc -O2 1111.C; grep bl.*__[ef] 1111.s > bl __extendbfsf2 > bl __extendbfsf2 > bl __extendbfsf2 > bl __extendsftf2 > bl __fixsfti > ./cc1plus -quiet -nostdinc -O2 -ffast-math 1111.C; grep bl.*__[ef] 1111.s > bl __extendsftf2 > bl __fixsfti
Thanks, sounds good. In some ways it's ironic that, in a bf->df conversion, it's the bf->sf that needs a call, and the sf->df can be done inline, given that one of the purposes of bf16 was to provide cheap conversions to float. And similarly that bf->sf is more expensive than sf->df. But that's not the patch's fault. Rather than have an out-of-line call, would it be possible to synthesise the checking inline by making bf->sf do a following sf->df conversion, even when the df result is not used? It would obviously need to be kept alive somehow (not sure how). Richard