From patchwork Sat Sep 18 08:56:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 45156 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A27C6385C41B for ; Sat, 18 Sep 2021 08:56:58 +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 306533858001 for ; Sat, 18 Sep 2021 08:56:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 306533858001 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=JN3oGyXHtRR3fpLrOHdRIA/9T0xqUAzB9wATXHhzw3M=; b=AgHeTMDRPtTOMnlT8hH15iv7Py pIQHUA0CqAJmzcz2yYXoGHY1VEjd4zwt9BFZyKKC7NQI+kju474VgXz8pE4oQupa3C1uBIeU0zWbY iDvH1uVPVWglsN9/TW2IHHDA8siETwySrGiAGvJrRZTA6+qpE/GacPGkXhkKq3xtwdAneaKel/fVq 6bWLZ/JpLE1P1UJU2sVxyIze+1fDYJqJumLe3Xi02DUrSIsxudEF+bOHm2H3YT1tLqLSNj8gAcnGy HxOEYM6oT4WeGTtlFvsRtDyTCdnCtJ8eRu0J6IKVKaD9AbnPvl4BKqtrYlfZHOGnjwEYwFlAi93uV nXtLjL4Q==; Received: from host86-168-251-41.range86-168.btcentralplus.com ([86.168.251.41]:57383 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 1mRW9I-0003M1-Cc for gcc-patches@gcc.gnu.org; Sat, 18 Sep 2021 04:56:40 -0400 From: "Roger Sayle" To: "'GCC Patches'" Subject: [PATCH] PR middle-end/88173: More constant folding of NaN comparisons. Date: Sat, 18 Sep 2021 09:56:38 +0100 Message-ID: <003501d7ac6b$18663ab0$4932b010$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AdesajTsSIYQcgroQ6amz9H/hNe0Ig== 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=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch tackles PR middle-end/88173 where the order of operands in a comparison affects constant folding. As diagnosed by Jason Merrill, "match.pd handles these comparisons very differently". The history is that the middle end, typically canonicalizes comparisons to place constants on the right, but when a comparison contains two constants we need to check/transform both constants, i.e. on both the left and the right. Hence the added lines below duplicate for @0 the same transform applied a few lines above for @1. Whilst preparing the testcase, I noticed that this transformation is incorrectly disabled with -fsignaling-nans even when both operands are known not be be signaling NaNs, so I've corrected that and added a second test case. Unfortunately, c-c++-common/pr57371-4.c then starts failing, as it doesn't distinguish QNaNs (which are quiet) from SNaNs (which signal), so this patch includes a minor tweak to the expected behaviour for QNaNs in that existing test. I suspect the middle-end (both at the tree-level and RTL) might need to respect -ftrapping-math for the non-equality comparisons against QNaN, but that's a different PR/patch [I need to double check/research whether and why those checks may have been removed in the past]. This patch has been tested on x86_64-pc-linux-gnu with "make bootstrap" and "make -k check" with no new failures. Ok for mainline? 2021-09-18 Roger Sayle gcc/ChangeLog PR middle-end/88173 * match.pd (cmp @0 REAL_CST@1): When @0 is also REAL_CST, apply the same transformations as to @1. For comparisons against NaN, don't check HONOR_SNANS but confirm that neither operand is a signaling NaN. gcc/testsuite/ChangeLog PR middle-end/88173 * c-c++-common/pr57371-4.c: Tweak/correct test case for QNaNs. * g++.dg/pr88173-1.C: New test case. * g++.dg/pr88173-2.C: New test case. Roger --- /* { dg-do compile } */ /* { dg-options "-O2 -std=c++11" } */ #define big __builtin_huge_val() #define nan __builtin_nan("") constexpr bool b1 = big > nan; constexpr bool b2 = nan < big; /* { dg-do compile } */ /* { dg-options "-O2 -fsignaling-nans -std=c++11" } */ #define big __builtin_huge_val() #define nan __builtin_nan("") constexpr bool b1 = big > nan; constexpr bool b2 = nan < big; diff --git a/gcc/match.pd b/gcc/match.pd index 008f775..4a2f058 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4480,9 +4480,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* a CMP (-0) -> a CMP 0 */ (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1))) (cmp @0 { build_real (TREE_TYPE (@1), dconst0); })) + /* (-0) CMP b -> 0 CMP b. */ + (if (TREE_CODE (@0) == REAL_CST + && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@0))) + (cmp { build_real (TREE_TYPE (@0), dconst0); } @1)) /* x != NaN is always true, other ops are always false. */ (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1)) - && ! HONOR_SNANS (@1)) + && !tree_expr_signaling_nan_p (@1) + && !tree_expr_maybe_signaling_nan_p (@0)) + { constant_boolean_node (cmp == NE_EXPR, type); }) + /* NaN != y is always true, other ops are always false. */ + (if (TREE_CODE (@0) == REAL_CST + && REAL_VALUE_ISNAN (TREE_REAL_CST (@0)) + && !tree_expr_signaling_nan_p (@0) + && !tree_expr_signaling_nan_p (@1)) { constant_boolean_node (cmp == NE_EXPR, type); }) /* Fold comparisons against infinity. */ (if (REAL_VALUE_ISINF (TREE_REAL_CST (@1)) diff --git a/gcc/testsuite/c-c++-common/pr57371-4.c b/gcc/testsuite/c-c++-common/pr57371-4.c index f43f7c2..d938ecd 100644 --- a/gcc/testsuite/c-c++-common/pr57371-4.c +++ b/gcc/testsuite/c-c++-common/pr57371-4.c @@ -13,25 +13,25 @@ void nonfinite(unsigned short x) { { volatile int nonfinite_1; nonfinite_1 = (float) x > QNAN; - /* { dg-final { scan-tree-dump "nonfinite_1 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */ } { volatile int nonfinite_2; nonfinite_2 = (float) x >= QNAN; - /* { dg-final { scan-tree-dump "nonfinite_2 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */ } { volatile int nonfinite_3; nonfinite_3 = (float) x < QNAN; - /* { dg-final { scan-tree-dump "nonfinite_3 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */ } { volatile int nonfinite_4; nonfinite_4 = (float) x <= QNAN; - /* { dg-final { scan-tree-dump "nonfinite_4 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */ } {