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:
parent
a1c045caab
commit
61717a4593
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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__))
|
||||
|
Loading…
x
Reference in New Issue
Block a user