This patch makes __ibm128 use the long double type node if long double uses the
IBM extended double representation, and similarly __float128 will use the long
double type node if long double uses the IEEE 128-bit representation.

I have fixed the pr85657.C test case to only test templates, and not explicit
overloading.

With this fix, the compiler no longer raises an internal error if you use
explicit overloading of __ibm128 and long double.  Instead it generates the
expected error:

foo01.C:33:15: error: 'bool foo::iszero(long double)' cannot be overloaded with 
'bool foo::iszero(long double)'
   inline bool iszero (__ibm128 i128) { return i128 == 0.0; }
               ^~~~~~
foo01.C:32:15: note: previous declaration 'bool foo::iszero(long double)'
   inline bool iszero (long double ld) { return ld == 0.0; }

I have checked this patch on a little endian power8 system and there were no
regressions.  As I mentioned previously, the pr85657.C now passes.

[gcc]
2018-06-05  Michael Meissner  <meiss...@linux.ibm.com>

        * config/rs6000/rs6000.c (rs6000_init_builtins): Make __ibm128 use
        the long double type if long double is IBM extended double.  Make
        __float128 use the long double type if long double is IEEE 128-bit.

[gcc/testsuite]
2018-06-05  Michael Meissner  <meiss...@linux.ibm.com>

        PR target/85657
        * g++.dg/pr85657.C: Only test whether __ibm128 and long double can
        be used in templates.  Don't check for them in overloaded functions.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 261175)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -16383,14 +16383,21 @@ rs6000_init_builtins (void)
      __ieee128.  */
   if (TARGET_FLOAT128_TYPE)
     {
-      ibm128_float_type_node = make_node (REAL_TYPE);
-      TYPE_PRECISION (ibm128_float_type_node) = 128;
-      SET_TYPE_MODE (ibm128_float_type_node, IFmode);
-      layout_type (ibm128_float_type_node);
+      if (TARGET_IEEEQUAD || !TARGET_LONG_DOUBLE_128)
+       {
+         ibm128_float_type_node = make_node (REAL_TYPE);
+         TYPE_PRECISION (ibm128_float_type_node) = 128;
+         SET_TYPE_MODE (ibm128_float_type_node, IFmode);
+         layout_type (ibm128_float_type_node);
+       }
+      else
+       ibm128_float_type_node = long_double_type_node;
+
       lang_hooks.types.register_builtin_type (ibm128_float_type_node,
                                              "__ibm128");
 
-      ieee128_float_type_node = float128_type_node;
+      ieee128_float_type_node
+       = TARGET_IEEEQUAD ? long_double_type_node : float128_type_node;
       lang_hooks.types.register_builtin_type (ieee128_float_type_node,
                                              "__ieee128");
     }
Index: gcc/testsuite/g++.dg/pr85657.C
===================================================================
--- gcc/testsuite/g++.dg/pr85657.C      (revision 261170)
+++ gcc/testsuite/g++.dg/pr85657.C      (working copy)
@@ -3,8 +3,8 @@
 // { dg-options "-mvsx -mfloat128 -O2 -mabi=ibmlongdouble -Wno-psabi" }
 
 // PR 85657
-// Check that __ibm128 and long double are represented as different types, even
-// if long double is currently using the same representation as __ibm128.
+// Check that __ibm128 and long double can be used in the same template,
+// even if long double uses the IBM extended double representation.
 
 template <class __T> inline bool
 iszero (__T __val)
@@ -18,30 +18,7 @@ use_template (void)
   long double ld = 0.0;
   __ibm128 ibm = 0.0;
 
-#ifdef _ARCH_PWR7
   __asm__ (" # %x0, %x1" : "+d" (ld), "+d" (ibm));
-#endif
 
   return iszero (ld) + iszero (ibm);
 }
-
-class foo {
-public:
-  foo () {}
-  ~foo () {}
-  inline bool iszero (long double ld) { return ld == 0.0; }
-  inline bool iszero (__ibm128 i128) { return i128 == 0.0; }
-} st;
-
-int
-use_class (void)
-{
-  long double ld = 0.0;
-  __ibm128 ibm = 0.0;
-
-#ifdef _ARCH_PWR7
-  __asm__ (" # %x0, %x1" : "+d" (ld), "+d" (ibm));
-#endif
-
-  return st.iszero (ld) + st.iszero (ibm);
-}

Reply via email to