re PR target/71241 ([x86] Missing built-in functions for float128 NaNs)
authorUros Bizjak <uros@gcc.gnu.org>
Sun, 12 Jun 2016 17:22:16 +0000 (19:22 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 12 Jun 2016 17:22:16 +0000 (19:22 +0200)
PR target/71241
* config/i386/i386.i386-builtin-types.def (CONST_STRING):
New primitive type.
(FLOAT128_FTYPE_CONST_STRING): New function type.
* config/i386/i386.c (enum ix86_builtins) [IX86_BUILTIN_NANQ]: New.
[IX86_BUILTIN_NANSQ]: Ditto.
(ix86_fold_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ.
(ix86_init_builtin_types) Declare const_string_type_node.
Add __builtin_nanq and __builtin_nansq builtin functions.
(ix86_expand_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ.
* doc/extend.texi (x86 Built-in Functions): Document
__builtin_nanq and __builtin_nansq.

testsuite/ChangeLog:

PR target/71241
* testsuite/gcc.dg/torture/float128-nan.c: New test.

From-SVN: r237338

gcc/ChangeLog
gcc/config/i386/i386-builtin-types.def
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/float128-nan.c [new file with mode: 0644]

index 6266fb35712368ed9764512a93c60fa131c83504..0a48316e0f9546877325c4f819d5ade238a52e2d 100644 (file)
@@ -1,3 +1,18 @@
+2016-06-12  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/71241
+       * config/i386/i386.i386-builtin-types.def (CONST_STRING):
+       New primitive type.
+       (FLOAT128_FTYPE_CONST_STRING): New function type.
+       * config/i386/i386.c (enum ix86_builtins) [IX86_BUILTIN_NANQ]: New.
+       [IX86_BUILTIN_NANSQ]: Ditto.
+       (ix86_fold_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ.
+       (ix86_init_builtin_types) Declare const_string_type_node.
+       Add __builtin_nanq and __builtin_nansq builtin functions.
+       (ix86_expand_builtin): Handle IX86_BUILTIN_NANQ and IX86_BUILTIN_NANSQ.
+       * doc/extend.texi (x86 Built-in Functions): Document
+       __builtin_nanq and __builtin_nansq.
+
 2016-06-11  Jiong Wang  <jiong.wang@arm.com>
 
        PR target/71061
@@ -60,7 +75,7 @@
        (fsm_find_control_statement_thread_paths): Avoid putting the same
        block on the thread path twice, but ensure the thread path is
        unchanged from the caller's point of view.
-       
+
 2016-06-10  Jan Hubicka  <hubicka@ucw.cz>
 
        * predict.c (predict_loops): Remove PRED_LOOP_BRANCH.
            Jiong Wang  <jiong.wang@arm.com>
 
        PR rtl-optimization/70751
-       * lra-constraints.c (process_alt_operands): Recognize Non-pseudo spilled
-       into memory.
+       * lra-constraints.c (process_alt_operands): Recognize Non-pseudo
+       spilled into memory.
 
-2016-06-09 Jonathan Yong  <10walls@gmail.com>
+2016-06-09  Jonathan Yong  <10walls@gmail.com>
 
        Revert:
        2015-09-21  Jonathan Yong  <10walls@gmail.com>
-        * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search
-        sysroot/usr/lib/32api for additional win32 libraries,
-        fixes failing Cygwin bootstrapping.
+
+       * config/i386/cygwin.h (STARTFILE_SPEC): Explicitly search
+       sysroot/usr/lib/32api for additional win32 libraries,
+       fixes failing Cygwin bootstrapping.
 
 2016-06-09  Marcin BaczyƄski  <marbacz@gmail.com>
 
        * diagnostic.h (diagnostic_line_cutoff, diagnostic_flush_buffer):
-       delete.
+       Delete.
 
 2016-06-09  David Malcolm  <dmalcolm@redhat.com>
 
 
 2016-06-07  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
-       * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local
-       variable.
+       * simplify-rtx.c (simplify_cond_clz_ctz): Delete 'mode' local variable.
 
 2016-06-07  Jakub Jelinek  <jakub@redhat.com>
 
index c66f65108f8aebebbccc651a0db4c035858cd855..7eb6fc96e66f8d50520a6847bd41641b0c97520d 100644 (file)
@@ -73,6 +73,7 @@ DEF_PRIMITIVE_TYPE (FLOAT, float_type_node)
 DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node)
 DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node)
 DEF_PRIMITIVE_TYPE (FLOAT128, float128_type_node)
+DEF_PRIMITIVE_TYPE (CONST_STRING, const_string_type_node)
 
 # MMX vectors
 DEF_VECTOR_TYPE (V2SF, FLOAT)
@@ -191,6 +192,7 @@ DEF_FUNCTION_TYPE (PVOID)
 
 DEF_FUNCTION_TYPE (FLOAT, FLOAT)
 DEF_FUNCTION_TYPE (FLOAT128, FLOAT128)
+DEF_FUNCTION_TYPE (FLOAT128, CONST_STRING)
 DEF_FUNCTION_TYPE (INT, INT)
 DEF_FUNCTION_TYPE (INT, V16QI)
 DEF_FUNCTION_TYPE (INT, V2DF)
index b807a9a00041eb6009261819fcd253bb147f2b52..dd47305c5b0cc2be0bf111e8a84a0c689e03b3a4 100644 (file)
@@ -32718,6 +32718,8 @@ enum ix86_builtins
   /* TFmode support builtins.  */
   IX86_BUILTIN_INFQ,
   IX86_BUILTIN_HUGE_VALQ,
+  IX86_BUILTIN_NANQ,
+  IX86_BUILTIN_NANSQ,
   IX86_BUILTIN_FABSQ,
   IX86_BUILTIN_COPYSIGNQ,
 
@@ -38105,11 +38107,28 @@ ix86_fold_builtin (tree fndecl, int n_args,
     {
       enum ix86_builtins fn_code = (enum ix86_builtins)
                                   DECL_FUNCTION_CODE (fndecl);
-      if (fn_code ==  IX86_BUILTIN_CPU_IS
-         || fn_code == IX86_BUILTIN_CPU_SUPPORTS)
+      switch (fn_code)
        {
+       case IX86_BUILTIN_CPU_IS:
+       case IX86_BUILTIN_CPU_SUPPORTS:
          gcc_assert (n_args == 1);
-          return fold_builtin_cpu (fndecl, args);
+         return fold_builtin_cpu (fndecl, args);
+
+       case IX86_BUILTIN_NANQ:
+       case IX86_BUILTIN_NANSQ:
+         {
+           tree type = TREE_TYPE (TREE_TYPE (fndecl));
+           const char *str = c_getstr (*args);
+           int quiet = fn_code == IX86_BUILTIN_NANQ;
+           REAL_VALUE_TYPE real;
+
+           if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
+             return build_real (type, real);
+           return NULL_TREE;
+         }
+
+       default:
+         break;
        }
     }
 
@@ -38210,7 +38229,7 @@ ix86_init_builtins_va_builtins_abi (void)
 static void
 ix86_init_builtin_types (void)
 {
-  tree float128_type_node, float80_type_node;
+  tree float128_type_node, float80_type_node, const_string_type_node;
 
   /* The __float80 type.  */
   float80_type_node = long_double_type_node;
@@ -38230,6 +38249,10 @@ ix86_init_builtin_types (void)
   layout_type (float128_type_node);
   lang_hooks.types.register_builtin_type (float128_type_node, "__float128");
 
+  const_string_type_node
+    = build_pointer_type (build_qualified_type
+                         (char_type_node, TYPE_QUAL_CONST));
+
   /* This macro is built by i386-builtin-types.awk.  */
   DEFINE_BUILTIN_PRIMITIVE_TYPES;
 }
@@ -38250,6 +38273,18 @@ ix86_init_builtins (void)
   def_builtin_const (0, "__builtin_huge_valq",
                     FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ);
 
+  t = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING);
+  t = add_builtin_function ("__builtin_nanq", t, IX86_BUILTIN_NANQ,
+                           BUILT_IN_MD, "nanq", NULL_TREE);
+  TREE_READONLY (t) = 1;
+  ix86_builtins[(int) IX86_BUILTIN_NANQ] = t;
+
+  t = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING);
+  t = add_builtin_function ("__builtin_nansq", t, IX86_BUILTIN_NANSQ,
+                           BUILT_IN_MD, "nansq", NULL_TREE);
+  TREE_READONLY (t) = 1;
+  ix86_builtins[(int) IX86_BUILTIN_NANSQ] = t;  
+
   /* We will expand them to normal call if SSE isn't available since
      they are used by libgcc. */
   t = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128);
