https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120231

--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:b6b238ddcb119bb51555ead9be0fa7b06b8a6be7

commit r16-1191-gb6b238ddcb119bb51555ead9be0fa7b06b8a6be7
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Jun 5 18:10:22 2025 +0200

    ranger: Add support for float <-> int casts [PR120231]

    The following patch adds support for float <-> integer conversions in
    ranger.
    The patch reverts part of the r16-571 changes, those changes were right
    for fold_range, but not for op1_range, where RO_IFI and RO_FIF are actually
    called rather than RO_IFF and RO_FII that the patch expected.
    Also, the float -> int operation actually uses FIX_TRUNC_EXPR tree code
    rather than NOP_EXPR or CONVERT_EXPR and int -> float uses FLOAT_EXPR,
    but I think we can just handle all of them using operator_cast, at least
    as long as we don't try to use VIEW_CONVERT_EXPR using that too; not really
    sure handling VCE at least for floating to integral or vice versa would
    be actually useful though.

    The patch "regressed" two tests, gfortran.dg/inline_matmul_16.f90 and
    g++.dg/tree-ssa/loop-split-1.C.  In the first case, there is a loop doing
    matmul on various sizes of matrices, up to 10x10 matrices, and Fortran
    FE given the options emits two implementations of the matmul, one inline
    for the case where the matmul has less than 1000 elements and one for
    larger matmuls.  The check for whatever reason uses floating point
    calculations and before this patch we weren't able to prove that all the
    matrices will be smaller than the cutoff and the test was checking for
    presence of the fallback call; with the patch we are able to figure it
    out and only keep the inline copy.  I've duplicated the test, once
    unmodified source which doesn't expect _gfortran_matmul string in optimized
    dump anymore, and another copy which uses volatile ten instead of 10 in
    loop upper bounds so that it has to keep the fallback and scans for it.
    The other test is g++.dg/tree-ssa/loop-split-1.C, which does
    constexpr unsigned s = 100000000;
    ...
        for(unsigned i = 0; i < s; ++i)
        {
            if(i == 0)
                a[i] = b[i] * c[i];
            else
                a[i] = (b[i] + c[i]) * c[i-1] * std::log(i);
        }
    and for some reason the successful loop splitting for which the test
    searches in a dump file is dependent on the errno fallback of std::log,
    where we do t = std::log((double)i); if ((double)i) u> 0); else log
((double)i);
    But i goes only from 1 to 100000000, so (double)i has the range
    [1.0, 100000000.0] with the patch and so we see it will never need errno
    nor raise exception.  I've tested adding + d for it where d is 0.0 but
    modifiable in some other TU, and tested it also with r14-2851 and r14-2852,
    where the former FAILed the test both unmodified and modified, while
    the latter PASSed both versions.

    2025-06-05  Jakub Jelinek  <ja...@redhat.com>

            PR tree-optimization/120231
            * range-op.cc (range_op_table::range_op_table): Register op_cast
            also for FLOAT_EXPR and FIX_TRUNC_EXPR.
            (RO_III): Adjust comment.
            (range_op_handler::op1_range): Handle RO_IFI rather than RO_IFF.
            Don't handle RO_FII.
            (range_operator::op1_range): Remove overload with
            irange &, tree, const frange &, const frange &, relation_trio
            and frange &, tree, const irange &, const irange &, relation_trio
            arguments.  Add overload with
            irange &, tree, const frange &, const irange &, relation_trio
            arguments.
            * range-op-mixed.h (operator_cast::op1_range): Remove overload with
            irange &, tree, const frange &, const frange &, relation_trio
            and frange &, tree, const irange &, const irange &, relation_trio
            arguments.  Add overload with
            irange &, tree, const frange &, const irange &, relation_trio and
            frange &, tree, const irange &, const frange &, relation_trio
            arguments.
            * range-op.h (range_operator::op1_cast): Remove overload with
            irange &, tree, const frange &, const frange &, relation_trio
            and frange &, tree, const irange &, const irange &, relation_trio
            arguments.  Add overload with
            irange &, tree, const frange &, const irange &, relation_trio
            arguments.
            * range-op-float.cc (operator_cast::fold_range): Implement
            float to int and int to float casts.
            (operator_cast::op1_range): Remove overload with
            irange &, tree, const frange &, const frange &, relation_trio
            and frange &, tree, const irange &, const irange &, relation_trio
            arguments.  Add overload with
            irange &, tree, const frange &, const irange &, relation_trio and
            frange &, tree, const irange &, const frange &, relation_trio
            arguments and implement reverse op of float to int and int to float
            cast there.

            * gcc.dg/tree-ssa/pr120231-2.c: New test.
            * gcc.dg/tree-ssa/pr120231-3.c: New test.
            * gfortran.dg/inline_matmul_16.f90: Don't expect any
_gfortran_matmul
            strings in optimized dump.
            * gfortran.dg/inline_matmul_26.f90: New test.
            * g++.dg/tree-ssa/loop-split-1.C (d): New variable.
            (main): Use std::log (i + d) instead of std::log (i).

Reply via email to