re PR middle-end/36757 (__builtin_signbit should be type-generic)
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Tue, 18 Aug 2015 20:07:57 +0000 (20:07 +0000)
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Tue, 18 Aug 2015 20:07:57 +0000 (20:07 +0000)
PR middle-end/36757

* builtins.c (expand_builtin_signbit): Add asserts to make sure
we can expand BUILT_IN_SIGNBIT inline.
* builtins.def (BUILT_IN_SIGNBIT): Make type-generic.
* doc/extend.texi: Document the type-generic __builtin_signbit.

* c-common.c (check_builtin_function_arguments): Add check
for BUILT_IN_SIGNBIT argument.

* gcc.dg/builtins-error.c: Add checks for __builtin_signbit.
* gcc.dg/tg-tests.h: Add checks for __builtin_signbit.

From-SVN: r226990

gcc/ChangeLog
gcc/builtins.c
gcc/builtins.def
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-error.c
gcc/testsuite/gcc.dg/tg-tests.h

index bd0435ee97119b2c5104acce684e10111292ef7c..f210fd685432c06f8591063bcf4c71d23386a5b4 100644 (file)
@@ -1,3 +1,11 @@
+2015-08-18  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR middle-end/36757
+       * builtins.c (expand_builtin_signbit): Add asserts to make sure
+       we can expand BUILT_IN_SIGNBIT inline.
+       * builtins.def (BUILT_IN_SIGNBIT): Make type-generic.
+       * doc/extend.texi: Document the type-generic __builtin_signbit.
+
 2015-08-18  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR rtl-optimization/67218
index 82229a549dc599b6d94fc773ee5f427bc9589945..31969ca3e534cebc745f01689f613011dea0eadf 100644 (file)
@@ -4953,11 +4953,9 @@ expand_builtin_adjust_trampoline (tree exp)
    function.  The function first checks whether the back end provides
    an insn to implement signbit for the respective mode.  If not, it
    checks whether the floating point format of the value is such that
-   the sign bit can be extracted.  If that is not the case, the
-   function returns NULL_RTX to indicate that a normal call should be
-   emitted rather than expanding the function in-line.  EXP is the
-   expression that is a call to the builtin function; if convenient,
-   the result should be placed in TARGET.  */
+   the sign bit can be extracted.  If that is not the case, error out.
+   EXP is the expression that is a call to the builtin function; if
+   convenient, the result should be placed in TARGET.  */
 static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
@@ -5000,8 +4998,7 @@ expand_builtin_signbit (tree exp, rtx target)
   if (bitpos < 0)
   {
     /* But we can't do this if the format supports signed zero.  */
-    if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
-      return NULL_RTX;
+    gcc_assert (!fmt->has_signed_zero || !HONOR_SIGNED_ZEROS (fmode));
 
     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
                       build_real (TREE_TYPE (arg), dconst0));
@@ -5011,8 +5008,7 @@ expand_builtin_signbit (tree exp, rtx target)
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
     {
       imode = int_mode_for_mode (fmode);
-      if (imode == BLKmode)
-       return NULL_RTX;
+      gcc_assert (imode != BLKmode);
       temp = gen_lowpart (imode, temp);
     }
   else
