From patchwork Mon Apr 3 19:53:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 78704 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp2547816vqo; Mon, 3 Apr 2023 12:54:49 -0700 (PDT) X-Google-Smtp-Source: AKy350aT30jPoYSadENMBchSTq6BXaxyLZwFKeOTrzYFr6S0SAqMBQfqxTAxhXp162LYFZQpSmfK X-Received: by 2002:a17:906:11d6:b0:93b:68a8:a0e0 with SMTP id o22-20020a17090611d600b0093b68a8a0e0mr34327151eja.16.1680551689180; Mon, 03 Apr 2023 12:54:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680551689; cv=none; d=google.com; s=arc-20160816; b=nA9G+XYskUGRFOSq5Z8SCJVmWxQnhGQIIk+0VlsCOOF7d/jizV/SlmsB/F0YldiJ2R sDDTsiJuPRTKBc5IVmX/hJGJpJKyd2Q9vots1TEYwCMxTm5E1O4XOG2YjkZ0yJjyqKPx PK9l1OkH5S5J3A5NnN3AI5665gPy7ZcbIsdVRNXIzEcAJMq074Lh4ITBLYk37aX4vEeO jf7RWvlI+OJhnEGo9U1i2IhPCYcB0Ru1G3iISlfOYg/kBVo40N0y6cZapnalUdcB4jB1 YxiLS3M5PQeJLU3qGn97dQwqNZZfqZOoBLefCSxbO9kQ+jZ+orB2YdDYYHJolY0tgNTD cGsg== 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:mime-version:message-id:subject:cc:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=vGwPu6FV1yVvfp/Qdsdpp3TKAAL5gD3j6Epc5Y7Nbgs=; b=ePADwmXjhOuUXVm8+cRGUJ92na2CGtzvZ3+u2aEWZDiXAj8z9wBButHIYaDezNmn2C 25OeuSC7Axvnnx108bP9d+4FyVRgPmNiLjv+apCuhlQ7nyxipXIbBlxHsKRsCZ12F/f9 Xv30ZVSuNSOz/Fb14ws76RgzJN7dFOlc8wzGwxmkZiHGFTlvavXn+p/uoteoaxDm/+bM 5SM5jKzjCekf2g55+AfWr81bAkuMBLChEn6ZRVVrTXR05guCclK2g6GjbFM3Jp/Ckhvh dko9aTPQWWri0Dx70D1FPgUORcnBT7PWeg8c/sUkYHJbpMGazqgr9fjwl35u/C89fIgv 9Maw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=CXWCQ7zf; 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 (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id n8-20020aa7c448000000b004fd22862030si8407625edr.502.2023.04.03.12.54.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Apr 2023 12:54:49 -0700 (PDT) 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=CXWCQ7zf; 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 06B5A3858428 for ; Mon, 3 Apr 2023 19:54:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 06B5A3858428 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1680551688; bh=vGwPu6FV1yVvfp/Qdsdpp3TKAAL5gD3j6Epc5Y7Nbgs=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=CXWCQ7zfXGvHlJ3vbTb3gIqKNrdlwaHSbMZd3eOIdgLuPsYEu4R/j7kuaJjyBEbN+ CkZ0a6GSM1NgWTk+hgjIHIqifELZsIm+Bkzv6EoP/aZSj6rzMBns+EbvBy2TrbPLp7 TRQsWspqDL8TI/SdXhqAKZOVEBuzK23zDIZ1aOKs= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id D56323858D39 for ; Mon, 3 Apr 2023 19:54:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D56323858D39 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-616-pNst7_muNuiQYniU35qlaw-1; Mon, 03 Apr 2023 15:54:02 -0400 X-MC-Unique: pNst7_muNuiQYniU35qlaw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DED09886065 for ; Mon, 3 Apr 2023 19:54:01 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.16]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A19E3492C13; Mon, 3 Apr 2023 19:54:01 +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 333Jrx6j1755092 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 3 Apr 2023 21:53:59 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 333JrwJZ1755091; Mon, 3 Apr 2023 21:53:58 +0200 Date: Mon, 3 Apr 2023 21:53:58 +0200 To: Andrew MacLeod , Aldy Hernandez Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] range-op-float: Fix reverse ops of comparisons [PR109386] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.3 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?1762186167807386453?= X-GMAIL-MSGID: =?utf-8?q?1762186167807386453?= Hi! I've missed one of my recent range-op-float.cc changes (likely the r13-6967 one) caused FAIL: libphobos.phobos/std/math/algebraic.d execution test FAIL: libphobos.phobos_shared/std/math/algebraic.d execution test regressions, distilled into a C testcase below. In the testcase, we have !(u >= v) condition where both u and v are results of fabs*, which guards t1 = u u<= __FLT_MAX__; and t2 = v u<= __FLT_MAX__; comparisons. From false u >= v where u and v have [0.0, +Inf] NAN ranges we (incorrectly deduce that one of them is [nextafterf (0.0, 1.0), +Inf] NAN and the other is [0.0, nextafterf (+Inf, 0.0)] NAN and from that deduce that one of the comparisons is always true, because UNLE_EXPR with the maximum representable number are false only if the value is +Inf and our ranges tell that is not possible. The bug is that the u >= v comparison determines a sensible range only when it is true - we then know neither operand can be NAN and it behaves correctly. But when the comparison is false, our current code gives sensible answers only if the other op can't be NAN. If it can be NAN, whenever it is NAN, the comparison is always false regardless of the other value, so the other value needs to be VARYING. Now, foperator_unordered_lt::op1_range etc. had code to deal with that for op?.known_nan (), but as the testcase shows, it is enough if it may be a NAN at runtime to make it VARYING. So, the following patch replaces for all those BRS_FALSE cases of the normal non-equality comparisons if (opOTHER.known_isnan ()) r.set_varying (type); to do it also if maybe_isnan (). For the unordered or ... comparisons, it is similar for BRS_TRUE. Those comparisons are true whenever either operand is NAN, or if neither is NAN, the corresponding normal comparison. So, if those comparisons are true and other operand might be a NAN, we can't tell (VARYING), if it is false, currently handling is correct. Bootstrapped/regtested on x86_64-linux and i686-linux, fixes those 2 D testcases and the newly added one. Ok for trunk? 2023-04-03 Jakub Jelinek PR tree-optimization/109386 * range-op-float.cc (foperator_lt::op1_range, foperator_lt::op2_range, foperator_le::op1_range, foperator_le::op2_range, foperator_gt::op1_range, foperator_gt::op2_range, foperator_ge::op1_range, foperator_ge::op2_range): Make r varying for BRS_FALSE case even if the other op is maybe_isnan, not just known_isnan. (foperator_unordered_lt::op1_range, foperator_unordered_lt::op2_range, foperator_unordered_le::op1_range, foperator_unordered_le::op2_range, foperator_unordered_gt::op1_range, foperator_unordered_gt::op2_range, foperator_unordered_ge::op1_range, foperator_unordered_ge::op2_range): Make r varying for BRS_TRUE case even if the other op is maybe_isnan, not just known_isnan. * gcc.c-torture/execute/ieee/pr109386.c: New test. Jakub --- gcc/range-op-float.cc.jj 2023-04-03 10:42:54.000000000 +0200 +++ gcc/range-op-float.cc 2023-04-03 13:31:01.163216123 +0200 @@ -889,7 +889,7 @@ foperator_lt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x < NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else build_ge (r, type, op2); @@ -926,7 +926,7 @@ foperator_lt::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN < x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else build_le (r, type, op1); @@ -1005,7 +1005,7 @@ foperator_le::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x <= NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else build_gt (r, type, op2); @@ -1038,7 +1038,7 @@ foperator_le::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN <= x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1122,7 +1122,7 @@ foperator_gt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x > NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1161,7 +1161,7 @@ foperator_gt::op2_range (frange &r, case BRS_FALSE: // On The FALSE side of NAN > x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1241,7 +1241,7 @@ foperator_ge::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x >= NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1275,7 +1275,7 @@ foperator_ge::op2_range (frange &r, tree case BRS_FALSE: // On the FALSE side of NAN >= x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1639,7 +1639,7 @@ foperator_unordered_lt::op1_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1673,7 +1673,7 @@ foperator_unordered_lt::op2_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1755,7 +1755,7 @@ foperator_unordered_le::op1_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1788,7 +1788,7 @@ foperator_unordered_le::op2_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1872,7 +1872,7 @@ foperator_unordered_gt::op1_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1907,7 +1907,7 @@ foperator_unordered_gt::op2_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1991,7 +1991,7 @@ foperator_unordered_ge::op1_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -2025,7 +2025,7 @@ foperator_unordered_ge::op2_range (frang switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; --- gcc/testsuite/gcc.c-torture/execute/ieee/pr109386.c.jj 2023-04-03 13:44:59.715981917 +0200 +++ gcc/testsuite/gcc.c-torture/execute/ieee/pr109386.c 2023-04-03 13:44:48.480145842 +0200 @@ -0,0 +1,21 @@ +/* PR tree-optimization/109386 */ + +static inline float +foo (float x, float y) +{ + float u = __builtin_fabsf (x); + float v = __builtin_fabsf (y); + if (!(u >= v)) + { + if (__builtin_isinf (v)) return v; + if (__builtin_isinf (u)) return u; + } + return 42.0f; +} + +int +main () +{ + if (!__builtin_isinf (foo (__builtin_inff (), __builtin_nanf ("")))) + __builtin_abort (); +}