Bug 97653 - [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
Summary: [11 Regression] Incorrect long double calculation with -mabi=ibmlongdouble
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 11.0
: P1 normal
Target Milestone: 11.0
Assignee: Michael Meissner
URL:
Keywords: wrong-code
Depends on: 97543
Blocks:
  Show dependency treegraph
 
Reported: 2020-10-31 08:57 UTC by Jonathan Wakely
Modified: 2021-04-20 09:45 UTC (History)
7 users (show)

See Also:
Host:
Target: powerpc64le-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-11-03 00:00:00


Attachments
Assembly code (1.16 KB, text/plain)
2020-10-31 08:58 UTC, Jonathan Wakely
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2020-10-31 08:57:21 UTC
GCC configured with --with-long-double-format=ieee produces incorrect results when compiling with -mabi=ibmlongdouble

This code (reduced from 26_numerics/random/knuth_b.cc in the libstdc++ testsuite) fails the assertion:

#include <assert.h>
int printf(const char*, ...);

unsigned long min() { return 1; }
unsigned long max() { return 2147483646; }

unsigned long k = 256;

unsigned long y = 1465645203;

unsigned long f()
{
  long double r = ((y - min()) / (max() - min() + 1.0L));
  assert( r < 1 );
  unsigned long j = k * ((y - min()) / (max() - min() + 1.0L));
  assert( j < k );
  return j;
}

int main()
{
  printf("%lu\n", f());
}


$ ~/gcc/ieee128/bin/gcc k.c -mno-gnu-attribute -mabi=ibmlongdouble && ./a.out
a.out: k.c:16: f: Assertion `j < k' failed.
Aborted (core dumped)


$ ~/gcc/ieee128/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/home/test/gcc/ieee128/bin/gcc
COLLECT_LTO_WRAPPER=/home/test/gcc/ieee128/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.0/lto-wrapper
Target: powerpc64le-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/test/gcc/ieee128/ --enable-libstdcxx-debug --disable-bootstrap --disable-multilib --disable-libvtv --with-system-zlib --without-isl --with-long-double-format=ieee --enable-languages=c,c++
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.0.0 20201030 (experimental) (GCC) 

This is an up to date Fedora 33 system:

# rpm -q glibc
glibc-2.32-1.fc33.ppc64le

# lscpu
Architecture:                    ppc64le
Byte Order:                      Little Endian
CPU(s):                          160
On-line CPU(s) list:             0-159
Thread(s) per core:              4
Core(s) per socket:              20
Socket(s):                       2
NUMA node(s):                    2
Model:                           2.2 (pvr 004e 1202)
Model name:                      POWER9, altivec supported
Frequency boost:                 enabled
CPU max MHz:                     3800.0000
CPU min MHz:                     2166.0000
L1d cache:                       1.3 MiB
L1i cache:                       1.3 MiB
L2 cache:                        10 MiB
L3 cache:                        200 MiB
NUMA node0 CPU(s):               0-79
NUMA node8 CPU(s):               80-159
Vulnerability Itlb multihit:     Not affected
Vulnerability L1tf:              Mitigation; RFI Flush, L1D private per thread
Vulnerability Mds:               Not affected
Vulnerability Meltdown:          Mitigation; RFI Flush, L1D private per thread
Vulnerability Spec store bypass: Mitigation; Kernel entry/exit barrier (eieio)
Vulnerability Spectre v1:        Mitigation; __user pointer sanitization, ori31 speculation barrier enabled
Vulnerability Spectre v2:        Mitigation; Indirect branch cache disabled, Software link stack flush
Vulnerability Srbds:             Not affected
Vulnerability Tsx async abort:   Not affected
Comment 1 Jonathan Wakely 2020-10-31 08:58:03 UTC
Created attachment 49479 [details]
Assembly code
Comment 2 Jonathan Wakely 2020-10-31 09:00:00 UTC
Without -mabilongdouble the result is correct.

If configured with --with-long-double-format=ibm the result is correct with any -mabi option.
Comment 3 Jonathan Wakely 2020-10-31 09:12:11 UTC

int printf(const char*, ...);

const unsigned long k = 256;

int main()
{
  long double r[] = { 0.1L, 0.2L, 0.5L, 0.9L };
  for (int i = 0; i < 4; ++i)
  {
    unsigned long j = k * r[i];
    printf("%lu * %Lf = %lu\n", k, r[i], j);
  }
}

$ ~/gcc/ieee128/bin/gcc k.c -mno-gnu-attribute -mabi=ibmlongdouble  -Wall && ./a.out
256 * 0.100000 = 256
256 * 0.200000 = 256
256 * 0.500000 = 256
256 * 0.900000 = 256
Comment 4 Michael Meissner 2020-11-03 19:58:24 UTC
You need the patch that fixes PR libgcc/97543, which is another side of the same coin.  PR 97543 was about making long double default to 64-bits, PR 97643 is about making long double default to IEEE 128-bit.

For both PRs, you need to make sure the modules that deal with IBM 128-bit values using -mabi=ibmlongdouble.  And also as a good measure, disable GNU attributes to prevent linker warnings.

Here is the patch that should be applied:
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/557413.html
Comment 5 Jonathan Wakely 2020-11-04 12:02:43 UTC
Yep, that fixes the testcases above, thanks. Retrying the libstdc++ tests ...
Comment 6 Jonathan Wakely 2020-12-08 14:09:04 UTC
This was committed, but with the wrong PR number so didn't get added here:


The master branch has been updated by Michael Meissner <meissner@gcc.gnu.org>:

https://gcc.gnu.org/g:9f1a6501994a2d18ec4fe2a6664637f48021b210

commit r11-5728-g9f1a6501994a2d18ec4fe2a6664637f48021b210
Author: Michael Meissner <meissner@linux.ibm.com>
Date:   Thu Dec 3 14:50:26 2020 -0500

    PowerPC: PR libgcc/97543 and libgcc/97643, fix long double issues
    
    If you use a compiler with long double defaulting to 64-bit instead of 128-bit
    with IBM extended double, you get linker warnings about mis-matches in the gnu
    attributes for long double (PR libgcc/97543).  Even if the compiler is
    configured to have long double be 64 bit as the default with the configuration
    option '--without-long-double-128' you get the warnings.
    
    You also get the same issues if you use a compiler with long double defaulting
    to IEEE 128-bit instead of IBM extended double (PR libgcc/97643).
    
    The issue is the way libgcc.a/libgcc.so is built.  Right now when building
    libgcc under Linux, the long double size is set to 128-bits when building
    libgcc.  However, the gnu attributes are set, leading to the warnings.
    
    One feature of the current GNU attribute implementation is if you have a shared
    library (such as libgcc_s.so), the GNU attributes for the shared library is an
    inclusive OR of all of the objects within the library.  This means if any
    object file that uses the -mlong-double-128 option and uses long double, the GNU
    attributes for the library will indicate that it uses 128-bit IBM long
    doubles.  If you have a static library, you will get the warning only if you
    actually reference an object file  with the attribute set.
    
    This patch does two things:
    
        1)  All of the object files that support IBM 128-bit long doubles
            explicitly set the ABI to IBM extended double.
    
        2)  I turned off GNU attributes for building the shared library or for
            building the IBM 128-bit long double support.
    
    libgcc/
    2020-12-03  Michael Meissner  <meissner@linux.ibm.com>
    
            PR libgcc/97543
            PR libgcc/97643
            * config/rs6000/t-linux (IBM128_STATIC_OBJS): New make variable.
            (IBM128_SHARED_OBJS): New make variable.
            (IBM128_OBJS): New make variable.  Set all objects to use the
            explicit IBM format, and disable gnu attributes.
            (IBM128_CFLAGS): New make variable.
            (gcc_s_compile): Add -mno-gnu-attribute to all shared library
            modules.
Comment 7 Michael Meissner 2021-01-21 01:44:42 UTC
Bug fixed with the December 3rd, 2020 check-in to the master branch.  We do not expect GCC 10 to build with IEEE 128-bit long double default, so we don't need a backport at this time.
Comment 8 Jonathan Wakely 2021-03-23 18:07:44 UTC
Reopening as I'm still seeing this (or it's returned).
Comment 9 Jonathan Wakely 2021-03-23 18:08:35 UTC
[test@ibm-p8-cluster-02 ~]$ cat 97653.c
int printf(const char*, ...);

const unsigned long k = 256;

int main()
{
  long double r[] = { 0.1L, 0.2L, 0.5L, 0.9L };
  for (int i = 0; i < 4; ++i)
  {
    unsigned long j = k * r[i];
    printf("%lu * %Lf = %lu\n", k, r[i], j);
  }
}
[test@ibm-p8-cluster-02 ~]$ ~/gcc/ieee/bin/gcc 97653.c  -mno-gnu-attribute -mabi=ibmlongdouble  -Wall -static-libgcc -v  && ./a.out
Using built-in specs.
COLLECT_GCC=/home/test/gcc/ieee/bin/gcc
COLLECT_LTO_WRAPPER=/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/lto-wrapper
Target: powerpc64le-unknown-linux-gnu
Configured with: /home/test/src/gcc/configure --prefix=/home/test/gcc/ieee --disable-multilib --disable-bootstrap --enable-languages=c++ --disable-pch --disable-nls --without-isl --with-long-double-format=ieee : (reconfigured) /home/test/src/gcc/configure --prefix=/home/test/gcc/ieee --disable-multilib --disable-bootstrap --enable-languages=c++ --disable-pch --disable-nls --without-isl --with-long-double-format=ieee
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.0.1 20210323 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-mno-gnu-attribute' '-mabi=ibmlongdouble' '-Wall' '-static-libgcc' '-v' '-dumpdir' 'a-'
 /home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/cc1 -quiet -v 97653.c -quiet -dumpdir a- -dumpbase 97653.c -dumpbase-ext .c -mno-gnu-attribute -mabi=ibmlongdouble -Wall -version -o /tmp/ccNHNZzj.s
GNU C17 (GCC) version 11.0.1 20210323 (experimental) (powerpc64le-unknown-linux-gnu)
        compiled by GNU C version 11.0.0 20210225 (Red Hat 11.0.0-0), GMP version 6.2.0, MPFR version 4.1.0-p9, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
ignoring nonexistent directory "/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/../../../../powerpc64le-unknown-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/include
 /usr/local/include
 /home/test/gcc/ieee/include
 /home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/include-fixed
 /usr/include
End of search list.
GNU C17 (GCC) version 11.0.1 20210323 (experimental) (powerpc64le-unknown-linux-gnu)
        compiled by GNU C version 11.0.0 20210225 (Red Hat 11.0.0-0), GMP version 6.2.0, MPFR version 4.1.0-p9, MPC version 1.2.1, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: ab29af0a0f73449cd280c2751cbad267
COLLECT_GCC_OPTIONS='-mno-gnu-attribute' '-mabi=ibmlongdouble' '-Wall' '-static-libgcc' '-v' '-dumpdir' 'a-'
 as -v -a64 -mpower8 -mlittle -o /tmp/cc4MmQYf.o /tmp/ccNHNZzj.s
GNU assembler version 2.35.1 (ppc64le-redhat-linux) using BFD version version 2.35.1-41.fc34
COMPILER_PATH=/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/:/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/:/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/:/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/:/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/
LIBRARY_PATH=/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/:/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-mno-gnu-attribute' '-mabi=ibmlongdouble' '-Wall' '-static-libgcc' '-v' '-dumpdir' 'a.'
 /home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/collect2 -plugin /home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/liblto_plugin.so -plugin-opt=/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-linux-gnu/11.0.1/lto-wrapper -plugin-opt=-fresolution=/tmp/ccwamb6Q.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh --eh-frame-hdr -V -m elf64lppc -dynamic-linker /lib64/ld64.so.2 /lib/../lib64/crt1.o /lib/../lib64/crti.o /home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/crtbegin.o -L/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1 -L/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/../../.. /tmp/cc4MmQYf.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /home/test/gcc/ieee/lib/gcc/powerpc64le-unknown-linux-gnu/11.0.1/crtend.o /lib/../lib64/crtn.o
GNU ld version 2.35.1-41.fc34
  Supported emulations:
   elf64lppc
   elf32lppc
   elf32lppclinux
   elf32lppcsim
   elf64ppc
   elf32ppc
   elf32ppclinux
   elf32ppcsim
   elf32_spu
   i386pep
   i386pe
   elf64bpf
COLLECT_GCC_OPTIONS='-mno-gnu-attribute' '-mabi=ibmlongdouble' '-Wall' '-static-libgcc' '-v' '-dumpdir' 'a.'
256 * 0.100000 = 256
256 * 0.200000 = 256
256 * 0.500000 = 256
256 * 0.900000 = 256
Comment 10 Jakub Jelinek 2021-03-30 11:28:28 UTC
(In reply to Jonathan Wakely from comment #9)
> [test@ibm-p8-cluster-02 ~]$ cat 97653.c
> int printf(const char*, ...);
> 
> const unsigned long k = 256;
> 
> int main()
> {
>   long double r[] = { 0.1L, 0.2L, 0.5L, 0.9L };
>   for (int i = 0; i < 4; ++i)
>   {
>     unsigned long j = k * r[i];
>     printf("%lu * %Lf = %lu\n", k, r[i], j);
>   }
> }
> [test@ibm-p8-cluster-02 ~]$ ~/gcc/ieee/bin/gcc 97653.c  -mno-gnu-attribute
> -mabi=ibmlongdouble  -Wall -static-libgcc -v  && ./a.out
> Using built-in specs.
> COLLECT_GCC=/home/test/gcc/ieee/bin/gcc
> COLLECT_LTO_WRAPPER=/home/test/gcc/ieee/libexec/gcc/powerpc64le-unknown-
> linux-gnu/11.0.1/lto-wrapper
> Target: powerpc64le-unknown-linux-gnu
> Configured with: /home/test/src/gcc/configure --prefix=/home/test/gcc/ieee
> --disable-multilib --disable-bootstrap --enable-languages=c++ --disable-pch
> --disable-nls --without-isl --with-long-double-format=ieee : (reconfigured)
> /home/test/src/gcc/configure --prefix=/home/test/gcc/ieee --disable-multilib
> --disable-bootstrap --enable-languages=c++ --disable-pch --disable-nls
> --without-isl --with-long-double-format=ieee

Is your compiler intentionally configured without --with-long-double-128, i.e. are you intentionally testing the double == long double case?
I can reproduce the weirdo output only when I build with such configured cross-compiler (without -mlong-double-128) and link on gcc112 on CompilerFarm with the system compiler (which defaults to -mlong-double-128).
Comment 11 Jonathan Wakely 2021-03-30 11:44:27 UTC
(In reply to Jakub Jelinek from comment #10)
> Is your compiler intentionally configured without --with-long-double-128,

No.

> i.e. are you intentionally testing the double == long double case?

Not intentionally, isn't that implied by --with-long-double-format=ieee ?!

That's what the docs seem to say:

  Specify whether long double uses the IBM extended double format or the IEEE
  128-bit floating point format on PowerPC Linux systems.
  [...]
  If you use the --with-long-double-64 configuration option, the
  --with-long-double-format=ibm and --with-long-double-format=ieee options
  are ignored.

That tells me that using --with-long-double-format={ibm,ieee} chooses *which* of the 128-bit long double formats you want, and so --with-long-double-128 is implied. Maybe I'm reading it wrong.

Let me test again. Maybe I was using the system libgcc_s.so not the one configured as --with-long-double-format=ieee (but I would still expect that to work as the system one is from F34's gcc-11).
Comment 12 Jonathan Wakely 2021-03-30 11:49:36 UTC
Also, the docs for --with-long-double-128 say

  When neither of these configure options are used, the default will be 128-bit
  long double when built against GNU C Library 2.4 and later, 64-bit long double
  otherwise.
Comment 13 Jakub Jelinek 2021-03-30 12:02:01 UTC
(In reply to Jonathan Wakely from comment #11)
> That tells me that using --with-long-double-format={ibm,ieee} chooses
> *which* of the 128-bit long double formats you want, and so
> --with-long-double-128 is implied. Maybe I'm reading it wrong.

At least from seeing what my cross-compiler does it is not implied.
If I compile with those 
-mno-gnu-attribute -mabi=ibmlongdouble
options, scp assembly to gcc112, compile there (system compiler defaults to -mlong-double-128), it fails, if I compile locally with
-mno-gnu-attribute -mabi=ibmlongdouble -mlong-double-128
and scp and do the same, it works.
And I can't reproduce on gcc112 with 11.0.0 20210126 gcc natively built there which defaults to -mlong-double-128:
~/gcc/obj31/gcc/xgcc -B ~/gcc/obj31/gcc/ -B ~/gcc/obj31/powerpc64le-unknown-linux-gnu/libgcc/ -o pr97653{,.c} -static-libgcc -mno-gnu-attribute -mabi=ibmlongdouble
./pr97653
256 * 0.100000 = 25
256 * 0.200000 = 51
256 * 0.500000 = 128
256 * 0.900000 = 230
Comment 14 Jakub Jelinek 2021-03-31 10:58:21 UTC
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.
Comment 15 Jakub Jelinek 2021-03-31 11:59:55 UTC
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).
Comment 16 Jakub Jelinek 2021-03-31 12:24:20 UTC
Actually, there is code to handle that already, just with typos and omissions in it.
So perhaps better:
2021-03-31  Jakub Jelinek  <jakub@redhat.com>

	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-linux	2021-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)
Comment 17 GCC Commits 2021-04-03 08:06:29 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:cda41ce0e8414aec59e6b9fbe645d96e6e8193e2

commit r11-7969-gcda41ce0e8414aec59e6b9fbe645d96e6e8193e2
Author: Jakub Jelinek <jakub@redhat.com>
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  <jakub@redhat.com>
    
            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.
Comment 18 Jakub Jelinek 2021-04-03 08:16:38 UTC
Fixed on the trunk.
Comment 19 GCC Commits 2021-04-20 09:45:37 UTC
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:8642b73a0f0df1f8e1e2d2102d67a76f8ed0a255

commit r10-9720-g8642b73a0f0df1f8e1e2d2102d67a76f8ed0a255
Author: Jakub Jelinek <jakub@redhat.com>
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  <jakub@redhat.com>
    
            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)