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

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

https://gcc.gnu.org/g:26615af93cf759999c5dfae0c51a827b05968cca

commit r14-11151-g26615af93cf759999c5dfae0c51a827b05968cca
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Dec 5 13:01:21 2024 +0100

    doloop: Fix up doloop df use [PR116799]

    The following testcases are miscompiled on s390x-linux, because the
    doloop_optimize
      /* Ensure that the new sequence doesn't clobber a register that
         is live at the end of the block.  */
      {
        bitmap modified = BITMAP_ALLOC (NULL);

        for (rtx_insn *i = doloop_seq; i != NULL; i = NEXT_INSN (i))
          note_stores (i, record_reg_sets, modified);

        basic_block loop_end = desc->out_edge->src;
        bool fail = bitmap_intersect_p (df_get_live_out (loop_end), modified);
    check doesn't work as intended.
    The problem is that it uses df, but the df analysis was only done using
      iv_analysis_loop_init (loop);
    ->
      df_analyze_loop (loop);
    which computes df inside on the bbs of the loop.
    While loop_end bb is inside of the loop, df_get_live_out computed that
    way includes registers set in the loop and used at the start of the next
    iteration, but doesn't include registers set in the loop (or before the
    loop) and used after the loop.

    The following patch fixes that by doing whole function df_analyze first,
    changes the loop iteration mode from 0 to LI_ONLY_INNERMOST (on many
    targets which use can_use_doloop_if_innermost target hook a so are known
    to only handle innermost loops) or LI_FROM_INNERMOST (I think only bfin
    actually allows non-innermost loops) and checking not just
    df_get_live_out (loop_end) (that is needed for something used by the
    next iteration), but also df_get_live_in (desc->out_edge->dest),
    i.e. what will be used after the loop.  df of such a bb shouldn't
    be affected by the df_analyze_loop and so should be from df_analyze
    of the whole function.

    2024-12-05  Jakub Jelinek  <ja...@redhat.com>

            PR rtl-optimization/113994
            PR rtl-optimization/116799
            * loop-doloop.cc: Include targhooks.h.
            (doloop_optimize): Also punt on intersection of modified
            with df_get_live_in (desc->out_edge->dest).
            (doloop_optimize_loops): Call df_analyze.  Use
            LI_ONLY_INNERMOST or LI_FROM_INNERMOST instead of 0 as
            second loops_list argument.

            * gcc.c-torture/execute/pr116799.c: New test.
            * g++.dg/torture/pr113994.C: New test.

    (cherry picked from commit 0eed81612ad6eac2bec60286348a103d4dc02a5a)
  • [Bug rtl-optimization/116799] [... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to