OpenMP: Avoid ICE with LTO and 'omp allocate' gcc/ChangeLog: * gimplify.cc (gimplify_bind_expr): Remove "omp allocate" attribute to avoid that auxillary statement list reaches to LTO. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/allocate-13a.f90: New test. gcc/gimplify.cc | 18 ++++++++----- gcc/testsuite/gfortran.dg/gomp/allocate-13a.f90 | 34 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 9c617c21381..22ff1075abb 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -1426,7 +1426,8 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) DECL_ATTRIBUTES (v) = tree_cons (get_identifier ("omp allocate var"), build_tree_list (NULL_TREE, t), - DECL_ATTRIBUTES (t)); + remove_attribute ("omp allocate", + DECL_ATTRIBUTES (t))); tmp = build_fold_indirect_ref (v); TREE_THIS_NOTRAP (tmp) = 1; SET_DECL_VALUE_EXPR (t, tmp); @@ -1473,7 +1474,12 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) at the top, unless an allocator or size expression requires to put it afterward; note that the size is always later in generated code; for strings, no - size expr but still an expr might be available. */ + size expr but still an expr might be available. + As LTO does not handle a statement list, 'sl' has + to be removed; done so by removing the attribute. */ + DECL_ATTRIBUTES (t) + = remove_attribute ("omp allocate", + DECL_ATTRIBUTES (t)); tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr))); tree_stmt_iterator e = tsi_start (sl); tree needle = NULL_TREE; @@ -1631,16 +1637,14 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) && !is_global_var (t) && DECL_CONTEXT (t) == current_function_decl) { - tree attr; if (flag_openmp && DECL_HAS_VALUE_EXPR_P (t) && TREE_USED (t) - && ((attr = lookup_attribute ("omp allocate", - DECL_ATTRIBUTES (t))) != NULL_TREE) - && TREE_CHAIN (TREE_VALUE (attr)) == NULL_TREE) + && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) { /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which - causes that the GOMP_free call is already added above. */ + causes that the GOMP_free call is already added above; + and "omp allocate" is removed from DECL_ATTRIBUTES. */ tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0); tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE); tmp = build_call_expr_loc (end_locus, tmp, 2, v, diff --git a/gcc/testsuite/gfortran.dg/gomp/allocate-13a.f90 b/gcc/testsuite/gfortran.dg/gomp/allocate-13a.f90 new file mode 100644 index 00000000000..4b297cdb4aa --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/allocate-13a.f90 @@ -0,0 +1,34 @@ +! { dg-do compile { target lto } } +! { dg-additional-options "-flto" } + +! Same as allocate-13.f90 but compiled with -flto. + +! This was failing before as the statement list, +! used for placing the GOMP_alloc/GOMP_free leaked +! through to LTO. + +module m + implicit none + !$omp requires dynamic_allocators +contains +subroutine f () + !$omp declare target + integer :: var + !$omp allocate(var) + var = 5 +end + +subroutine h () + !$omp target + !$omp parallel + !$omp single + block + integer :: var2(5) + !$omp allocate(var2) + var2(1) = 7 + end block + !$omp end single + !$omp end parallel + !$omp end target +end +end module