On Mon, Aug 03, 2020 at 05:37:40PM +0200, Tobias Burnus wrote:
> It turned out that the omp_discover_declare_target_tgt_fn_r
> discovered all nodes – but as it tagged the C++ alias nodes
> and not the streamed-out nodes, no device function was created
> and one got link errors if offloading devices were configured.
> (Only with -O0 as otherwise inlining happened.)
> 
> (Testcase is based on a sollve_vv testcase which in turn was
> based on an LLVM bugreport.)

> OpenMP: Handle cpp_implicit_alias in declare-target discovery (PR96390)
> 
> gcc/ChangeLog:
> 
>       PR middle-end/96390
>       * omp-offload.c (omp_discover_declare_target_tgt_fn_r): Handle
>       cpp_implicit_alias nodes.
> 
> libgomp/ChangeLog:
> 
>       PR middle-end/96390
>       * testsuite/libgomp.c++/pr96390.C: New test.
> 
>  gcc/omp-offload.c                       |  8 ++++++
>  libgomp/testsuite/libgomp.c++/pr96390.C | 49 
> +++++++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c
> index 32c2485abd4..4aef7dbea6c 100644
> --- a/gcc/omp-offload.c
> +++ b/gcc/omp-offload.c
> @@ -207,6 +207,14 @@ omp_discover_declare_target_tgt_fn_r (tree *tp, int 
> *walk_subtrees, void *data)
>        symtab_node *node = symtab_node::get (*tp);
>        if (node != NULL)
>       {
> +       if (node->cpp_implicit_alias)
> +         {
> +           node = node->get_alias_target ();
> +           if (!omp_declare_target_fn_p (node->decl))
> +             ((vec<tree> *) data)->safe_push (node->decl);
> +           DECL_ATTRIBUTES (node->decl)
> +             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (node->decl));
> +         }
>         node->offloadable = 1;
>         if (ENABLE_OFFLOADING)
>           g->have_offload = true;

Sorry for the review delay.

I don't see what is special on cpp_implicit_alias here, compared to any
other aliases.
So, I wonder if the code shouldn't do:
      tree decl = *tp;
      symtab_node *node = symtab_node::get (decl);
      if (node != NULL)
        {
          symtab_node *anode = node->ultimate_alias_target ();
          if (anode && anode != node)
            {
              decl = anode->decl;
              gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
              if (omp_declare_target_fn_p (*tp)
                  || lookup_attribute ("omp declare target host",
                                       DECL_ATTRIBUTES (decl)))
                return NULL_TREE;
              node = anode;
            }
        }
      tree id = get_identifier ("omp declare target");
      if (!DECL_EXTERNAL (decl) && DECL_SAVED_TREE (decl))
        ((vec<tree> *) data)->safe_push (decl);
      DECL_ATTRIBUTES (decl) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES 
(decl));
      if (node != NULL)
        {
          node->offloadable = 1;
          if (ENABLE_OFFLOADING)
            g->have_offload = true;
        }

Otherwise, if we have say:
void foo () { }
void bar () __attribute__((alias ("foo")));
void baz () __attribute__((alias ("bar")));
int
main ()
{
  #pragma omp target
  baz ();
}
we won't mark foo as being declare target.
Though, maybe that is not enough and we need to mark all the aliases from
node to the ultimate alias that way (so perhaps instead iterate one
get_alias_target (if node->alias) by one and mark all the decls the way the
code marks right now (i.e. pushes those non-DECL_EXTERNAL with
DECL_SAVED_TREE for further processing and add attributes to all of them?

        Jakub

Reply via email to