summaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-27 11:51:43 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-27 11:51:43 +0000
commitb5cb051268ac3cf810bb1fb84daabdc38c97cc94 (patch)
tree81cfb3c2323bef8e2dc2dea990e95e29dc92fc9d /gcc/match.pd
parente1da2e5d4c6b0c99577c44b705ffe07bcbedfe57 (diff)
downloadgcc-b5cb051268ac3cf810bb1fb84daabdc38c97cc94.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229422 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd19
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 26491d27840..b8e6b4643c8 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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
{