Commit c53233c6 by Richard Sandiford Committed by Richard Sandiford

Fold comparisons between sqrt and zero

The expression:

      signbit(sqrt(x))

is always 0 for -ffast-math.  The signbit fold first converts it to:

      sqrt(x) < 0

and whether we realise that this is false depends on a race between two
folders: the sqrt comparison folder, which wants to convert it to

      x < 0*0

and the generic tree_expr_nonnegative_p rule for ... < 0, which would
give the hoped-for 0.

The sqrt code already handles comparisons with negative values specially,
so this patch simply extends that idea to comparisons with zero.

Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.

gcc/
	* match.pd: Handle sqrt(x) cmp 0 specially.

gcc/testsuite/
	* gcc.dg/torture/builtin-sqrt-cmp-1.c: New test.

From-SVN: r229422
parent 3f8c04e7
2015-10-27 Richard Sandiford <richard.sandiford@arm.com>
* match.pd: Handle sqrt(x) cmp 0 specially.
2015-10-27 Ilya Enkovich <enkovich.gnu@gmail.com>
* tree-vect-generic.c (expand_vector_operations_1): Check
......@@ -1973,6 +1973,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ constant_boolean_node (true, type); })
/* sqrt(x) > y is the same as x >= 0, if y is negative. */
(ge @0 { build_real (TREE_TYPE (@0), dconst0); })))
(if (real_equal (TREE_REAL_CST_PTR (@1), &dconst0))
(switch
/* sqrt(x) < 0 is always false. */
(if (cmp == LT_EXPR)
{ constant_boolean_node (false, type); })
/* sqrt(x) >= 0 is always true if we don't care about NaNs. */
(if (cmp == GE_EXPR && !HONOR_NANS (@0))
{ constant_boolean_node (true, type); })
/* sqrt(x) <= 0 -> x == 0. */
(if (cmp == LE_EXPR)
(eq @0 @1))
/* Otherwise sqrt(x) cmp 0 -> x cmp 0. Here cmp can be >=, >,
== or !=. In the last case:
(sqrt(x) != 0) == (NaN != 0) == true == (x != 0)
if x is negative or NaN. Due to -funsafe-math-optimizations,
the results for other x follow from natural arithmetic. */
(cmp @0 @1)))
(if (cmp == GT_EXPR || cmp == GE_EXPR)
(with
{
......
2015-10-27 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/torture/builtin-sqrt-cmp-1.c: New test.
2015-10-27 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/builtins-52.c: Add -O to dg-options.
2015-10-27 Richard Sandiford <richard.sandiford@arm.com>
......
/* { dg-do link } */
/* { dg-options "-ffast-math" } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
extern double sqrt (double);
extern float sqrtf (float);
extern long double sqrtl (long double);
/* All references to link_error should go away at compile-time. */
extern void link_error (void);
#define TEST_ONE(SUFFIX, TYPE) \
void __attribute__ ((noinline, noclone)) \
test##SUFFIX (TYPE f, int *res) \
{ \
TYPE sqrt_res = sqrt##SUFFIX (f); \
res[0] = sqrt_res < 0; \
if (res[0]) \
link_error (); \
res[1] = sqrt_res <= 0; \
if (res[1] != (f == 0)) \
link_error (); \
res[2] = (sqrt_res == 0); \
if (res[2] != (f == 0)) \
link_error (); \
res[3] = (sqrt_res != 0); \
if (res[3] != (f != 0)) \
link_error (); \
res[4] = (sqrt_res > 0); \
if (res[4] != (f > 0)) \
link_error (); \
res[5] = (sqrt_res >= 0); \
if (!res[5]) \
link_error (); \
}
volatile float f;
volatile double d;
volatile long double ld;
TEST_ONE (f, float)
TEST_ONE (, double)
TEST_ONE (l, long double)
int
main ()
{
int res[6];
testf (f, res);
test (d, res);
testl (ld, res);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment