From 61717a4593d0c710b6fed946e8ce9728c83ed369 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Tue, 18 Aug 2015 20:07:57 +0000 Subject: [PATCH] re PR middle-end/36757 (__builtin_signbit should be type-generic) 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 | 8 ++++++++ gcc/builtins.c | 14 +++++--------- gcc/builtins.def | 2 +- gcc/c-family/ChangeLog | 6 ++++++ gcc/c-family/c-common.c | 1 + gcc/doc/extend.texi | 2 +- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/builtins-error.c | 3 +++ gcc/testsuite/gcc.dg/tg-tests.h | 26 ++++++++++++++++++++++---- 9 files changed, 53 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd0435ee9711..f210fd685432 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-08-18 Francois-Xavier Coudert + + 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 PR rtl-optimization/67218 diff --git a/gcc/builtins.c b/gcc/builtins.c index 82229a549dc5..31969ca3e534 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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 diff --git a/gcc/builtins.def b/gcc/builtins.def index 80e4a9cab655..f7ac4a834cc4 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -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) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 6200d1bc0260..7a25c399e22e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2015-08-18 Francois-Xavier Coudert + + PR middle-end/36757 + * c-common.c (check_builtin_function_arguments): Add check + for BUILT_IN_SIGNBIT argument. + 2015-08-18 Paolo Carlini PR c++/67160 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 13175d84f41c..f081dadd6b6c 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 64d9a6ab0da4..dba8b4382b25 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af91c7dab7aa..9ca2ce5bd9c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-08-18 Francois-Xavier Coudert + + 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 PR rtl-optimization/67218 diff --git a/gcc/testsuite/gcc.dg/builtins-error.c b/gcc/testsuite/gcc.dg/builtins-error.c index 0f41700ba1a0..9ddf1b1e2ae1 100644 --- a/gcc/testsuite/gcc.dg/builtins-error.c +++ b/gcc/testsuite/gcc.dg/builtins-error.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/tg-tests.h b/gcc/testsuite/gcc.dg/tg-tests.h index ce9cfb866cfb..a645cc4f4526 100644 --- a/gcc/testsuite/gcc.dg/tg-tests.h +++ b/gcc/testsuite/gcc.dg/tg-tests.h @@ -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__)) -- 2.43.5