Hi, '#pragma omp critical (name)' can be placed in the function, marked with '#pragma omp declare target', in this case the corresponding node should be marked as offloadable too. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
-- Ilya gcc/ * omp-low.c (lower_omp_critical): Mark critical sections inside target functions as offloadable. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 3924282..6c5774c 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -9366,16 +9366,6 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx) DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; - /* If '#pragma omp critical' is inside target region, the symbol must - be marked for offloading. */ - omp_context *octx; - for (octx = ctx->outer; octx; octx = octx->outer) - if (is_targetreg_ctx (octx)) - { - varpool_node::get_create (decl)->offloadable = 1; - break; - } - varpool_node::finalize_decl (decl); critical_name_mutexes->put (name, decl); @@ -9383,6 +9373,20 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx) else decl = *n; + /* If '#pragma omp critical' is inside target region or + inside function marked as offloadable, the symbol must be + marked as offloadable too. */ + omp_context *octx; + if (cgraph_node::get (current_function_decl)->offloadable) + varpool_node::get_create (decl)->offloadable = 1; + else + for (octx = ctx->outer; octx; octx = octx->outer) + if (is_targetreg_ctx (octx)) + { + varpool_node::get_create (decl)->offloadable = 1; + break; + } + lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START); lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));