From patchwork Mon Dec 5 15:33:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 29735 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2323054wrr; Mon, 5 Dec 2022 07:34:49 -0800 (PST) X-Google-Smtp-Source: AA0mqf7U4Uy5Mx5YbnP2byH1lJMqC54P6WseZDE6NeOcqYwsLugrxYuQVZfEx8jS1zlQL7OqELPo X-Received: by 2002:a17:907:6284:b0:7c0:fa5f:9dbe with SMTP id nd4-20020a170907628400b007c0fa5f9dbemr3102225ejc.281.1670254489473; Mon, 05 Dec 2022 07:34:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670254489; cv=none; d=google.com; s=arc-20160816; b=kcXCG62KuQ1jYH+S54AM6r7z2RYEPQeEz6nP1g/USyRm3vLPISXuJ9wGVPcTs0EYiI wOv7io708QZiMzX6Arns5/XKBNbDkxPTMbdVzgPwyhPgHfnT7JbrIYUhsybuAGCfFmSC XVKFVDrofy4yw/odFk1XWNj3bnjZatLC+XLTlzR/ukH2XHxzbw3QAFELmfOgYsnHKwnB wXhBDEuFYqF6Pcxycpuqia7CTkTObxTBvnIe/Z7lELwTpjk2ljM4WEU/CTk3B61KtWQr r7mEyoVly2dfKEjgH0RyHHUKt2gopn/gQrNG9B0LgD1M00aGLsFDbdvUuoOhuih7LBSH lWrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:cc:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=Sj0ZTIZeLgIdtVEBdGjR9+gtVklnFBomHjcff3JjBps=; b=jIjEdmf3AocmLhs/cAYqFWYbTRFmc2n8Bx2HE5pYRazw7hgGCEJ05Mj4nfvVyQCMED LwwPYhGBjJBbRqEt1jrLKbOvR7iLDHsono5EpdypQUW4dnkhccCCIOE9eit6TwnCWV7m 9qFCwzSbIZpeoLEkXlKz+5umIF5mlIwUCM1CuCDqNLFJrookaYs/EnFaURKXdKOnn6aE 0XbzgtbFCH/QGkXspU/Lpx3GXfJqTyOmGAdEhFS7nfotNDiEbRFBNUZalAb3vxVATvpc 4V+/nCKt6lfmWiblkpGciR4AeEqL4wzFLBx4b+RIy86kZpPFdZfyKTWjjgHq/ro0xpdo U7DA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=D2hDvQLC; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id gt7-20020a1709072d8700b007897abd2d17si8371563ejc.468.2022.12.05.07.34.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Dec 2022 07:34:49 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=D2hDvQLC; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 01585392AC09 for ; Mon, 5 Dec 2022 15:34:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 01585392AC09 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670254488; bh=Sj0ZTIZeLgIdtVEBdGjR9+gtVklnFBomHjcff3JjBps=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=D2hDvQLCX6k2bwksPVismn1inMyd29eryswhYOWlKUHM0msShp+TFhJTTsQRFHtmC E5bjxiKb7vYhAoKwlufUH4m+f5L/I0e2oS4YTKnbv6ngT9cnRo+nNAa+ucMk1FOAO4 KsG1/m/Hk97Sv8jUO4inwJf1oGGoKhv9lQLtQ/gE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 09D6238AA27B for ; Mon, 5 Dec 2022 15:34:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 09D6238AA27B Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-283-xV7fo3zfMdGSez6pfzl2tg-1; Mon, 05 Dec 2022 10:33:59 -0500 X-MC-Unique: xV7fo3zfMdGSez6pfzl2tg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 957533813F26 for ; Mon, 5 Dec 2022 15:33:59 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.195.114]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4A8222027062; Mon, 5 Dec 2022 15:33:59 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 2B5FXsvf3418473 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 5 Dec 2022 16:33:54 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 2B5FXsdr3418472; Mon, 5 Dec 2022 16:33:54 +0100 Date: Mon, 5 Dec 2022 16:33:53 +0100 To: Aldy Hernandez Cc: gcc-patches@gcc.gnu.org, Andrew MacLeod Subject: [PATCH] range-op-float: Improve binary reverse operations Message-ID: References: <1f2b50a8-8f3c-690a-182b-c636fc2f86ed@redhat.com> <32b96813-616d-ba73-811f-8a36e70f9ecd@redhat.com> MIME-Version: 1.0 In-Reply-To: <32b96813-616d-ba73-811f-8a36e70f9ecd@redhat.com> X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1751388771443966984?= X-GMAIL-MSGID: =?utf-8?q?1751388771443966984?= Hi! On Mon, Dec 05, 2022 at 02:29:36PM +0100, Aldy Hernandez wrote: > > So like this for multiplication op1/2_range if it passes bootstrap/regtest? > > For division I'll need to go to a drawing board... > > Sure, looks good to me. Ulrich just filed PR107972, so in the light of that PR the following patch attempts to do that differently. Is this also ok if it passes bootstrap/regtest? As for testcase, I've tried both attached testcases, but unfortunately it seems that in neither of the cases we actually figure out that res range is finite (or for last function non-zero ordered). So there is further work needed on that. 2022-12-05 Jakub Jelinek PR tree-optimization/107972 * range-op-float.cc (frange_drop_infs): New function. (float_binary_op_range_finish): Add OP argument. If OP is not RDIV_EXPR and lhs is finite, r must be finite too. (foperator_plus::op1_range, foperator_minus::op1_range, foperator_minus::op2_range, foperator_mult::op1_range): Pass operation code to float_binary_op_range_finish. (foperator_div::op1_range): Pass RDIV_EXPR to float_binary_op_range_finish. If lhs is finite, r must be finite too. (foperator_div::op2_range): Pass RDIV_EXPR to float_binary_op_range_finish. If lhs is not NAN nor zero, r must be finite. Jakub double foo (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a + b; if (!__builtin_isfinite (res)) __builtin_unreachable (); return res; } double bar (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a - b; if (!__builtin_isfinite (res)) __builtin_unreachable (); return res; } double baz (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a * b; if (!__builtin_isfinite (res)) __builtin_unreachable (); return res; } double qux (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; double res = a / b; if (!__builtin_isfinite (res)) __builtin_unreachable (); return res; } double quux (double a, double b) { if (!__builtin_isfinite (b)) return 42.0; double res = a / b; if (__builtin_isnan (res) || res == 0.0) __builtin_unreachable (); return res; } double foo (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a + b; __attribute__((assume (__builtin_isfinite (res)))); return res; } double bar (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a - b; __attribute__((assume (__builtin_isfinite (res)))); return res; } double baz (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; if (!__builtin_isfinite (b)) return 42.0; double res = a * b; __attribute__((assume (__builtin_isfinite (res)))); return res; } double qux (double a, double b) { if (!__builtin_isfinite (a)) return 42.0; double res = a / b; __attribute__((assume (__builtin_isfinite (res)))); return res; } double quux (double a, double b) { if (!__builtin_isfinite (b)) return 42.0; double res = a / b; __attribute__((assume (!__builtin_isnan (res) && res != 0.0))); return res; } --- gcc/range-op-float.cc.jj 2022-12-05 11:17:34.900573272 +0100 +++ gcc/range-op-float.cc 2022-12-05 16:13:54.414845672 +0100 @@ -330,6 +330,18 @@ frange_drop_ninf (frange &r, tree type) r.intersect (tmp); } +// Crop R to [MIN, MAX] where MAX is the maximum representable number +// for TYPE and MIN the minimum representable number for TYPE. + +static inline void +frange_drop_infs (frange &r, tree type) +{ + REAL_VALUE_TYPE max = real_max_representable (type); + REAL_VALUE_TYPE min = real_min_representable (type); + frange tmp (type, min, max); + r.intersect (tmp); +} + // If zero is in R, make sure both -0.0 and +0.0 are in the range. static inline void @@ -1883,7 +1895,7 @@ foperator_unordered_equal::op1_range (fr static bool float_binary_op_range_finish (bool ret, frange &r, tree type, - const frange &lhs) + const frange &lhs, enum tree_code op) { if (!ret) return false; @@ -1904,7 +1916,16 @@ float_binary_op_range_finish (bool ret, // If lhs isn't NAN, then neither operand could be NAN, // even if the reverse operation does introduce a maybe_nan. if (!lhs.maybe_isnan ()) - r.clear_nan (); + { + r.clear_nan (); + if (op != RDIV_EXPR + && !real_isinf (&lhs.lower_bound ()) + && !real_isinf (&lhs.upper_bound ())) + // For reverse + or - or *, if result is finite, then r must + // be finite too, as X + INF or X - INF or X * INF is always + // +-INF or NAN. For division handle it in the caller. + frange_drop_infs (r, type); + } // If lhs is a maybe or known NAN, the operand could be // NAN. else @@ -2020,7 +2041,7 @@ public: if (!minus) return false; return float_binary_op_range_finish (minus.fold_range (r, type, lhs, op2), - r, type, lhs); + r, type, lhs, PLUS_EXPR); } virtual bool op2_range (frange &r, tree type, const frange &lhs, @@ -2067,7 +2088,7 @@ public: return false; return float_binary_op_range_finish (fop_plus.fold_range (r, type, lhs, op2), - r, type, lhs); + r, type, lhs, MINUS_EXPR); } virtual bool op2_range (frange &r, tree type, const frange &lhs, @@ -2077,7 +2098,7 @@ public: if (lhs.undefined_p ()) return false; return float_binary_op_range_finish (fold_range (r, type, op1, lhs), - r, type, lhs); + r, type, lhs, MINUS_EXPR); } private: void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan, @@ -2166,7 +2187,7 @@ public: // or if lhs must be zero and op2 doesn't include zero, it would be // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF // range. Those are supersets of UNDEFINED, so let's keep that way. - return float_binary_op_range_finish (ret, r, type, lhs); + return float_binary_op_range_finish (ret, r, type, lhs, MULT_EXPR); } virtual bool op2_range (frange &r, tree type, const frange &lhs, @@ -2313,7 +2334,12 @@ public: zero_to_inf_range (lb, ub, signbit_known); r.set (type, lb, ub); } - return float_binary_op_range_finish (ret, r, type, lhs); + // If lhs must be finite (can't be +-INF nor NAN), then op1 must be + // finite too - +-INF / anything is either +-INF or NAN (NAN if op2 is + // +-INF or NAN). + if (!real_isinf (&lhs_lb) && !real_isinf (&lhs_ub) && !lhs.maybe_isnan ()) + frange_drop_infs (r, type); + return float_binary_op_range_finish (ret, r, type, lhs, RDIV_EXPR); } virtual bool op2_range (frange &r, tree type, const frange &lhs, @@ -2341,7 +2367,11 @@ public: zero_to_inf_range (lb, ub, signbit_known); r.set (type, lb, ub); } - return float_binary_op_range_finish (ret, r, type, lhs); + // If lhs can't be zero nor NAN, then op2 must be finite - anything / +-INF + // is either +-0 or NAN (NAN if op1 is +-INF or NAN). + if (!contains_zero_p (lhs_lb, lhs_ub) && !lhs.maybe_isnan ()) + frange_drop_infs (r, type); + return float_binary_op_range_finish (ret, r, type, lhs, RDIV_EXPR); } private: void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,