Surya Kumari Jangala via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> sched1: Fix -fcompare-debug issue in schedule_region [PR105586]
>
> In schedule_region(), a basic block that does not contain any real insns
> is not scheduled and the dfa state at the entry of the bb is not copied
> to the fallthru basic block. However a DEBUG insn is treated as a real
> insn, and if a bb contains non-real insns and a DEBUG insn, it's dfa
> state is copied to the fallthru bb. This was resulting in
> -fcompare-debug failure as the incoming dfa state of the fallthru block
> is different with -g. We should always copy the dfa state of a bb to
> it's fallthru bb even if the bb does not contain real insns.
>
> 2022-08-22  Surya Kumari Jangala  <jskum...@linux.ibm.com>
>
> gcc/
>       PR rtl-optimization/105586
>       * sched-rgn.cc (schedule_region): Always copy dfa state to
>       fallthru block.
>
> gcc/testsuite/
>       PR rtl-optimization/105586
>       * gcc.target/powerpc/pr105586.c: New test.
>
>
> diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc
> index 0dc2a8f2851..6c9202c0b2b 100644
> --- a/gcc/sched-rgn.cc
> +++ b/gcc/sched-rgn.cc
> @@ -3082,6 +3082,24 @@ free_bb_state_array (void)
>    bb_state = NULL;
>  }
>  
> +static void
> +save_state_for_fallthru_edge (basic_block last_bb, state_t state)

The convention (not always followed) is to have a comment above each
function explaining what it does.  How about something like:

/* If LAST_BB falls through to another block B, record that B should
   start with DFA start STATE.  */

OK for trunk with that change (and with the new changelog).

Thanks,
Richard

> +{
> +  edge f = find_fallthru_edge (last_bb->succs);
> +  if (f
> +      && (!f->probability.initialized_p ()
> +       || (f->probability.to_reg_br_prob_base () * 100
> +           / REG_BR_PROB_BASE
> +           >= param_sched_state_edge_prob_cutoff)))
> +  {
> +    memcpy (bb_state[f->dest->index], state,
> +         dfa_state_size);
> +    if (sched_verbose >= 5)
> +      fprintf (sched_dump, "saving state for edge %d->%d\n",
> +            f->src->index, f->dest->index);
> +  }
> +}
> +
>  /* Schedule a region.  A region is either an inner loop, a loop-free
>     subroutine, or a single basic block.  Each bb in the region is
>     scheduled after its flow predecessors.  */
> @@ -3155,6 +3173,7 @@ schedule_region (int rgn)
>        if (no_real_insns_p (head, tail))
>       {
>         gcc_assert (first_bb == last_bb);
> +       save_state_for_fallthru_edge (last_bb, bb_state[first_bb->index]);
>         continue;
>       }
>  
> @@ -3173,26 +3192,13 @@ schedule_region (int rgn)
>        curr_bb = first_bb;
>        if (dbg_cnt (sched_block))
>          {
> -       edge f;
>         int saved_last_basic_block = last_basic_block_for_fn (cfun);
>  
>         schedule_block (&curr_bb, bb_state[first_bb->index]);
>         gcc_assert (EBB_FIRST_BB (bb) == first_bb);
>         sched_rgn_n_insns += sched_n_insns;
>         realloc_bb_state_array (saved_last_basic_block);
> -       f = find_fallthru_edge (last_bb->succs);
> -       if (f
> -           && (!f->probability.initialized_p ()
> -               || (f->probability.to_reg_br_prob_base () * 100
> -                   / REG_BR_PROB_BASE
> -                   >= param_sched_state_edge_prob_cutoff)))
> -         {
> -           memcpy (bb_state[f->dest->index], curr_state,
> -                   dfa_state_size);
> -           if (sched_verbose >= 5)
> -             fprintf (sched_dump, "saving state for edge %d->%d\n",
> -                      f->src->index, f->dest->index);
> -         }
> +       save_state_for_fallthru_edge (last_bb, curr_state);
>          }
>        else
>          {
> diff --git a/gcc/testsuite/gcc.target/powerpc/pr105586.c 
> b/gcc/testsuite/gcc.target/powerpc/pr105586.c
> new file mode 100644
> index 00000000000..bd397f58bc0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/pr105586.c
> @@ -0,0 +1,19 @@
> +/* { dg-options "-mdejagnu-tune=power4 -O2 -fcompare-debug 
> -fno-if-conversion -fno-guess-branch-probability" } */
> +
> +extern int bar(int i);
> +
> +typedef unsigned long u64;
> +int g;
> +
> +__int128 h;
> +
> +void
> +foo(int a, int b) {
> +  int i;
> +  char u8_1 = g, u8_3 = a;
> +  u64 u64_1 = bar(0), u64_3 = u8_3 * u64_1;
> +  __int128 u128_1 = h ^ __builtin_expect(i, 0);
> +  u64 u64_4 = u64_1 << ((__builtin_sub_overflow_p(0, u8_1, (u64)0) ^ u128_1) 
> & 8);
> +  u64 u64_r = b + u64_3 + u64_4;
> +  bar((short)u64_r + u8_3);
> +}

Reply via email to