From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C1BB1385828E; Tue, 10 Jan 2023 14:33:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C1BB1385828E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1673361188; bh=CvPGgD9+hzAXiy+h4n/QPOw/cSlD785tG/2WmuSwin8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=E/s8dARh9GZ2rdAclE3d5s//vSop1VfWcOapSfAnpVlR1lfFPlKmnG9p6VnKnlaNE dfSsbRKBRAhUiOaNtKJ6jFCJISHSNu8xZsBWOCAwjNQ8w8JqsfIir3iYSyS5Zej2xZ biUwwYzba6gxIKs6uiSimtQNjWA3d4p7g0izAIB0= From: "aldyh at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c Date: Tue, 10 Jan 2023 14:33:08 +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: missed-optimization, wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: aldyh at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P1 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=3D107608 --- Comment #22 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #20) > (In reply to Aldy Hernandez from comment #16) > > Created attachment 54224 [details] > > untested patch > >=20 > > Perhaps this would work. It solves the testcase, though I think we sho= uld > > probably audit the operators that don't use the generic > > range_operator_float::fold_range to make sure they're not doing anything > > silly. >=20 > Even as a workaround this seems to be quite a big hammer. > If we want to preserve overflow traps, all we need to arrange is that if > non-inf operands result in singleton inf we don't treat that result as > singleton. > Now, what result one gets in different rounding modes depends on the > rounding mode, > in round to nearest it should be +-inf, in round to zero +-max, in round = to > +inf +inf or -max and in round to -inf -inf or +max. But right now GCC > doesn't handle the separate rounding modes, it just differentiates between > -fno-rounding-math where we assume round to nearest and -frounding-math > where we should consider any rounding mode. Note that we currently can't represent +-inf or +-max, as we only have two endpoints. So that would just be represented as VARYING. > I think for -frounding-math we already don't treat such results as > singletons, as we > end up with ranges like [+max, +inf] or [-inf, -max]. > So, one possible way for -fno-rounding-math -ftrapping-math could be inst= ead > of making > the result VARYING just extend the range by one ulp towards 0, i.e. inste= ad > of singleton > [+inf, +inf] use [+max, +inf] etc. This seems reasonable. So instead of set_varying(), we could do [+max, +in= f], etc. > Another would be to add some bool flag to frange which would say this is > never a singleton and just take that flag into account, though perhaps it= is > too risky right now. That seems easy to get wrong, especially this late in the cycle. >=20 > As for invalid exceptions, that implies result maybe or known NAN, but we > don't treat > maybe or known NAN as singletons, do we? After all, there isn't just a > single NAN and we don't know which one the result is. That doesn't mean = we > handle all cases right, say > if a result of something is only used in __builtin_isnan or similar, we c= an > still happily optimized it away. NANs are never singletons, and maybe_nans either. See frange::singleton_p: if (m_kind =3D=3D VR_RANGE && real_identical (&m_min, &m_max)) { // Return false for any singleton that may be a NAN. if (HONOR_NANS (m_type) && maybe_isnan ()) return false; ... } Also, all the conditional operators in frange fail to fold if maybe_isnan. = The only things we fold for sure are: a) One operand is a known NAN. b) None of the operands can ever be a NAN *and* we know the answer to the conditional. For example, foperator_gt::fold_range: ... ... if (op1.known_isnan () || op2.known_isnan ()) r =3D range_false (type); else if (!maybe_isnan (op1, op2)) { if (real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ())) r =3D range_true (type); else if (!real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ())) r =3D range_false (type); else r =3D range_true_and_false (type); } so... we're pretty careful about NOT folding relationals that have the possibility of a NAN, and a singleton is only for a known range without a N= AN.=