From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15987 invoked by alias); 7 May 2019 07:21:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 15978 invoked by uid 89); 7 May 2019 07:21:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.1 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,GIT_PATCH_3,SPF_HELO_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 07 May 2019 07:21:52 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BCD8E3082E24; Tue, 7 May 2019 07:21:51 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-81.ams2.redhat.com [10.36.116.81]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 629BC5B097; Tue, 7 May 2019 07:21:51 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id x477Lnqb029922; Tue, 7 May 2019 09:21:49 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id x477LkiP029921; Tue, 7 May 2019 09:21:46 +0200 Date: Tue, 07 May 2019 07:21:00 -0000 From: Jakub Jelinek To: Richard Biener , Jeff Law , Marc Glisse Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Fold (x + 0.0) + 0.0 to x + 0.0 (PR tree-optimization/90356) Message-ID: <20190507072146.GG2706@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.11.3 (2019-02-01) X-IsSubscribed: yes X-SW-Source: 2019-05/txt/msg00261.txt.bz2 Hi! fold_real_zero_addition_p will fold x + (-0.0) or x - 0.0 to x when not -frounding-math, but not the rest of the options when -fsigned-zeros, and not when -fsignaling-nans. If we have (x + 0.0) + 0.0, we can fold that to just x + 0.0 even when honoring signed zeros, and IMNSHO even when honoring sNaNs, of course unless -frounding-math, then we can't do anything. For x other than 0.0, -0.0 and sNaN it is obviously correct, for sNaN sNaN + 0.0 will raise an exception and turn the result into qNaN, which will not raise further exception on the second addition, so IMHO it is ok too (unless we want to say special case -fnon-call-exceptions and the exception handler changing the result back to sNaN and expecting yet another exception). For 0.0/-0.0 if we can assume rounding other than towards negative infinity, the results are: x x (0.0 + 0.0) + 0.0 = 0.0 = (0.0 + 0.0) (-0.0 + 0.0) + 0.0 = 0.0 = (-0.0 + 0.0) (0.0 - 0.0) - 0.0 = 0.0 = (0.0 - 0.0) (-0.0 - 0.0) - 0.0 = -0.0 = (-0.0 - 0.0) (0.0 + 0.0) - 0.0 = 0.0 = (0.0 + 0.0) (-0.0 + 0.0) - 0.0 = 0.0 = (-0.0 + 0.0) For the above ones, the two operations are always equal to the inner operation (0.0 - 0.0) + 0.0 = 0.0 = 0.0 + 0.0 (-0.0 - 0.0) + 0.0 = 0.0 = -0.0 + 0.0 For the above cases, the two operations are always equal to the outer operation If it is y + (-0.0), it is equivalent to y - 0.0 and if it is y - (-0.0), it is equivalent to y + 0.0 in the above. For rounding towards negative infinity, 0.0 - 0.0 is -0.0 rather than 0.0 and so some of the above equivalencies are not true. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-05-07 Jakub Jelinek PR tree-optimization/90356 * match.pd ((X +/- 0.0) +/- 0.0): Optimize into X +/- 0.0 if possible. * gcc.dg/tree-ssa/pr90356-1.c: New test. * gcc.dg/tree-ssa/pr90356-2.c: New test. * gcc.dg/tree-ssa/pr90356-3.c: New test. * gcc.dg/tree-ssa/pr90356-4.c: New test. --- gcc/match.pd.jj 2019-05-03 15:22:07.370401908 +0200 +++ gcc/match.pd 2019-05-06 11:26:04.701663020 +0200 @@ -152,6 +152,28 @@ (define_operator_list COND_TERNARY (if (fold_real_zero_addition_p (type, @1, 1)) (non_lvalue @0))) +/* Even if the fold_real_zero_addition_p can't simplify X + 0.0 + into X, we can optimize (X + 0.0) + 0.0 or (X + 0.0) - 0.0 + or (X - 0.0) + 0.0 into X + 0.0 and (X - 0.0) - 0.0 into X - 0.0 + if not -frounding-math. For sNaNs the first operation would raise + exceptions but turn the result into qNan, so the second operation + would not raise it. */ +(for inner_op (plus minus) + (for outer_op (plus minus) + (simplify + (outer_op (inner_op @0 real_zerop@1) real_zerop@2) + (if (TREE_CODE (@1) == REAL_CST + && TREE_CODE (@2) == REAL_CST + && HONOR_SIGNED_ZEROS (element_mode (type)) + && !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))) + (with { bool plus1 = ((inner_op == PLUS_EXPR) + ^ REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1))); + bool plus2 = ((outer_op == PLUS_EXPR) + ^ REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@2))); } + (if (plus2 && !plus1) + (outer_op @0 @2) + (inner_op @0 @1))))))) + /* Simplify x - x. This is unsafe for certain floats even in non-IEEE formats. In IEEE, it is unsafe because it does wrong for NaNs. --- gcc/testsuite/gcc.dg/tree-ssa/pr90356-1.c.jj 2019-05-06 11:39:58.998288472 +0200 +++ gcc/testsuite/gcc.dg/tree-ssa/pr90356-1.c 2019-05-06 11:42:53.597489688 +0200 @@ -0,0 +1,23 @@ +/* PR tree-optimization/90356 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-rounding-math -fsignaling-nans -fsigned-zeros -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "x_\[0-9]*.D. \\+ 0.0;" 12 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "y_\[0-9]*.D. - 0.0;" 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \[+-] 0.0;" 16 "optimized" } } */ + +double f1 (double x) { return (x + 0.0) + 0.0; } +double f2 (double y) { return (y + (-0.0)) + (-0.0); } +double f3 (double y) { return (y - 0.0) - 0.0; } +double f4 (double x) { return (x - (-0.0)) - (-0.0); } +double f5 (double x) { return (x + 0.0) - 0.0; } +double f6 (double x) { return (x + (-0.0)) - (-0.0); } +double f7 (double x) { return (x - 0.0) + 0.0; } +double f8 (double x) { return (x - (-0.0)) + (-0.0); } +double f9 (double x) { double t = x + 0.0; return t + 0.0; } +double f10 (double y) { double t = y + (-0.0); return t + (-0.0); } +double f11 (double y) { double t = y - 0.0; return t - 0.0; } +double f12 (double x) { double t = x - (-0.0); return t - (-0.0); } +double f13 (double x) { double t = x + 0.0; return t - 0.0; } +double f14 (double x) { double t = x + (-0.0); return t - (-0.0); } +double f15 (double x) { double t = x - 0.0; return t + 0.0; } +double f16 (double x) { double t = x - (-0.0); return t + (-0.0); } --- gcc/testsuite/gcc.dg/tree-ssa/pr90356-2.c.jj 2019-05-06 11:43:07.232271129 +0200 +++ gcc/testsuite/gcc.dg/tree-ssa/pr90356-2.c 2019-05-06 11:45:41.145803937 +0200 @@ -0,0 +1,8 @@ +/* PR tree-optimization/90356 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-rounding-math -fno-signaling-nans -fsigned-zeros -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "x_\[0-9]*.D. \\+ 0.0;" 12 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "y_\[0-9]*.D. - 0.0;" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \[+-] 0.0;" 12 "optimized" } } */ + +#include "pr90356-1.c" --- gcc/testsuite/gcc.dg/tree-ssa/pr90356-3.c.jj 2019-05-06 11:45:05.056382441 +0200 +++ gcc/testsuite/gcc.dg/tree-ssa/pr90356-3.c 2019-05-06 11:47:19.779222871 +0200 @@ -0,0 +1,6 @@ +/* PR tree-optimization/90356 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -frounding-math -fsignaling-nans -fsigned-zeros -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " \[+-] 0.0;" 32 "optimized" } } */ + +#include "pr90356-1.c" --- gcc/testsuite/gcc.dg/tree-ssa/pr90356-4.c.jj 2019-05-06 11:46:02.140467400 +0200 +++ gcc/testsuite/gcc.dg/tree-ssa/pr90356-4.c 2019-05-06 11:47:28.175088284 +0200 @@ -0,0 +1,6 @@ +/* PR tree-optimization/90356 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -frounding-math -fno-signaling-nans -fsigned-zeros -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times " \[+-] 0.0;" 32 "optimized" } } */ + +#include "pr90356-1.c" Jakub