On Thu, Feb 8, 2018 at 11:23 PM, David Malcolm <dmalc...@redhat.com> wrote:
> PR tree-optimization/84178 reports a couple of source files that ICE inside
> ifcvt when compiled with -03 -fno-tree-forwprop (trunk and gcc 7).
>
> Both cases involve problems with ifcvt's per-BB gimplified predicates.
>
> Testcase 1 fails this assertion within release_bb_predicate during cleanup:
>
> 283           if (flag_checking)
> 284             for (gimple_stmt_iterator i = gsi_start (stmts);
> 285                  !gsi_end_p (i); gsi_next (&i))
> 286               gcc_assert (! gimple_use_ops (gsi_stmt (i)));
>
> The testcase contains a division in the loop, which leads to
> if_convertible_loop_p returning false (due to gimple_could_trap_p being true
> for the division).  This happens *after* the per-BB gimplified predicates
> have been created in predicate_bbs (loop).
> Hence tree_if_conversion bails out to "cleanup", but the gimplified predicates
> exist and make use of SSA names; for example this conjunction for two BB
> conditions:
>
>   _4 = h4.1_112 != 0;
>   _175 = (signed char) _117;
>   _176 = _175 >= 0;
>   _174 = _4 & _176;
>
> is using SSA names.

But then this shouldn't cause any stmt operands to be created - who is calling
update_stmt () on a stmt using the SSA names?  Maybe something calls
force_gimple_operand_gsi to add to the sequence?

> This assertion was added in r236498 (aka 
> c3deca2519d97c55876869c57cf11ae1e5c6cf8b):
>
>     2016-05-20  Richard Biener  <rguent...@suse.de>
>
>         * tree-if-conv.c (add_bb_predicate_gimplified_stmts): Use
>         gimple_seq_add_seq_without_update.
>         (release_bb_predicate): Assert we have no operands to free.
>         (if_convertible_loop_p_1): Calculate post dominators later.
>         Do not free BB predicates here.
>         (combine_blocks): Do not recompute BB predicates.
>         (version_loop_for_if_conversion): Save BB predicates around
>         loop versioning.
>
>         * gcc.dg/tree-ssa/ifc-cd.c: Adjust.
>
> The following patch fixes this by removing the assertion, and reinstating the
> cleanup of the operands.

But that was supposed to be not necessary...  I'll note that simply restoring
the old behavior is not ideal either - luckily we now have gimple_seq_discard ()
which should do a better job here (and actually does what the function comment
says!).

>
> Testcase 2 segfaults inside update_ssa when called from
> version_loop_for_if_conversion when a loop is versioned.
>
> During loop_version, some blocks are duplicated, and this can duplicate
> SSA names, leading to the duplicated SSA names being added to
> tree-into-ssa.c's old_ssa_names.
>
> For example, _117 is an SSA name defined in one of these to-be-duplicated
> blocks, and hence is added to old_ssa_names when duplicated.
>
> One of the BBs has this gimplified predicate (again, these stmts are *not*
> yet in a BB):
>   _173 = h4.1_112 != 0;
>   _171 = (signed char) _117;
>   _172 = _171 >= 0;
>   _170 = ~_172;
>   _169 = _170 & _173;
>
> Note the reference to SSA name _117 in the above.
>
> When update_ssa runs later on in version_loop_for_if_conversion,
> SSA name _117 is in the old_ssa_names bitmap, and thus has
> prepare_use_sites_for called on it:
>
> 2771      /* If an old name is in NAMES_TO_RELEASE, we cannot remove it from
> 2772         OLD_SSA_NAMES, but we have to ignore its definition site.  */
> 2773      EXECUTE_IF_SET_IN_BITMAP (old_ssa_names, 0, i, sbi)
> 2774        {
> 2775          if (names_to_release == NULL || !bitmap_bit_p 
> (names_to_release, i))
> 2776            prepare_def_site_for (ssa_name (i), insert_phi_p);
> 2777          prepare_use_sites_for (ssa_name (i), insert_phi_p);
> 2778        }
>
> prepare_use_sites_for iterates over the immediate users, which includes
> the:
>   _171 = (signed char) _117;
> in the gimplified predicate.
>
> This tried to call "mark_block_for_update" on the BB of this def_stmt,
> leading to a read-through-NULL segfault, since this statement isn't in a
> BB yet.
>
> With the caveat that this is at the limit of my understanding of the
> innards of gimple, I'm wondering how this ever works: we have gimplified
> predicates that aren't in a BB yet, which typically refer to
> SSA names in the CFG proper, and we're attempting non-trivial manipulations
> of that CFG that can e.g. duplicate those SSA names.
>
> The following patch fixes the 2nd ICE by inserting the gimplified predicates
> earlier: immediately before the possible version_loop_for_if_conversion,
> rather than within combine_blocks.  That way they're in their BBs before
> we attempt any further manipulation of the CFG.

