This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/24998] [4.2 Regression] Build failure on sparc-sun-solaris2.9/arm: undefined symbol __floatunsitf



------- Comment #9 from joseph at codesourcery dot com  2005-11-25 02:51 -------
Subject:  Patch for sparc-solaris build failure

This patch fixes some of the problems associated with the use of
libcalls for unsigned-to-floating conversions (bug 24998).  The
underlying problem was that my patch did not allow for targets which
defined their own libcall names, referring to functions in libc.

It does not address the powerpc64-linux problem (where
config/rs6000/ppc64-fp.c needs unsigned functions added); I understand
from IRC that someone has an unsubmitted patch for that already.  It
does not address the arm-netbsdelf problem (__floatsidf in libc),
which really needs to be addressed by someone who can test that
platform; likewise any other platform with the GNU names in libc.

Of the platforms using libcalls to libc, it fixes the issue for SPARC
(_Q_utoq specified in the ABI, _Q_ulltoq from the Solaris libc) and
PowerPC (_q_utoq in the ABI; for some reason glibc's
sysdeps/powerpc/soft-fp/q_utoq.c defines _q_uitoq but this looks like
a bug given the ABI and given that the Versions file says _q_utoq).
It doesn't fix the issue for ia64-hpux, which I intend to address in a
followup patch (the HP-UX libc has _U_Qfcnvxuf_dbl_to_quad for
unsigned DImode to TFmode conversion, but nothing for unsigned SImode
to TFmode conversion so I'll add a C wrapper).  I can't test hppa-hpux
right now though the issues are probably similar.  In the cases of
MIPS and FRV I hope the relevant maintainers can help.  The MIPS issue
seems only to be with mips16.S which needs implementations of the
relevant functions.  The FRV issue is that there are trivial C
implementations of the form

double __uitod (unsigned int a)
{
  return a;
}

but unlike for the signed functions there is nothing to make the
compiler call those names; if the intention was for these functions to
use the wrapper around a signed libcall the compiler formerly
generated, the right approach (given that this seems to be a
soft-float target) might be to remove these trivial implementations
and instead treat them just like the signed functions.

The tests are much bigger than the rest of the patch, and I hope for
the most part more thorough than gcc.c-torture/execute/conversion.c
which tests similar things (and gets largely optimized away at higher
optimization levels).

If one of the included testcases fails on your platform because of
undefined references to __floatun*, and it does not have a
corresponding undefined reference to the corresponding signed
conversion function without "un" in the name, add a note to bug 24998.
If it fails for any other reason indicating a bug in GCC, open an
appropriate new bug if there isn't one already (I filed bug 25028 for
a problem with TImode conversions being broken, shown up by the
testcases).  Some tests may fail because of external issues: the
__float128 tests are XFAILed on x86/x86_64 because they need an
external library implementing the TFmode functions (but when the fixes
are complete they should work OK on ia64-hpux which has enough
functions in libc).

I've verified that this patch makes a sparc-sun-solaris2.8 build go
beyond where it previously failed, and tested the new testcases for
syntax and XFAILs on x86_64-unknown-linux-gnu.  OK to commit?

2005-11-25  Joseph S. Myers  <joseph@codesourcery.com>

        PR middle-end/24998
        * config/rs6000/rs6000.c (rs6000_init_libfuncs): Use _q_utoq for
        unsigned conversions from SImode to TFmode.
        * config/sparc/sparc.c (sparc_init_libfuncs): Use _Q_utoq and
        _Q_ulltoq for unsigned conversions from SImode and DImode to
        TFmode.

testsuite:
2005-11-25  Joseph S. Myers  <joseph@codesourcery.com>

        PR middle-end/24998
        * gcc.dg/torture/fp-int-convert-float.c,
        gcc.dg/torture/fp-int-convert-double.c,
        gcc.dg/torture/fp-int-convert-long-double.c,
        gcc.dg/torture/fp-int-convert-timode.c,
        gcc.dg/torture/fp-int-convert-float80.c,
        gcc.dg/torture/fp-int-convert-float80-timode.c,
        gcc.dg/torture/fp-int-convert-float128.c,
        gcc.dg/torture/fp-int-convert-float128-timode.c,
        gcc.dg/torture/fp-int-convert.h: New files.

