From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 953433842329; Tue, 6 Dec 2022 17:16:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 953433842329 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1670346991; bh=ZtLn7XLsVy6VWCBQHYlbpLPwXY2lUZGEw2hCdCkm9cA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZE0iP6aOTpZdn/FvdfDKllLgzgElOKb2KAhwPvSCo+vKg1l75Y0JFAr71Xxr5DeU0 7XfvKgzlPkmccDm/BFaqkTU+1Yq9f6+mFQH2/CYgEMAMMOecppNCP+LYeZPP7C8ivv WTJhZUzYmKuvQXdTAI8fdgNBX2yhgAaeVxOzNT0A= From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/107967] [13 regression] The gcc commit r13-3923 caused the glibc make check fails. Date: Tue, 06 Dec 2022 17:16:29 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 13.0 X-Bugzilla-Keywords: needs-reduction, wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 13.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D107967 --- Comment #8 from Jakub Jelinek --- Actually, looking at: 288 // Be extra careful if there may be discrepancies between the 289 // compile and runtime results. 290 if ((mode_composite || (real_isneg (&inf) ? real_less (&result, &value) 291 : !real_less (&value, &result))) 292 && (inexact || !real_identical (&result, &value))) I wonder if we didn't get it exactly wrong. value is what is computed by real_arithmetic and result is that rounded to = the desired TYPE_MODE. So, for non-mode_composite, if inf is negative, we want to find a low bound= ary. Now, the value -> result conversion can round downward or upward or result = can be identical to value. If real_less (&result, &value), it rounded it downward, if real_less (&valu= e, &result), it rounded it upwards. If we want low boundary and it was already rounded downward, we don't need = to round further. So, I think we want - if ((mode_composite || (real_isneg (&inf) ? real_less (&result, &value) + if ((mode_composite || (real_isneg (&inf) ? !real_less (&result, &value) : !real_less (&value, &result))) && (inexact || !real_identical (&result, &value))) which fixes the thinko/inconsistency. Say on: double foo (void) { const double huge =3D 1.0e+300; return huge * huge; } double bar (void) { const double huge =3D 1.0e+300; return huge * -huge; } current trunk optimizes foo to return Inf; but doesn't optimize bar to retu= rn -Inf. Now, at least for -fno-trapping-math -fno-rounding-math, I'd say we actually want return Inf; and return -Inf;, for -ftrapping-math per PR107608 resolution compute [Inf, Inf] or [-Inf, -Inf] ranges and only for -frounding-math use [DBL_MAX, Inf] and [-Inf, -DBL_MAX] ranges. For that I guess we might want to special case real_isinf (&result) && !real_isinf (&value) && !flag_rounding_math cases or even just a subset of those when in round to even mode the computa= tion would always round to infinity by far. And another thing is mode_composite, if frange_nextafter is the right thing= to do from infinity. But I think (but can't find now where we say it) that double double is only supported in round to nearest mode, at least: #include #include void foo () { volatile double huge =3D 1.0e+308; volatile double inf =3D __builtin_inf (); fesetround (FE_DOWNWARD); volatile double r1 =3D huge + huge; volatile double r2 =3D huge * huge; volatile double r3 =3D huge + inf; volatile double r4 =3D r2 + huge; volatile double r5 =3D inf - 1.0; volatile double r6 =3D inf - huge; fesetround (FE_TONEAREST); printf ("%e %e %e %e %e %e\n", r1, r2, r3, r4, r5, r6); } void bar () { volatile long double huge =3D 1.0e+308L; volatile long double inf =3D __builtin_infl (); fesetround (FE_DOWNWARD); volatile long double r1 =3D huge + huge; volatile long double r2 =3D huge * huge; volatile long double r3 =3D huge + inf; volatile long double r4 =3D r2 + huge; volatile long double r5 =3D inf - 1.0; volatile long double r6 =3D inf - huge; fesetround (FE_TONEAREST); printf ("%Le %Le %Le %Le %Le %Le\n", r1, r2, r3, r4, r5, r6); } int main () { foo (); bar (); return 0; } goes wild on ppc64 and prints 1.797693e+308 1.797693e+308 inf 1.797693e+308 inf inf 1.797693e+308 -inf inf -inf inf inf The -inf is quite far from +inf or LDBL_MAX. Anyway, what I found is in libgcc/config/rs6000/ibm-ldouble-format is: "Addition and subtraction are performed using library routines. They are not at present performed perfectly accurately, the result produced will be within 1ulp of the range generated by adding or subtracting 1ulp from the input values, where a 'ulp' is 2^(e-106) given the exponent 'e'. In the presence of cancellation, this may be arbitrarily inaccurate. Subtraction is done by negation and addition. Multiplication is also performed using a library routine. Its result will be within 2ulp of the correct result. Division is also performed using a library routine. Its result will be within 3ulp of the correct result." so for frange_arithmetics mode_composite we probably need to account for th= at extra ulp on +-, 2ulps for * and 3ulps for /.=