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
This commit is contained in:
Francois-Xavier Coudert 2015-08-18 20:07:57 +00:00 committed by François-Xavier Coudert
parent a1c045caab
commit 61717a4593
9 changed files with 53 additions and 15 deletions

View 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

View 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

View 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)

View 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

View 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)

View 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.

View 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

View 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;
}

View 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__))