Hi Aldy, This commit breaks the attached test case at -O2 on x86_64-linux-gnu and loongarch64-linux-gnu :(.
The code is simplified from Glibc: the breakage causes two Glibc test failures on loongarch64-linux-gnu. Reverting the commit can fix the breakage. On Wed, 2022-11-09 at 08:07 +0100, Aldy Hernandez via Gcc-patches wrote: > Now that the generic parts of the binary operators have been > abstracted, implementing MINUS_EXPR is a cinch. > > The op[12]_range entries will be submitted as a follow-up. > > gcc/ChangeLog: > > * range-op-float.cc (class foperator_minus): New. > (floating_op_table::floating_op_table): Add MINUS_EXPR entry. > --- > gcc/range-op-float.cc | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc > index 7075c25442a..d52e971f84e 100644 > --- a/gcc/range-op-float.cc > +++ b/gcc/range-op-float.cc > @@ -1884,6 +1884,29 @@ class foperator_plus : public > range_operator_float > } fop_plus; > > > +class foperator_minus : public range_operator_float > +{ > + void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool > &maybe_nan, > + tree type, > + const REAL_VALUE_TYPE &lh_lb, > + const REAL_VALUE_TYPE &lh_ub, > + const REAL_VALUE_TYPE &rh_lb, > + const REAL_VALUE_TYPE &rh_ub) const final override > + { > + frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, > dconstninf); > + frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, > dconstinf); > + > + // [+INF] - [+INF] = NAN > + if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false)) > + maybe_nan = true; > + // [-INF] - [-INF] = NAN > + else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true)) > + maybe_nan = true; > + else > + maybe_nan = false; > + } > +} fop_minus; > + > // Instantiate a range_op_table for floating point operations. > static floating_op_table global_floating_table; > > @@ -1917,6 +1940,7 @@ floating_op_table::floating_op_table () > set (ABS_EXPR, fop_abs); > set (NEGATE_EXPR, fop_negate); > set (PLUS_EXPR, fop_plus); > + set (MINUS_EXPR, fop_minus); > } > > // Return a pointer to the range_operator_float instance, if there is -- Xi Ruoyao <xry...@xry111.site> School of Aerospace Science and Technology, Xidian University
__attribute__((noipa,noinline)) int t(double a, double b) { double c = a - b; if (!__builtin_isfinite(c)) { if (__builtin_isnan(c)) { if (!__builtin_isnan(a) && !__builtin_isnan(b)) return 1; } else if (__builtin_isfinite(a) && __builtin_isfinite(b)) return 2; } else if (c == 0 && a != b) return 3; return 4; } int main() { double a = __builtin_inf(); if (t(a, a) != 1) __builtin_abort(); }