+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
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)
{
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));
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
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)
+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
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)
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.
+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
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;
}
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;
}
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;
}
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 ();
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
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__))