[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 --- Comment #19 from CVS Commits --- The releases/gcc-10 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:8642b73a0f0df1f8e1e2d2102d67a76f8ed0a255 commit r10-9720-g8642b73a0f0df1f8e1e2d2102d67a76f8ed0a255 Author: Jakub Jelinek Date: Sat Apr 3 10:05:32 2021 +0200 rs6000: Fix up libgcc ABI when built with --with-long-double-format=ieee [PR97653] __floatunditf and __fixtfdi and a couple of other libgcc{.a,_s.so} entrypoints for backwards compatibility should mean IBM double double handling (i.e. IFmode), gcc emits such calls for that format and form IEEE long double emits *kf* instead. When gcc is configured without --with-long-double-format=ieee , everything is fine, but when it is not, we need to compile those libgcc sources with -mno-gnu-attribute -mabi=ibmlongdouble. The following snippet in libgcc/config/rs6000/t-linux was attempting to ensure that, and for some routines it works fine (e.g. for _powitf2). But, due to 4 different types of bugs it doesn't work for most of those functions, which means that in --with-long-double-format=ieee configured gcc those *tf* entrypoints instead handle the long double arguments as if they were KFmode. The bugs are: 1) the first few objs properly use $(objext) as suffix, but several other contain a typo and use $(object) instead, which is a variable that isn't set to anything, so we don't add .o etc. extensions 2) while unsigned fix are properly called _fixuns*, unsigned float are called _floatun* (without s), but the var was using there the extra s and so didn't match 3) the variable didn't cover any of the TF <-> TI conversions, only TF <-> DI conversions 4) nothing in libgcc_s.so was handled, as those object files are called *_s.o rather than *.o and IBM128_SHARED_OBJS used wrong syntax of the GNU make substitution reference, which should be $(var:a=b) standing for $(patsubst a,b,$(var)) but it used $(var:a:b) instead 2021-04-03 Jakub Jelinek PR target/97653 * config/rs6000/t-linux (IBM128_STATIC_OBJS): Fix spelling, use $(objext) instead of $(object). Use _floatunditf instead of _floatunsditf. Add tf <-> ti conversion objects. (IBM128_SHARED_OBJS): Use proper substitution reference syntax. (cherry picked from commit cda41ce0e8414aec59e6b9fbe645d96e6e8193e2)
[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 Jakub Jelinek changed: What|Removed |Added Resolution|--- |FIXED Status|REOPENED|RESOLVED --- Comment #18 from Jakub Jelinek --- Fixed on the trunk.
[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 --- Comment #17 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:cda41ce0e8414aec59e6b9fbe645d96e6e8193e2 commit r11-7969-gcda41ce0e8414aec59e6b9fbe645d96e6e8193e2 Author: Jakub Jelinek Date: Sat Apr 3 10:05:32 2021 +0200 rs6000: Fix up libgcc ABI when built with --with-long-double-format=ieee [PR97653] __floatunditf and __fixtfdi and a couple of other libgcc{.a,_s.so} entrypoints for backwards compatibility should mean IBM double double handling (i.e. IFmode), gcc emits such calls for that format and form IEEE long double emits *kf* instead. When gcc is configured without --with-long-double-format=ieee , everything is fine, but when it is not, we need to compile those libgcc sources with -mno-gnu-attribute -mabi=ibmlongdouble. The following snippet in libgcc/config/rs6000/t-linux was attempting to ensure that, and for some routines it works fine (e.g. for _powitf2). But, due to 4 different types of bugs it doesn't work for most of those functions, which means that in --with-long-double-format=ieee configured gcc those *tf* entrypoints instead handle the long double arguments as if they were KFmode. The bugs are: 1) the first few objs properly use $(objext) as suffix, but several other contain a typo and use $(object) instead, which is a variable that isn't set to anything, so we don't add .o etc. extensions 2) while unsigned fix are properly called _fixuns*, unsigned float are called _floatun* (without s), but the var was using there the extra s and so didn't match 3) the variable didn't cover any of the TF <-> TI conversions, only TF <-> DI conversions 4) nothing in libgcc_s.so was handled, as those object files are called *_s.o rather than *.o and IBM128_SHARED_OBJS used wrong syntax of the GNU make substitution reference, which should be $(var:a=b) standing for $(patsubst a,b,$(var)) but it used $(var:a:b) instead 2021-04-03 Jakub Jelinek PR target/97653 * config/rs6000/t-linux (IBM128_STATIC_OBJS): Fix spelling, use $(objext) instead of $(object). Use _floatunditf instead of _floatunsditf. Add tf <-> ti conversion objects. (IBM128_SHARED_OBJS): Use proper substitution reference syntax.
[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 --- Comment #16 from Jakub Jelinek --- Actually, there is code to handle that already, just with typos and omissions in it. So perhaps better: 2021-03-31 Jakub Jelinek PR target/97653 * config/rs6000/t-linux (IBM128_STATIC_OBJS): Fix spelling, use $(objext) instead of $(object). Use _floatunditf instead of _floatunsditf. Add tf <-> ti conversion objects. --- libgcc/config/rs6000/t-linux.jj 2020-12-04 08:08:06.556434569 +0100 +++ libgcc/config/rs6000/t-linux2021-03-31 14:20:50.953852864 +0200 @@ -11,9 +11,11 @@ HOST_LIBGCC2_CFLAGS += -mno-minimal-toc # the IBM extended double format. Also turn off gnu attributes on the static # modules. IBM128_STATIC_OBJS = ibm-ldouble$(objext) _powitf2$(objext) \ - ppc64-fp$(objext) _divtc3$(object) _multc3$(object) \ - _fixtfdi$(object) _fixunstfdi$(object) \ - _floatditf$(objext) _floatunsditf$(objext) + ppc64-fp$(objext) _divtc3$(objext) _multc3$(objext) \ + _fixtfdi$(objext) _fixunstfdi$(objext) \ + _floatditf$(objext) _floatunditf$(objext) \ + _fixtfti$(objext) _fixunstfti$(objext) \ + _floattitf$(objext) _floatuntitf$(objext) IBM128_SHARED_OBJS = $(IBM128_STATIC_OBJS:$(objext):_s$(objext)) IBM128_OBJS= $(IBM128_STATIC_OBJS) $(IBM128_SHARED_OBJS)
[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 --- Comment #15 from Jakub Jelinek --- So, just completely untested possibility: --- libgcc/config/rs6000/t-float128.jj 2021-03-30 18:11:52.572091848 +0200 +++ libgcc/config/rs6000/t-float128 2021-03-31 13:55:47.199756547 +0200 @@ -90,8 +90,16 @@ ibm128_dec_objs = $(addsuffix $(objext) FP128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble IBM128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble +ibm128_siditi_tf_funcs = \ + $(foreach f,$(sifuncs) $(difuncs) $(tifuncs),$(if $(findstring tf,$f),$f)) +ibm128_siditi_tf_objs = $(patsubst %,%$(objext),$(ibm128_siditi_tf_funcs)) +ifeq ($(enable_shared),yes) +ibm128_siditi_tf_objs += $(patsubst %,%_s$(objext),$(ibm128_siditi_tf_funcs)) +endif + $(fp128_dec_objs) : INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL) $(ibm128_dec_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL) +$(ibm128_siditi_tf_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL) $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep) @src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \ (though IBM128_CFLAGS_DECIMAL is misnamed for those because it has nothing to do with decimal).
[Bug target/97653] [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97653 Jakub Jelinek changed: What|Removed |Added Priority|P3 |P1 Target Milestone|--- |11.0 Summary|Incorrect long double |[11 Regression] Incorrect |calculation with|long double calculation |-mabi=ibmlongdouble |with -mabi=ibmlongdouble --- Comment #14 from Jakub Jelinek --- So, what I missed was that my gcc on gccfarm has been configured without the --with-long-double-format=ieee option, but Jonathan's gcc has been configured with that option. When compiling the #c9 testcase with -mabi=ibmlongdouble , both on compiler that was configured --with-long-double-format=ieee and on compiler that was configured without it, gcc emits calls to __floatunditf __gcc_qmul __fixunstfdi while when compiling the testcase with -mabi=ieeelongdouble , on both compilers it emits calls to __floatundikf __mulkf3 __fixunskfdi So far so good. The problem I see is that depending on how gcc has been configured, libgcc changes. In gcc configured without --with-long-double-format=ieee , I see __floatunditf calling __gcc_qadd and __gcc_qmul, so looks that the tf it talks about is IBM double double aka if. But looking at __floatunditf on --with-long-double-format=ieee configured gcc, I see it calls __floatundikf, __mulkf3 and __addkf3. So it looks both like ABI incompatibility and something else weird going on, because if it was treating the tf as kf, why would it call __floatundikf and something on top of that? Skimming other __*tf* functions in libgcc.a in --with-long-double-format=ieee configured gcc, __powitf2 calls __gcc_q{mul,div}, so might be ok, __eprintf calls __fprintfieee128 rather than fprintf from the other gcc, but maybe it is ok because it passes to fprintf only arguments that are not floating point. __fixtfdi calls __lekf2, so looks ABI incompatible, ditto __fixunstfdi, __floatditf calls __gcc_q{mul,add}, so might be ok, __fixtfti calls __lekf2, so looks ABI incompatible, ditto __fixunstfti, __floattitf also looks broken, ditto __floatuntitf. Ignoring the decimal stuff (_dpd*). So, if we want backwards ABI compatibility, I'm afraid when building libgcc, at least the *tf* entry points, they should be built with explicit -mabi=ibmlongdouble or otherwise ensure it is using IFmode rather than TFmode stuff.