@@ -41463,6 +41498,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
        return target;
       }
 
+    case IX86_BUILTIN_NANQ:
+    case IX86_BUILTIN_NANSQ:
+      return expand_call (exp, target, ignore);
+
     case IX86_BUILTIN_RDPMC:
     case IX86_BUILTIN_RDTSC:
     case IX86_BUILTIN_RDTSCP:
index 305af6b92f03c508ae84b00446472e5fa085f384..426c8ad1865a7a28f3f698184707f88ebaecf675 100644 (file)
@@ -1,3 +1,8 @@
+2016-06-12  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/71241
+       * testsuite/gcc.dg/torture/float128-nan.c: New test.
+
 2016-06-12  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
        PR target/60751
diff --git a/gcc/testsuite/gcc.dg/torture/float128-nan.c b/gcc/testsuite/gcc.dg/torture/float128-nan.c
new file mode 100644 (file)
index 0000000..b570623
--- /dev/null
@@ -0,0 +1,101 @@
+/* Test __float128 NaN generation.  */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "" } */
+
+#include <fenv.h>
+#include <stdbool.h>
+
+typedef unsigned long long int uint64_t;
+
+typedef union
+{
+  __float128 value;
+
+  struct
+#ifdef __MINGW32__
+  /* Make sure we are using gnu-style bitfield handling.  */
+  __attribute__ ((gcc_struct))
+#endif
+  {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    unsigned negative:1;
+    unsigned exponent:15;
+    unsigned quiet_nan:1;
+    uint64_t mant_high:47;
+    uint64_t mant_low:64;
+#else
+    uint64_t mant_low:64;
+    uint64_t mant_high:47;
+    unsigned quiet_nan:1;
+    unsigned exponent:15;
+    unsigned negative:1;
+#endif
+  } nan;
+
+} ieee854_float128;
+
+bool
+__attribute__((noinline, noclone))
+check_nan (__float128 val, bool quiet)
+{
+  ieee854_float128 u;
+  volatile __float128 tmp;
+
+  u.value = val;
+
+  if (u.nan.exponent != 0x7fff
+      || (u.nan.quiet_nan | u.nan.mant_high | u.nan.mant_low) == 0
+      || u.nan.quiet_nan != quiet)
+    return false;
+
+  if (!__builtin_isnan (u.value))
+    return false;
+
+  feclearexcept (FE_INVALID);
+
+  tmp = u.value + u.value;
+
+  if ((fetestexcept (FE_INVALID) != 0) == quiet)
+    return false;
+
+  return true;
+}
+
+int
+main (void)
+{
+  __float128 nan;
+
+  nan = __builtin_nanq ("");
+
+  if (!check_nan (nan, true))
+    __builtin_abort ();
+
+  nan = __builtin_nanq ("0x0");
+
+  if (!check_nan (nan, true))
+    __builtin_abort ();
+
+  nan = __builtin_nanq ("0x1");
+
+  if (!check_nan (nan, true))
+    __builtin_abort ();
+
+  nan = __builtin_nansq ("");
+
+  if (!check_nan (nan, false))
+    __builtin_abort ();
+
+  nan = __builtin_nansq ("0x0");
+
+  if (!check_nan (nan, false))
+    __builtin_abort ();
+
+  nan = __builtin_nansq ("0x1");
+
+  if (!check_nan (nan, false))
+    __builtin_abort ();
+
+  return 0;
+}