Hum, but that will alter both copies of the loops, no?  I think the fix is
to instead delay the update_ssa call to _after_ combine_blocks ()
(and remember if it is necessary just in case we didn't version).

Richard.

> This fixes the ICE, though it introduces a regression of
>   gcc.target/i386/avx2-vec-mask-bit-not.c
> which no longer vectorizes for some reason (I haven't investigated
> why yet).
>
> Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.
>
> Thoughts?  Does this analysis sound sane?
>
> Dave
>
> gcc/ChangeLog:
>         PR tree-optimization/84178
>         * tree-if-conv.c (release_bb_predicate): Reinstate the
>         free_stmt_operands loop removed in r236498, removing
>         the assertion that the stmts have NULL use_ops.
>         (combine_blocks): Move the call to insert_gimplified_predicates...
>         (tree_if_conversion): ...to here, immediately before attempting
>         to version the loop.
>
> gcc/testsuite/ChangeLog:
>         PR tree-optimization/84178
>         * gcc.c-torture/compile/pr84178-1.c: New test.
>         * gcc.c-torture/compile/pr84178-2.c: New test.
> ---
>  gcc/testsuite/gcc.c-torture/compile/pr84178-1.c | 18 ++++++++++++++++++
>  gcc/testsuite/gcc.c-torture/compile/pr84178-2.c | 18 ++++++++++++++++++
>  gcc/tree-if-conv.c                              | 15 +++++++++------
>  3 files changed, 45 insertions(+), 6 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr84178-1.c
>  create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr84178-2.c
>
> diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84178-1.c 
> b/gcc/testsuite/gcc.c-torture/compile/pr84178-1.c
> new file mode 100644
> index 0000000..49f2c89
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/compile/pr84178-1.c
> @@ -0,0 +1,18 @@
> +/* { dg-options "-fno-tree-forwprop" } */
> +
> +int zy, h4;
> +
> +void
> +r8 (long int mu, int *jr, int *fi, short int dv)
> +{
> +  do
> +    {
> +      int tx;
> +
> +      tx = !!h4 ? (zy / h4) : 1;
> +      mu = tx;
> +      *jr = (((unsigned char) mu > (254 >> dv)) ? 0 : (unsigned char) tx) + 
> *fi;
> +    } while (*jr == 0);
> +
> +  r8 (mu, jr, fi, 1);
> +}
> diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84178-2.c 
> b/gcc/testsuite/gcc.c-torture/compile/pr84178-2.c
> new file mode 100644
> index 0000000..b2548e9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/compile/pr84178-2.c
> @@ -0,0 +1,18 @@
> +/* { dg-options "-fno-tree-forwprop" } */
> +
> +int zy, h4;
> +
> +void
> +r8 (long int mu, int *jr, int *fi, short int dv)
> +{
> +  do
> +    {
> +      int tx;
> +
> +      tx = !!h4 ? (zy + h4) : 1;
> +      mu = tx;
> +      *jr = (((unsigned char) mu > (254 >> dv)) ? 0 : (unsigned char) tx) + 
> *fi;
> +    } while (*jr == 0);
> +
> +  r8 (mu, jr, fi, 1);
> +}
> diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
> index cac3fd7..3edfc70 100644
> --- a/gcc/tree-if-conv.c
> +++ b/gcc/tree-if-conv.c
> @@ -280,11 +280,9 @@ release_bb_predicate (basic_block bb)
>    gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
>    if (stmts)
>      {
> -      if (flag_checking)
> -       for (gimple_stmt_iterator i = gsi_start (stmts);
> -            !gsi_end_p (i); gsi_next (&i))
> -         gcc_assert (! gimple_use_ops (gsi_stmt (i)));
> -
> +      gimple_stmt_iterator i;
> +      for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
> +       free_stmt_operands (cfun, gsi_stmt (i));
>        set_bb_predicate_gimplified_stmts (bb, NULL);
>      }
>  }
> @@ -2369,7 +2367,6 @@ combine_blocks (struct loop *loop)
>    edge_iterator ei;
>
>    remove_conditions_and_labels (loop);
> -  insert_gimplified_predicates (loop);
>    predicate_all_scalar_phis (loop);
>
>    if (any_pred_load_store)
> @@ -2839,6 +2836,12 @@ tree_if_conversion (struct loop *loop)
>           || loop->dont_vectorize))
>      goto cleanup;
>
> +  /* We've generated gimplified predicates, but they aren't in their BBs
> +     yet.  Put them there now, in case version_loop_for_if_conversion
> +     needs to duplicate the SSA names for the gimplified predicates
> +     (at which point they need to be in BBs; PR 84178).  */
> +  insert_gimplified_predicates (loop);
> +
>    /* Since we have no cost model, always version loops unless the user
>       specified -ftree-loop-if-convert or unless versioning is required.
>       Either version this loop, or if the pattern is right for outer-loop
> --
> 1.8.5.3
>

Reply via email to