diff -rupN GCC.orig/gcc/config/rs6000/rs6000.c GCC/gcc/config/rs6000/rs6000.c
--- GCC.orig/gcc/config/rs6000/rs6000.c 2005-11-23 14:11:11.000000000 +0000
+++ GCC/gcc/config/rs6000/rs6000.c      2005-11-24 23:34:31.000000000 +0000
@@ -9078,6 +9078,7 @@ rs6000_init_libfuncs (void)
       set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
       set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
       set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
+      set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
     }
 }

diff -rupN GCC.orig/gcc/config/sparc/sparc.c GCC/gcc/config/sparc/sparc.c
--- GCC.orig/gcc/config/sparc/sparc.c   2005-10-28 23:33:40.000000000 +0000
+++ GCC/gcc/config/sparc/sparc.c        2005-11-24 23:40:27.000000000 +0000
@@ -7707,12 +7707,14 @@ sparc_init_libfuncs (void)
       set_conv_libfunc (sfix_optab,   SImode, TFmode, "_Q_qtoi");
       set_conv_libfunc (ufix_optab,   SImode, TFmode, "_Q_qtou");
       set_conv_libfunc (sfloat_optab, TFmode, SImode, "_Q_itoq");
+      set_conv_libfunc (ufloat_optab, TFmode, SImode, "_Q_utoq");

       if (DITF_CONVERSION_LIBFUNCS)
        {
          set_conv_libfunc (sfix_optab,   DImode, TFmode, "_Q_qtoll");
          set_conv_libfunc (ufix_optab,   DImode, TFmode, "_Q_qtoull");
          set_conv_libfunc (sfloat_optab, TFmode, DImode, "_Q_lltoq");
+         set_conv_libfunc (ufloat_optab, TFmode, DImode, "_Q_ulltoq");
        }

       if (SUN_CONVERSION_LIBFUNCS)
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c      
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-double.c    2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test floating-point conversions.  Standard types and double.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+  TEST_I_F(signed char, unsigned char, double, DBL_MANT_DIG);
+  TEST_I_F(signed short, unsigned short, double, DBL_MANT_DIG);
+  TEST_I_F(signed int, unsigned int, double, DBL_MANT_DIG);
+  TEST_I_F(signed long, unsigned long, double, DBL_MANT_DIG);
+  TEST_I_F(signed long long, unsigned long long, double, DBL_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c       
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float.c     2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test floating-point conversions.  Standard types and float.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+  TEST_I_F(signed char, unsigned char, float, FLT_MANT_DIG);
+  TEST_I_F(signed short, unsigned short, float, FLT_MANT_DIG);
+  TEST_I_F(signed int, unsigned int, float, FLT_MANT_DIG);
+  TEST_I_F(signed long, unsigned long, float, FLT_MANT_DIG);
+  TEST_I_F(signed long long, unsigned long long, float, FLT_MANT_DIG);
+  exit (0);
+}
diff -rupN
GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c     
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode.c  
2005-11-25 02:27:44.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test floating-point conversions.  __float128 type with TImode.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
+/* { dg-xfail-if "" { i?86-*-* x86_64-*-* } { "*" } { "" } } */
+/* { dg-options "" } */
+/* { dg-options "-mmmx" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-mmmx" { target { x86_64-*-* && ilp32 } } } */
+
+#include "fp-int-convert.h"
+
+#define FLOAT128_MANT_DIG 113
+
+int
+main (void)
+{
+  TEST_I_F(TItype, UTItype, __float128, FLOAT128_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c    
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c  2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,22 @@
+/* Test floating-point conversions.  __float128 type.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
+/* { dg-xfail-if "" { i?86-*-* x86_64-*-* } { "*" } { "" } } */
+/* { dg-options "" } */
+/* { dg-options "-mmmx" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-mmmx" { target { x86_64-*-* && ilp32 } } } */
+
+#include "fp-int-convert.h"
+
+#define FLOAT128_MANT_DIG 113
+
+int
+main (void)
+{
+  TEST_I_F(signed char, unsigned char, __float128, FLOAT128_MANT_DIG);
+  TEST_I_F(signed short, unsigned short, __float128, FLOAT128_MANT_DIG);
+  TEST_I_F(signed int, unsigned int, __float128, FLOAT128_MANT_DIG);
+  TEST_I_F(signed long, unsigned long, __float128, FLOAT128_MANT_DIG);
+  TEST_I_F(signed long long, unsigned long long, __float128,
FLOAT128_MANT_DIG);
+  exit (0);
+}
diff -rupN
GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c      
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80-timode.c   
2005-11-25 02:27:44.000000000 +0000
@@ -0,0 +1,17 @@
+/* Test floating-point conversions.  __float80 type with TImode.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
+/* { dg-options "" } */
+/* { dg-options "-mmmx" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-mmmx" { target { x86_64-*-* && ilp32 } } } */
+
+#include "fp-int-convert.h"
+
+#define FLOAT80_MANT_DIG 64
+
+int
+main (void)
+{
+  TEST_I_F(TItype, UTItype, __float80, FLOAT80_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c     
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c   2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,21 @@
+/* Test floating-point conversions.  __float80 type.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
+/* { dg-options "" } */
+/* { dg-options "-mmmx" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-mmmx" { target { x86_64-*-* && ilp32 } } } */
+
+#include "fp-int-convert.h"
+
+#define FLOAT80_MANT_DIG 64
+
+int
+main (void)
+{
+  TEST_I_F(signed char, unsigned char, __float80, FLOAT80_MANT_DIG);
+  TEST_I_F(signed short, unsigned short, __float80, FLOAT80_MANT_DIG);
+  TEST_I_F(signed int, unsigned int, __float80, FLOAT80_MANT_DIG);
+  TEST_I_F(signed long, unsigned long, __float80, FLOAT80_MANT_DIG);
+  TEST_I_F(signed long long, unsigned long long, __float80, FLOAT80_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c 
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-long-double.c      
2005-11-25 02:27:44.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test floating-point conversions.  Standard types and long double.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+  TEST_I_F(signed char, unsigned char, long double, LDBL_MANT_DIG);
+  TEST_I_F(signed short, unsigned short, long double, LDBL_MANT_DIG);
+  TEST_I_F(signed int, unsigned int, long double, LDBL_MANT_DIG);
+  TEST_I_F(signed long, unsigned long, long double, LDBL_MANT_DIG);
+  TEST_I_F(signed long long, unsigned long long, long double, LDBL_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c      
1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode.c    2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,16 @@
+/* Test floating-point conversions.  TImode types.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do run { xfail *-*-* } } */
+/* { dg-options "" } */
+
+#include <float.h>
+#include "fp-int-convert.h"
+
+int
+main (void)
+{
+  TEST_I_F(TItype, UTItype, float, FLT_MANT_DIG);
+  TEST_I_F(TItype, UTItype, double, DBL_MANT_DIG);
+  TEST_I_F(TItype, UTItype, long double, LDBL_MANT_DIG);
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert.h
GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert.h
--- GCC.orig/gcc/testsuite/gcc.dg/torture/fp-int-convert.h      1970-01-01
00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/torture/fp-int-convert.h   2005-11-25
02:27:44.000000000 +0000
@@ -0,0 +1,89 @@
+/* Test floating-point conversions.  */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+
+#include <limits.h>
+extern void abort (void);
+extern void exit (int);
+
+/* Not all platforms support TImode integers; logic as in
+   gcc.dg/titype-1.c.  */
+#if defined(__LP64__) && !defined(__hppa__)
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+#else
+typedef long TItype;
+typedef unsigned long UTItype;
+#endif
+
+/* TEST_I_F(I, U, F, P) tests conversions between the pair of signed
+   and unsigned integer types I and U and the floating-point type F,
+   where P is the binary precision of the floating point type.  We
+   test conversions of the values 0, 1, 0x7...f, 0x8...0, 0xf...f.  We
+   also test conversions of values half way inbetween two
+   representable values (rounding both ways), just above half way, and
+   just below half way.  */
+#define TEST_I_F(I, U, F, P)                                   \
+do {                                                           \
+  TEST_I_F_VAL (I, F, (I)0, 1);                                        \
+  TEST_I_F_VAL (I, F, (I)1, 1);                                        \
+  TEST_I_F_VAL (I, F, (I)(((U)~(U)0) >> 1), P_OK1 (P, I));     \
+  TEST_I_F_VAL (I, F, (I)(U)~(((U)~(U)0) >> 1), 1);            \
+  TEST_I_F_VAL (I, F, (I)(U)~(U)0, P_OK (P, I));               \
+  TEST_I_F_VAL (I, F, HVAL0S (P, I), P_OK (P, I));             \
+  TEST_I_F_VAL (I, F, HVAL0S (P, I) + 1, P_OK (P, I));         \
+  TEST_I_F_VAL (I, F, HVAL0S (P, I) - 1, P_OK (P, I));         \
+  TEST_I_F_VAL (I, F, HVAL1S (P, I), P_OK (P, I));             \
+  TEST_I_F_VAL (I, F, HVAL1S (P, I) + 1, P_OK (P, I));         \
+  TEST_I_F_VAL (I, F, HVAL1S (P, I) - 1, P_OK (P, I));         \
+  TEST_I_F_VAL (I, F, -HVAL0S (P, I), P_OK (P, I));            \
+  TEST_I_F_VAL (I, F, -HVAL0S (P, I) + 1, P_OK (P, I));                \
+  TEST_I_F_VAL (I, F, -HVAL0S (P, I) - 1, P_OK (P, I));                \
+  TEST_I_F_VAL (I, F, -HVAL1S (P, I), P_OK (P, I));            \
+  TEST_I_F_VAL (I, F, -HVAL1S (P, I) + 1, P_OK (P, I));                \
+  TEST_I_F_VAL (I, F, -HVAL1S (P, I) - 1, P_OK (P, I));                \
+  TEST_I_F_VAL (U, F, (U)0, 1);                                        \
+  TEST_I_F_VAL (U, F, (U)1, 1);                                        \
+  TEST_I_F_VAL (U, F, (U)(((U)~(U)0) >> 1), P_OK1 (P, U));     \
+  TEST_I_F_VAL (U, F, (U)~(((U)~(U)0) >> 1), 1);               \
+  TEST_I_F_VAL (U, F, (U)~(U)0, P_OK (P, U));                  \
+  TEST_I_F_VAL (U, F, HVAL0U (P, U), P_OK (P, U));             \
+  TEST_I_F_VAL (U, F, HVAL0U (P, U) + 1, P_OK (P, U));         \
+  TEST_I_F_VAL (U, F, HVAL0U (P, U) - 1, P_OK (P, U));         \
+  TEST_I_F_VAL (U, F, HVAL1U (P, U), P_OK (P, U));             \
+  TEST_I_F_VAL (U, F, HVAL1U (P, U) + 1, P_OK (P, U));         \
+  TEST_I_F_VAL (U, F, HVAL1U (P, U) - 1, P_OK (P, U));         \
+} while (0)
+
+#define P_OK(P, T) ((P) >= sizeof(T) * CHAR_BIT)
+#define P_OK1(P, T) ((P) >= sizeof(T) * CHAR_BIT - 1)
+#define HVAL0U(P, U) (U)(P_OK (P, U)                                    \
+                        ? (U)1                                          \
+                        : (((U)1 << (sizeof(U) * CHAR_BIT - 1))         \
+                           + ((U)1 << (sizeof(U) * CHAR_BIT - 1 - P))))
+#define HVAL1U(P, U) (U)(P_OK (P, U)                                    \
+                        ? (U)1                                          \
+                        : (((U)1 << (sizeof(U) * CHAR_BIT - 1))         \
+                           + ((U)3 << (sizeof(U) * CHAR_BIT - 1 - P))))
+#define HVAL0S(P, S) (S)(P_OK1 (P, S)                                   \
+                        ? (S)1                                          \
+                        : (((S)1 << (sizeof(S) * CHAR_BIT - 2))         \
+                           + ((S)1 << (sizeof(S) * CHAR_BIT - 2 - P))))
+#define HVAL1S(P, S) (S)(P_OK1 (P, S)                                   \
+                        ? (S)1                                          \
+                        : (((S)1 << (sizeof(S) * CHAR_BIT - 2))         \
+                           + ((S)3 << (sizeof(S) * CHAR_BIT - 2 - P))))
+
+#define TEST_I_F_VAL(IT, FT, VAL, PREC_OK)             \
+do {                                                   \
+  static volatile IT ivin, ivout;                      \
+  static volatile FT fv1, fv2;                         \
+  ivin = (VAL);                                                \
+  fv1 = (VAL);                                         \
+  fv2 = ivin;                                          \
+  ivout = fv2;                                         \
+  if (ivin != (VAL)                                    \
+      || ((PREC_OK) && ivout != ivin)                  \
+      || ((PREC_OK) && ivout != (VAL))                 \
+      || fv1 != (VAL) || fv2 != (VAL) || fv1 != fv2)   \
+    abort ();                                          \
+} while (0)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24998


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]