index 80e4a9cab6553821b0ac58d6dcb998b96990338d..f7ac4a834cc40906cba3c6d9edf23ebef743b9e5 100644 (file)
@@ -489,7 +489,7 @@ DEF_C99_BUILTIN        (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUB
 DEF_C99_BUILTIN        (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
-DEF_EXT_LIB_BUILTIN    (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN    (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_SIGNBITD32, "signbitd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
index 6200d1bc0260c83a79a44edf31fbb38def6578bb..7a25c399e22ed988029e87134ede96b8a03eded0 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-18  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR middle-end/36757
+       * c-common.c (check_builtin_function_arguments): Add check
+       for BUILT_IN_SIGNBIT argument.
+
 2015-08-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/67160
index 13175d84f41ce9d12f1a4dfa881ab3fc31757ea5..f081dadd6b6ceaa78ac90795e8cdafed9b10eb99 100644 (file)
@@ -10151,6 +10151,7 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
     case BUILT_IN_ISINF_SIGN:
     case BUILT_IN_ISNAN:
     case BUILT_IN_ISNORMAL:
+    case BUILT_IN_SIGNBIT:
       if (builtin_function_validate_nargs (fndecl, nargs, 1))
        {
          if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE)
index 64d9a6ab0da4d286abc0c66435df8ddcf287560a..dba8b4382b257172273175225cde3df441f5bcb3 100644 (file)
@@ -10448,7 +10448,7 @@ the same names as the standard macros ( @code{isgreater},
 prefixed.  We intend for a library implementor to be able to simply
 @code{#define} each standard macro to its built-in equivalent.
 In the same fashion, GCC provides @code{fpclassify}, @code{isfinite},
-@code{isinf_sign} and @code{isnormal} built-ins used with
+@code{isinf_sign}, @code{isnormal} and @code{signbit} built-ins used with
 @code{__builtin_} prefixed.  The @code{isinf} and @code{isnan}
 built-in functions appear both with and without the @code{__builtin_} prefix.
 
index af91c7dab7aa3407585d8c499cc2949fd64a0ecd..9ca2ce5bd9c82599bf19a7ca89c9e65b2007333a 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-18  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR middle-end/36757
+       * gcc.dg/builtins-error.c: Add checks for __builtin_signbit.
+       * gcc.dg/tg-tests.h: Add checks for __builtin_signbit.
+
 2015-08-18  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR rtl-optimization/67218
index 0f41700ba1a081c5d4ef5ef051f89383a89a065f..9ddf1b1e2ae13ebcb7d4d8cb4d4ff1104c32a61b 100644 (file)
@@ -16,6 +16,7 @@ int test1(struct X x)
   if (x.x == 10) return __builtin_islessequal(x, x); /* { dg-error "non-floating-point arguments" } */
   if (x.x == 11) return __builtin_islessgreater(x, x); /* { dg-error "non-floating-point arguments" } */
   if (x.x == 12) return __builtin_isunordered(x, x); /* { dg-error "non-floating-point arguments" } */
+  if (x.x == 13) return __builtin_signbit(x); /* { dg-error "non-floating-point argument" } */
 
   return 0;
 }
@@ -34,6 +35,7 @@ int test2(double x)
   if (x == 10) return __builtin_islessequal(x); /* { dg-error "not enough arguments" } */
   if (x == 11) return __builtin_islessgreater(x); /* { dg-error "not enough arguments" } */
   if (x == 12) return __builtin_isunordered(x); /* { dg-error "not enough arguments" } */
+  if (x == 13) return __builtin_signbit(); /* { dg-error "not enough arguments" } */
   return 0;
 }
 
@@ -51,6 +53,7 @@ int test3(double x)
   if (x == 10) return __builtin_islessequal(x, x, x); /* { dg-error "too many arguments" } */
   if (x == 11) return __builtin_islessgreater(x, x, x); /* { dg-error "too many arguments" } */
   if (x == 12) return __builtin_isunordered(x, x, x); /* { dg-error "too many arguments" } */
+  if (x == 13) return __builtin_signbit(x, x); /* { dg-error "too many arguments" } */
   return 0;
 }
 
index ce9cfb866cfb455a879e28ac500af21fa21fcba8..a645cc4f4526b4fbc1310359bed5cc57fc5f9a80 100644 (file)
@@ -11,7 +11,7 @@ void __attribute__ ((__noinline__))
 foo_1 (float f, double d, long double ld,
        int res_unord, int res_isnan, int res_isinf,
        int res_isinf_sign, int res_isfin, int res_isnorm,
-       int classification)
+       int res_signbit, int classification)
 {
   if (__builtin_isunordered (f, 0) != res_unord)
     __builtin_abort ();
@@ -80,6 +80,23 @@ foo_1 (float f, double d, long double ld,
   if (__builtin_finitel (ld) != res_isfin)
     __builtin_abort ();
 
+  /* Sign bit of zeros and nans is not preserved in unsafe math mode.  */
+#ifdef UNSAFE
+  if (!res_isnan && d != 0)
+#endif
+    {
+      if ((__builtin_signbit (f) ? 1 : 0) != res_signbit)
+       __builtin_abort ();
+      if ((__builtin_signbit (d) ? 1 : 0) != res_signbit)
+       __builtin_abort ();
+      if ((__builtin_signbit (ld) ? 1 : 0) != res_signbit)
+       __builtin_abort ();
+      if ((__builtin_signbitf (f) ? 1 : 0) != res_signbit)
+       __builtin_abort ();
+      if ((__builtin_signbitl (ld) ? 1 : 0) != res_signbit)
+       __builtin_abort ();
+    }
+
   /* Subnormals can abruptly underflow to zero in unsafe math
      mode, so bypass testing these numbers if necessary.  */
 #ifdef UNSAFE
@@ -100,9 +117,10 @@ foo (float f, double d, long double ld,
      int res_unord, int res_isnan, int res_isinf,
      int res_isfin, int res_isnorm, int classification)
 {
-  foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, classification);
-  /* Try all the values negated as well.  */
-  foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, classification);
+  foo_1 (f, d, ld, res_unord, res_isnan, res_isinf, res_isinf, res_isfin, res_isnorm, 0, classification);
+  /* Try all the values negated as well.  All will have the sign bit set,
+     except for the nan.  */
+  foo_1 (-f, -d, -ld, res_unord, res_isnan, res_isinf, -res_isinf, res_isfin, res_isnorm, 1, classification);
 }
 
 int __attribute__ ((__noinline__))