https://gcc.gnu.org/g:2c3ff1f475d11a5576adf4c72e8bd5b74ce5b060
commit r17-3148-g2c3ff1f475d11a5576adf4c72e8bd5b74ce5b060 Author: Aldy Hernandez <[email protected]> Date: Fri Aug 7 09:50:26 2026 +0000 [frange] Convert the float to int cast to sub-ranges. Tested on ppc64le Linux. gcc/ChangeLog: * range-op-float.cc (operator_cast::fold_range): Convert each sub-range and union the results. (range_op_float_tests): New test. Diff: --- gcc/range-op-float.cc | 56 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 75514c0603ee..156b4f766db9 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -2991,31 +2991,37 @@ operator_cast::fold_range (irange &r, tree type, const frange &op1, r.set_varying (type); return true; } - REAL_VALUE_TYPE lb, ub; - real_trunc (&lb, VOIDmode, &op1.lower_bound ()); - real_trunc (&ub, VOIDmode, &op1.upper_bound ()); REAL_VALUE_TYPE l, u; l = real_value_from_int_cst (NULL_TREE, TYPE_MIN_VALUE (type)); - if (real_less (&lb, &l)) - { - r.set_varying (type); - return true; - } u = real_value_from_int_cst (NULL_TREE, TYPE_MAX_VALUE (type)); - if (real_less (&u, &ub)) - { - r.set_varying (type); - return true; - } - bool fail = false; - wide_int wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type)); - wide_int wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type)); - if (fail) + + r.set_undefined (); + for (unsigned i = 0; i < op1.num_pairs (); ++i) { - r.set_varying (type); - return true; + REAL_VALUE_TYPE lb, ub; + real_trunc (&lb, VOIDmode, &op1.lower_bound (i)); + real_trunc (&ub, VOIDmode, &op1.upper_bound (i)); + if (real_less (&lb, &l)) + { + r.set_varying (type); + return true; + } + if (real_less (&u, &ub)) + { + r.set_varying (type); + return true; + } + bool fail = false; + wide_int wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type)); + wide_int wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type)); + if (fail) + { + r.set_varying (type); + return true; + } + int_range<2> tmp (type, wlb, wub); + r.union_ (tmp); } - r.set (type, wlb, wub); return true; } @@ -3281,6 +3287,16 @@ range_op_float_tests () r0.clear_nan (); range_op_handler (CONVERT_EXPR).fold_range (r, float_type_node, r0, r0); ASSERT_EQ (r.num_pairs (), 2); + + // Cast conversion of (int)([1.0,2.0] U [10.0,11.0]) stays two pieces. + r0 = frange_float ("1.0", "2.0"); + r1 = frange_float ("10.0", "11.0"); + r0.union_ (r1); + r0.clear_nan (); + int_range<2> ir, ir_op2; + range_op_handler (FIX_TRUNC_EXPR).fold_range (ir, integer_type_node, + r0, ir_op2); + ASSERT_EQ (ir.num_pairs (), 2); } } // namespace selftest
