On 8/9/24 5:26 AM, Alex Coplan wrote:
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 in maybe_convert_cond by walking through
any ANNOTATE_EXPRs and doing any condition conversion on the inner expression,
leaving the ANNOTATE_EXPRs (if any) as the outermost expressions in the
condition.

I see that simplify_loop_decl_cond and finish_loop_cond use this same pattern. OK.

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

Bootstrapped/regtested on aarch64-linux-gnu, OK for trunk?

gcc/cp/ChangeLog:

        PR libstdc++/116140
        * semantics.cc (maybe_convert_cond): 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.
---
  gcc/cp/semantics.cc                           | 26 ++++++++++++-------
  .../g++.dg/ext/pragma-unroll-lambda.C         | 17 ++++++++++++
  2 files changed, 34 insertions(+), 9 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/pragma-unroll-lambda.C


Reply via email to