From patchwork Thu Jun 10 19:44:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 1490636 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nextmovesoftware.com header.i=@nextmovesoftware.com header.a=rsa-sha256 header.s=default header.b=PFdQN2Eh; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G1Dvy6NJlz9sSs for ; Fri, 11 Jun 2021 05:45:01 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 25D6939A242C for ; Thu, 10 Jun 2021 19:44:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id 73286386FC1A for ; Thu, 10 Jun 2021 19:44:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 73286386FC1A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=9a4lc0/fpWuE2s+O8KMCv+1phEFmEnjd0ytnWOm9194=; b=PFdQN2EhPRcEdU2ZKh3hKgPUMO /gNOohyXti0LMaPrcIEsq7DeU86c/5BIT2udpBq++KxcXMajpZEQTWDLCrolAowb0UlFOE8blc1Vi 1ZDlA2JIcq+3qoYPpfoqS9XgPr5KnO1Tzt05CO56QIQT2osucH7gVH5ZfYayY+RAMsh0SRDSZuunq dEisFHs4yDds1YaxiyW6P876OXdatBzkyMC1YUNAZRNVPs3P3qq+E4E626sRlqdfOM6fEdV/JPW3k cVFBbBmsIrIwscbHyWi+CM2KOC75Wceg8YE9hwF8ztFDoKJxHe7ejX5zgFnWmnLXDdb/3szZKB4bf DuxUOufA==; Received: from [185.62.158.67] (port=52283 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1lrQbd-0002ou-QN for gcc-patches@gcc.gnu.org; Thu, 10 Jun 2021 15:44:46 -0400 From: "Roger Sayle" To: "'GCC Patches'" Subject: [PATCH] PR tree-optimization/96392 Optimize x+0.0 if x is an integer Date: Thu, 10 Jun 2021 20:44:44 +0100 Message-ID: <024401d75e31$10edfe40$32c9fac0$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AddeL39fnv3rRUQlQJGvOU2xyfNG4Q== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The patch implements a missed optimization enhancement. Under usual IEEE rules, x+0.0 can't be simplified to x when x might potentially be an IEEE minus zero (-0.0). The current logic in the middle-end checks whether the type of x should honor signed zeros, but with this patch we introduce tree_expr_maybe_real_minus_zero_p that allows us to confirm that the value can't possibly be -0.0, for example, the result of a conversion from an integer type, or the result of fabs (or has a type that doesn't honor signed zero). Whilst modifying match.pd, I also converted some additional folding transformations from "testing the type" to "testing the value". The following patch has been tested on x86_64-pc-linux-gnu with a make bootstrap and make -k check with no new failures. Ok for mainline? 2020-06-10 Roger Sayle gcc/ChangeLog PR tree-optimization/96392 * fold-const.c (fold_real_zero_addition_p): Take both arguments of the addition or subtraction, not just the zero. Use this other argument in tests for signaling NaNs and signed zeros. (tree_expr_maybe_real_minus_zero_p): New predicate. * fold-const.h (fold_real_zero_addition_p): Update prototype. (tree_expr_maybe_real_minus_zero_p): New function prototype. * match.pd: Update calls to fold_real_zero_addition_p. Replace HONOR_NANS with tree_expr_maybe_nan_p. Replace HONOR_SIGNED_ZEROS with tree_expr_maybe_real_minus_zero_p. Replace HONOR_SNANS with tree_expr_maybe_signaling_nan_p. * tree-ssa-reassoc.c (eliminate_using_constants): Update call to fold_real_zero_addition_p. gcc/testsuite/ChangeLog PR tree-optimization/96392 * gcc.dg/pr96392.c: New test. Roger --- Roger Sayle NextMove Software Cambridge, UK /* PR tree-optimization/96392 */ /* { dg-do compile } */ /* { dg-options "-O -fdump-tree-optimized" } */ double plus0(int x) { return x + 0.0; } double sub0(int x) { return x - 0.0; } double mult0(int x) { return 0.0 * x; } double negate(int x) { return 0.0 - x; } double subtract(int x) { return (double)x - (double)x; } /* { dg-final { scan-tree-dump-not " \\+ " "optimized" } } */ /* { dg-final { scan-tree-dump-not " \\- " "optimized" } } */ /* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6e5835a..95673d2 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7127,11 +7127,13 @@ fold_binary_op_with_conditional_arg (location_t loc, } -/* Subroutine of fold() that checks for the addition of +/- 0.0. +/* Subroutine of fold() that checks for the addition of ARG +/- 0.0. - If !NEGATE, return true if ADDEND is +/-0.0 and, for all X of type - TYPE, X + ADDEND is the same as X. If NEGATE, return true if X - - ADDEND is the same as X. + If !NEGATE, return true if ZERO_ARG is +/-0.0 and, for all ARG of + type TYPE, ARG + ZERO_ARG is the same as ARG. If NEGATE, return true + if ARG - ZERO_ARG is the same as X. + + If ARG is NULL, check for any value of type TYPE. X + 0 and X - 0 both give X when X is NaN, infinite, or nonzero and finite. The problematic cases are when X is zero, and its mode @@ -7140,13 +7142,14 @@ fold_binary_op_with_conditional_arg (location_t loc, modes, X + 0 is not the same as X because -0 + 0 is 0. */ bool -fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) +fold_real_zero_addition_p (const_tree type, const_tree arg, + const_tree zero_arg, int negate) { - if (!real_zerop (addend)) + if (!real_zerop (zero_arg)) return false; /* Don't allow the fold with -fsignaling-nans. */ - if (HONOR_SNANS (type)) + if (arg ? tree_expr_maybe_signaling_nan_p (arg) : HONOR_SNANS (type)) return false; /* Allow the fold if zeros aren't signed, or their sign isn't important. */ @@ -7158,19 +7161,20 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) return false; /* In a vector or complex, we would need to check the sign of all zeros. */ - if (TREE_CODE (addend) == VECTOR_CST) - addend = uniform_vector_p (addend); - if (!addend || TREE_CODE (addend) != REAL_CST) + if (TREE_CODE (zero_arg) == VECTOR_CST) + zero_arg = uniform_vector_p (zero_arg); + if (!zero_arg || TREE_CODE (zero_arg) != REAL_CST) return false; /* Treat x + -0 as x - 0 and x - -0 as x + 0. */ - if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend))) + if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (zero_arg))) negate = !negate; /* The mode has signed zeros, and we have to honor their sign. - In this situation, there is only one case we can return true for. - X - 0 is the same as X with default rounding. */ - return negate; + In this situation, there are only two cases we can return true for. + (i) X - 0 is the same as X with default rounding. + (ii) X + 0 is X when X can't possibly be -0.0. */ + return negate || (arg && !tree_expr_maybe_real_minus_zero_p (arg)); } /* Subroutine of match.pd that optimizes comparisons of a division by @@ -14375,6 +14379,44 @@ tree_expr_maybe_nan_p (const_tree x) } } +/* Return true if expression X could evaluate to -0.0. + This function returns true if uncertain. */ + +bool +tree_expr_maybe_real_minus_zero_p (const_tree x) +{ + if (!HONOR_SIGNED_ZEROS (x)) + return false; + switch (TREE_CODE (x)) + { + case REAL_CST: + return REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (x)); + case INTEGER_CST: + case FLOAT_EXPR: + case ABS_EXPR: + return false; + case NON_LVALUE_EXPR: + case SAVE_EXPR: + return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 0)); + case COND_EXPR: + return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 1)) + || tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 2)); + case CALL_EXPR: + switch (get_call_combined_fn (x)) + { + CASE_CFN_FABS: + return false; + default: + break; + } + default: + break; + } + /* Ideally !(tree_expr_nonzero_p (X) || tree_expr_nonnegative_p (X)) + * but currently those predicates require tree and not const_tree. */ + return true; +} + #define tree_expr_nonnegative_warnv_p(X, Y) \ _Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0 diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 2a74287..0d8d786 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -164,7 +164,8 @@ extern bool integer_valued_real_call_p (combined_fn, tree, tree, int); extern bool integer_valued_real_single_p (tree, int); extern bool integer_valued_real_p (tree, int = 0); -extern bool fold_real_zero_addition_p (const_tree, const_tree, int); +extern bool fold_real_zero_addition_p (const_tree, const_tree, const_tree, + int); extern tree combine_comparisons (location_t, enum tree_code, enum tree_code, enum tree_code, tree, tree, tree); extern void debug_fold_checksum (const_tree); @@ -195,6 +196,7 @@ extern bool tree_expr_signaling_nan_p (const_tree); extern bool tree_expr_maybe_signaling_nan_p (const_tree); extern bool tree_expr_nan_p (const_tree); extern bool tree_expr_maybe_nan_p (const_tree); +extern bool tree_maybe_real_minus_zero_p (const_tree); extern tree make_range (tree, int *, tree *, tree *, bool *); extern tree make_range_step (location_t, enum tree_code, tree, tree, tree, tree *, tree *, int *, bool *); diff --git a/gcc/match.pd b/gcc/match.pd index d06ff17..b5ed87f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -152,13 +152,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) Likewise if the operands are reversed. */ (simplify (plus:c @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 0)) + (if (fold_real_zero_addition_p (type, @0, @1, 0)) (non_lvalue @0))) /* See if ARG1 is zero and X - ARG1 reduces to X. */ (simplify (minus @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 1)) + (if (fold_real_zero_addition_p (type, @0, @1, 1)) (non_lvalue @0))) /* Even if the fold_real_zero_addition_p can't simplify X + 0.0 @@ -190,7 +190,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) is volatile. */ (simplify (minus @0 @0) - (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (type)) + (if (!FLOAT_TYPE_P (type) || !tree_expr_maybe_nan_p (@0)) { build_zero_cst (type); })) (simplify (pointer_diff @@0 @0) @@ -206,14 +206,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) negative value by 0 gives -0, not +0. */ (simplify (mult @0 real_zerop@1) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@1)) @1)) /* In IEEE floating point, x*1 is not equivalent to x for snans. Likewise for complex arithmetic with signed zeros. */ (simplify (mult @0 real_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (non_lvalue @0))) @@ -221,7 +223,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform x * -1.0 into -x. */ (simplify (mult @0 real_minus_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) @@ -259,7 +261,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? 1.0 : -1.0) into -abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_onep@1 real_minus_onep)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outp (abs @0)))) /* Transform X * (X > 0.0 ? -1.0 : 1.0) into -abs(X). */ /* Transform X * (X >= 0.0 ? -1.0 : 1.0) into -abs(X). */ @@ -267,19 +269,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? -1.0 : 1.0) into abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_minus_onep real_onep@1)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outn (abs @0))))) /* Transform X * copysign (1.0, X) into abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep @0)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (abs @0))) /* Transform X * copysign (1.0, -X) into -abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep (negate @0))) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (negate (abs @0)))) /* Transform copysign (CST, X) into copysign (ABS(CST), X). */ @@ -444,13 +446,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* In IEEE floating point, x/1 is not equivalent to x for snans. */ (simplify (rdiv @0 real_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (non_lvalue @0))) /* In IEEE floating point, x/-1 is not equivalent to -x for snans. */ (simplify (rdiv @0 real_minus_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (negate @0))) (if (flag_reciprocal_math) @@ -3543,7 +3545,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (-ARG1 + ARG0) reduces to -ARG1. */ (simplify (minus real_zerop@0 @1) - (if (fold_real_zero_addition_p (type, @0, 0)) + (if (fold_real_zero_addition_p (type, @1, @0, 0)) (negate @1))) /* Transform x * -1 into -x. */ diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 6dfc703..2dd4435 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -1062,7 +1062,7 @@ eliminate_using_constants (enum tree_code opcode, if (integer_zerop (oelast->op) || (FLOAT_TYPE_P (type) && (opcode == PLUS_EXPR || opcode == MINUS_EXPR) - && fold_real_zero_addition_p (type, oelast->op, + && fold_real_zero_addition_p (type, 0, oelast->op, opcode == MINUS_EXPR))) { if (ops->length () != 1)