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

--- Comment #10 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Alex Coplan <acop...@gcc.gnu.org>:

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

commit r15-3583-gf97d86242b86e4ad2bef3623c97e91481840a210
Author: Alex Coplan <alex.cop...@arm.com>
Date:   Fri Aug 2 09:52:50 2024 +0100

    c++: Ensure ANNOTATE_EXPRs remain outermost expressions in conditions
[PR116140]

    For the testcase added with this patch, we would end up losing the:

      #pragma GCC unroll 4

    and emitting "warning: ignoring loop annotation".  That warning comes
    from tree-cfg.cc:replace_loop_annotate, and means that we failed to
    process the ANNOTATE_EXPR in tree-cfg.cc:replace_loop_annotate_in_block.
    That function walks backwards over the GIMPLE in an exiting BB for a
    loop, skipping over the final gcond, and looks for any ANNOTATE_EXPRS
    immediately preceding the gcond.

    The function documents the following pre-condition:

       /* [...] We assume that the annotations come immediately before the
          condition in BB, if any.  */

    now looking at the exiting BB of the loop, we have:

      <bb 8> :
      D.4524 = .ANNOTATE (iftmp.1, 1, 4);
      retval.0 = D.4524;
      if (retval.0 != 0)
        goto <bb 3>; [INV]
      else
        goto <bb 9>; [INV]

    and crucially there is an intervening assignment between the gcond and
    the preceding .ANNOTATE ifn call.  To see where this comes from, we can
    look to the IR given by -fdump-tree-original:

      if (<<cleanup_point ANNOTATE_EXPR <first != last && !use_find(short
        int*)::<lambda(short int)>::operator() (&pred, *first), unroll 4>>>)
        goto <D.4518>;
      else
        goto <D.4516>;

    here the problem is that we've wrapped a CLEANUP_POINT_EXPR around the
    ANNOTATE_EXPR, meaning the ANNOTATE_EXPR is no longer the outermost
    expression in the condition.

    The CLEANUP_POINT_EXPR gets added by the following call chain:

    finish_while_stmt_cond
     -> maybe_convert_cond
     -> condition_conversion
     -> fold_build_cleanup_point_expr

    this patch chooses to fix the issue by first introducing a new helper
    class (annotate_saver) to save and restore outer chains of
    ANNOTATE_EXPRs and then using it in maybe_convert_cond.

    With this patch, we don't get any such warning and the loop gets unrolled
as
    expected at -O2.

    gcc/cp/ChangeLog:

            PR libstdc++/116140
            * semantics.cc (anotate_saver): New. Use it ...
            (maybe_convert_cond): ... here, to ensure any ANNOTATE_EXPRs
            remain the outermost expression(s) of the condition.

    gcc/testsuite/ChangeLog:

            PR libstdc++/116140
            * g++.dg/ext/pragma-unroll-lambda.C: New test.

Reply via email to