From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 026203833A0E for ; Wed, 7 Dec 2022 15:49:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 026203833A0E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1670428197; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=GdaP7Itnf3w1aX3bGN6x+l9HgsWtU+D/jYcOX/ETaF4=; b=hbtjonJs3cJfjUB4hkVokMvquo63xJAhWSwAKhCrCCmJOAfjkhJsmWOJg+69w3QMEkG9UQ SdcqsSmIulIVT34J7AoB3H8jhrttpb0U16VQ77Waljl4uOn0F18Llvy3qcnaazML/exlhk Ul8b3eVpJuCXthapU5LJh87F0xHAjb8= 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-589-C-gR0eEpPsKYYgKsqDwC0A-1; Wed, 07 Dec 2022 10:49:56 -0500 X-MC-Unique: C-gR0eEpPsKYYgKsqDwC0A-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 34B77811E81 for ; Wed, 7 Dec 2022 15:49:56 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.195.114]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E8039492B04; Wed, 7 Dec 2022 15:49:55 +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 2B7FnpU5098220 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 7 Dec 2022 16:49:51 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 2B7Fnot4098219; Wed, 7 Dec 2022 16:49:50 +0100 Date: Wed, 7 Dec 2022 16:49:49 +0100 From: Jakub Jelinek To: Aldy Hernandez Cc: gcc-patches@gcc.gnu.org, andrew MacLeod Subject: [PATCH] range-op-float, v2: Fix up frange_arithmetic [PR107967] Message-ID: Reply-To: Jakub Jelinek References: MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.5 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 List-Id: On Wed, Dec 07, 2022 at 04:26:14PM +0100, Aldy Hernandez wrote: > This chunk... > > ...is quite similar to this one. Could you abstract this? It differs in various small details, plus comment content. Anyway, here it is reworked such that those various small details are based on whether inf is negative or positive in a single piece of code. Is this ok if it passes bootstrap/regtest? 2022-12-07 Jakub Jelinek PR tree-optimization/107967 * range-op-float.cc (frange_arithmetic): Fix a thinko - if inf is negative, use nextafter if !real_less (&result, &value) rather than if real_less (&result, &value). If result is +-INF while value is finite and -fno-rounding-math, don't do rounding if !inexact or if result is significantly above max representable value or below min representable value. * gcc.dg/pr107967-1.c: New test. * gcc.dg/pr107967-2.c: New test. * gcc.dg/pr107967-3.c: New test. --- gcc/range-op-float.cc.jj 2022-12-07 16:37:05.285143250 +0100 +++ gcc/range-op-float.cc 2022-12-07 16:41:58.500928517 +0100 @@ -287,9 +287,42 @@ frange_arithmetic (enum tree_code code, // Be extra careful if there may be discrepancies between the // compile and runtime results. - if ((mode_composite || (real_isneg (&inf) ? real_less (&result, &value) - : !real_less (&value, &result))) - && (inexact || !real_identical (&result, &value))) + bool round = false; + if (mode_composite) + round = true; + else + { + bool low = real_isneg (&inf); + round = (low ? !real_less (&result, &value) + : !real_less (&value, &result)); + if (real_isinf (&result, !low) + && !real_isinf (&value) + && !flag_rounding_math) + { + // Use just [+INF, +INF] rather than [MAX, +INF] + // even if value is larger than MAX and rounds to + // nearest to +INF. Similarly just [-INF, -INF] + // rather than [-INF, +MAX] even if value is smaller + // than -MAX and rounds to nearest to -INF. + // Unless INEXACT is true, in that case we need some + // extra buffer. + if (!inexact) + round = false; + else + { + REAL_VALUE_TYPE tmp = result, tmp2; + frange_nextafter (mode, tmp, inf); + // TMP is at this point the maximum representable + // number. + real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp); + if (real_isneg (&tmp2) != low + && (REAL_EXP (&tmp2) - REAL_EXP (&tmp) + >= 2 - REAL_MODE_FORMAT (mode)->p)) + round = false; + } + } + } + if (round && (inexact || !real_identical (&result, &value))) { if (mode_composite) { --- gcc/testsuite/gcc.dg/pr107967-1.c.jj 2022-12-07 16:38:07.519248686 +0100 +++ gcc/testsuite/gcc.dg/pr107967-1.c 2022-12-07 16:38:07.519248686 +0100 @@ -0,0 +1,35 @@ +/* PR tree-optimization/107967 */ +/* { dg-do compile { target float64 } } */ +/* { dg-options "-O2 -frounding-math -fno-trapping-math -fdump-tree-optimized" } */ +/* { dg-add-options float64 } */ +/* { dg-final { scan-tree-dump-not "return\[ \t]\*-?Inf;" "optimized" } } */ + +_Float64 +foo (void) +{ + const _Float64 huge = 1.0e+300f64; + return huge * huge; +} + +_Float64 +bar (void) +{ + const _Float64 huge = 1.0e+300f64; + return huge * -huge; +} + +_Float64 +baz (void) +{ + const _Float64 a = 0x1.fffffffffffffp+1023f64; + const _Float64 b = 0x1.fffffffffffffp+970f64; + return a + b; +} + +_Float64 +qux (void) +{ + const _Float64 a = 0x1.fffffffffffffp+1023f64; + const _Float64 b = 0x1.fffffffffffffp+969f64; + return a + b; +} --- gcc/testsuite/gcc.dg/pr107967-2.c.jj 2022-12-07 16:38:07.519248686 +0100 +++ gcc/testsuite/gcc.dg/pr107967-2.c 2022-12-07 16:38:07.519248686 +0100 @@ -0,0 +1,35 @@ +/* PR tree-optimization/107967 */ +/* { dg-do compile { target float64 } } */ +/* { dg-options "-O2 -fno-rounding-math -fno-trapping-math -fdump-tree-optimized" } */ +/* { dg-add-options float64 } */ +/* { dg-final { scan-tree-dump-times "return\[ \t]\*-?Inf;" 3 "optimized" } } */ + +_Float64 +foo (void) +{ + const _Float64 huge = 1.0e+300f64; + return huge * huge; +} + +_Float64 +bar (void) +{ + const _Float64 huge = 1.0e+300f64; + return huge * -huge; +} + +_Float64 +baz (void) +{ + const _Float64 a = 0x1.fffffffffffffp+1023f64; + const _Float64 b = 0x1.fffffffffffffp+970f64; + return a + b; +} + +_Float64 +qux (void) +{ + const _Float64 a = 0x1.fffffffffffffp+1023f64; + const _Float64 b = 0x1.fffffffffffffp+969f64; + return a + b; +} --- gcc/testsuite/gcc.dg/pr107967-3.c.jj 2022-12-07 16:38:07.519248686 +0100 +++ gcc/testsuite/gcc.dg/pr107967-3.c 2022-12-07 16:38:07.519248686 +0100 @@ -0,0 +1,53 @@ +/* PR tree-optimization/107967 */ +/* { dg-do compile { target float64 } } */ +/* { dg-options "-O2 -fno-rounding-math -fno-trapping-math -fdump-tree-optimized" } */ +/* { dg-add-options float64 } */ +/* { dg-final { scan-tree-dump-times "return\[ \t]\*-?Inf;" 3 "optimized" } } */ + +_Float64 +foo (_Float64 x) +{ + if (x >= 1.0e+300f64) + ; + else + __builtin_unreachable (); + return x * x; +} + +_Float64 +bar (_Float64 x) +{ + if (x >= 1.0e+300f64) + ; + else + __builtin_unreachable (); + return x * -x; +} + +_Float64 +baz (_Float64 a, _Float64 b) +{ + if (a >= 0x1.fffffffffffffp+1023f64) + ; + else + __builtin_unreachable (); + if (b >= 0x1.p+972f64) + ; + else + __builtin_unreachable (); + return a + b; +} + +_Float64 +qux (_Float64 a, _Float64 b) +{ + if (a >= 0x1.fffffffffffffp+1023f64) + ; + else + __builtin_unreachable (); + if (b >= 0x1.fffffffffffffp+969f64) + ; + else + __builtin_unreachable (); + return a + b; +} Jakub