From 3939c1b11279dc950d2f160eb940dd791f7b40f1 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 15 Feb 2022 12:26:48 +0100 Subject: [PATCH] Fortran/OpenMP: Fix depend-clause handling gcc/fortran/ChangeLog: * trans-openmp.cc (gfc_trans_omp_clauses, gfc_trans_omp_depobj): Depend on the proper addr, for ptr/alloc depend on pointee. libgomp/ChangeLog: * testsuite/libgomp.fortran/depend-4.f90: New test. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/depend-4.f90: New test. * gfortran.dg/gomp/depend-5.f90: New test. --- gcc/fortran/trans-openmp.cc | 46 ++++- gcc/testsuite/gfortran.dg/gomp/depend-4.f90 | 240 +++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/depend-5.f90 | 82 +++++++++ libgomp/testsuite/libgomp.fortran/depend-4.f90 | 109 +++++++++++ 4 files changed, 469 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/gomp/depend-4.f90 create mode 100644 gcc/testsuite/gfortran.dg/gomp/depend-5.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/depend-4.f90 diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 0eba0b3..e1c9d46 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -2881,15 +2881,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, tree decl = gfc_trans_omp_variable (n->sym, false); if (gfc_omp_privatize_by_reference (decl)) decl = build_fold_indirect_ref (decl); - if (n->u.depend_op == OMP_DEPEND_DEPOBJ - && POINTER_TYPE_P (TREE_TYPE (decl))) - decl = build_fold_indirect_ref (decl); if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { decl = gfc_conv_descriptor_data_get (decl); gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl))); decl = build_fold_indirect_ref (decl); } + else if (n->sym->attr.allocatable || n->sym->attr.pointer) + decl = build_fold_indirect_ref (decl); else if (DECL_P (decl)) TREE_ADDRESSABLE (decl) = 1; OMP_CLAUSE_DECL (node) = decl; @@ -5508,12 +5507,43 @@ gfc_trans_omp_depobj (gfc_code *code) if (n) { tree var; - if (n->expr) - var = gfc_convert_expr_to_tree (&block, n->expr); + if (n->expr && n->expr->ref->u.ar.type != AR_FULL) + { + gfc_init_se (&se, NULL); + if (n->expr->ref->u.ar.type == AR_ELEMENT) + { + gfc_conv_expr_reference (&se, n->expr); + var = se.expr; + } + else + { + gfc_conv_expr_descriptor (&se, n->expr); + var = gfc_conv_array_data (se.expr); + } + gfc_add_block_to_block (&block, &se.pre); + gfc_add_block_to_block (&block, &se.post); + gcc_assert (POINTER_TYPE_P (TREE_TYPE (var))); + } else - var = gfc_get_symbol_decl (n->sym); - if (!POINTER_TYPE_P (TREE_TYPE (var))) - var = gfc_build_addr_expr (NULL, var); + { + var = gfc_get_symbol_decl (n->sym); + if (POINTER_TYPE_P (TREE_TYPE (var)) + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (var)))) + var = build_fold_indirect_ref (var); + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (var))) + { + var = gfc_conv_descriptor_data_get (var); + gcc_assert (POINTER_TYPE_P (TREE_TYPE (var))); + } + else if ((n->sym->attr.allocatable || n->sym->attr.pointer) + && n->sym->attr.optional) + var = build_fold_indirect_ref (var); + else if (!POINTER_TYPE_P (TREE_TYPE (var))) + { + TREE_ADDRESSABLE (var) = 1; + var = gfc_build_addr_expr (NULL, var); + } + } depobj = save_expr (depobj); tree r = build_fold_indirect_ref_loc (loc, depobj); gfc_add_expr_to_block (&block, diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-4.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-4.f90 new file mode 100644 index 0000000..d6686c1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/depend-4.f90 @@ -0,0 +1,240 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-gimple -fdump-tree-original" } + +! Check that 'omp depobj's depend and 'omp task/... depend' depend on +! the same variable + +! For pointers, it depends on the address of the pointer target +! For allocatable, on the allocated memory address + +subroutine foo(dss, dsp, dsa, daa, daaa, daap, doss, dosp, dosa, doaa, doaaa, doaap) + !use omp_lib + use iso_c_binding, only: c_intptr_t + implicit none (type, external) + integer, parameter :: omp_depend_kind = 2*c_intptr_t + integer :: ss, sp, sa, aa(4), aaa(:), aap(:) + integer :: dss, dsp, dsa, daa(4), daaa(:), daap(:) + integer :: doss, dosp, dosa, doaa(4), doaaa(:), doaap(:) + optional :: doss, dosp, dosa, doaa, doaaa, doaap + allocatable :: sa, aaa, dsa, daaa, dosa, doaaa + pointer :: sp, aap, dsp, daap, dosp, doaap + + integer(omp_depend_kind) :: object(18) + integer(omp_depend_kind) :: elem(9) + + !$omp depobj(object(1)) depend(in: ss) + !$omp depobj(object(2)) depend(in: sp) + !$omp depobj(object(3)) depend(in: sa) + !$omp depobj(object(4)) depend(in: aa) + !$omp depobj(object(5)) depend(in: aaa) + !$omp depobj(object(6)) depend(in: aap) + !$omp depobj(object(7)) depend(in: dss) + !$omp depobj(object(8)) depend(in: dsp) + !$omp depobj(object(9)) depend(in: dsa) + !$omp depobj(object(10)) depend(in: daa) + !$omp depobj(object(11)) depend(in: daaa) + !$omp depobj(object(12)) depend(in: daap) + !$omp depobj(object(13)) depend(in: doss) + !$omp depobj(object(14)) depend(in: dosp) + !$omp depobj(object(15)) depend(in: dosa) + !$omp depobj(object(16)) depend(in: doaa) + !$omp depobj(object(17)) depend(in: doaaa) + !$omp depobj(object(18)) depend(in: doaap) + + !$omp depobj(elem(1)) depend(in: aa(2)) + !$omp depobj(elem(2)) depend(in: aaa(2)) + !$omp depobj(elem(3)) depend(in: aap(2)) + !$omp depobj(elem(4)) depend(in: daa(2)) + !$omp depobj(elem(5)) depend(in: daaa(2)) + !$omp depobj(elem(6)) depend(in: daap(2)) + !$omp depobj(elem(6)) depend(in: doaa(2)) + !$omp depobj(elem(8)) depend(in: doaaa(2)) + !$omp depobj(elem(9)) depend(in: doaap(2)) + + !$omp parallel + !$omp single + !$omp task depend(out: ss) + ss = 4 + !$omp end task + !$omp task depend(out: sp) + sp = 4 + !$omp end task + !$omp task depend(out: sa) + sa = 4 + !$omp end task + !$omp task depend(out: aa) + aa = 4 + !$omp end task + !$omp task depend(out: aaa) + aaa = 4 + !$omp end task + !$omp task depend(out: aap) + aap = 4 + !$omp end task + !$omp task depend(out: dss) + dss = 4 + !$omp end task + !$omp task depend(out: dsp) + dsp = 4 + !$omp end task + !$omp task depend(out: dsa) + dsa = 4 + !$omp end task + !$omp task depend(out: daa) + daa = 4 + !$omp end task + !$omp task depend(out: daaa) + daaa = 4 + !$omp end task + !$omp task depend(out: daap) + daap = 4 + !$omp end task + !$omp task depend(out: doss) + doss = 4 + !$omp end task + !$omp task depend(out: dosp) + dosp = 4 + !$omp end task + !$omp task depend(out: dosa) + dosa = 4 + !$omp end task + !$omp task depend(out: doaa) + doaa = 4 + !$omp end task + !$omp task depend(out: doaaa) + doaaa = 4 + !$omp end task + !$omp task depend(out: doaap) + doaap = 4 + !$omp end task + + !$omp task depend(out: aa(2)) + aa(2) = 4 + !$omp end task + !$omp task depend(out: aaa(2)) + aaa(2) = 4 + !$omp end task + !$omp task depend(out: aap(2)) + aap(2) = 4 + !$omp end task + !$omp task depend(out: daa(2)) + daa(2) = 4 + !$omp end task + !$omp task depend(out: daaa(2)) + daaa(2) = 4 + !$omp end task + !$omp task depend(out: daap(2)) + daap(2) = 4 + !$omp end task + !$omp task depend(out: doaa(2)) + doaa(2) = 4 + !$omp end task + !$omp task depend(out: doaaa(2)) + doaaa(2) = 4 + !$omp end task + !$omp task depend(out: doaap(2)) + doaap(2) = 4 + !$omp end task + !$omp end single + !$omp end parallel +end + +subroutine bar + implicit none (type, external) + integer :: depvar, x + + x = 7 + !$omp parallel + !$omp single + !$omp task depend(out: depvar) + x =5 + !$omp end task + !$omp task depend(in: depvar) + if (x /= 5) stop + !$omp end task + !$omp end single + !$omp end parallel +end + +! depvar - only used for dependency, but should still be used in depend: + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:depvar\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(in:depvar\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "&object\\\[0\\\] = &ss;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[1\\\] = sp;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[2\\\] = sa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[3\\\] = &aa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[4\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) aaa.data;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[5\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) aap.data;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[6\\\] = dss;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[7\\\] = dsp;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[8\\\] = dsa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[9\\\] = daa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[10\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) daaa->data;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[11\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) daap->data;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[12\\\] = doss;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[13\\\] = \\*dosp;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[14\\\] = \\*dosa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[15\\\] = doaa;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[16\\\] = .integer.kind=4.\\\[0:\\\] \\* restrict\\) doaaa->data;" 1 "original" } } +! { dg-final { scan-tree-dump-times "&object\\\[17\\\] = .integer.kind=4.\\\[0:\\\] \\*\\) doaap->data;" 1 "original" } } + +! { dg-final { scan-tree-dump-times "&elem\\\[0\\\] = &aa\\\[1\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[1\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[2\\\] = \\(integer.kind=4. \\*\\) \\(aap.data \\+ .sizetype. \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[3\\\] = &\\(\\*daa\\)\\\[1\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[4\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = \\(integer.kind=4. \\*\\) \\(daap->data \\+ .sizetype. \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\);" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[5\\\] = &\\(\\*doaa\\)\\\[1\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[7\\\] = &\\(\\*\\(integer.kind=4.\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\];" 1 "original" } } +! { dg-final { scan-tree-dump-times "&elem\\\[8\\\] = \\(integer.kind=4. \\*\\) \\(doaap->data \\+ .sizetype. \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\);" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:ss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*sa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) aap.data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*dss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dsa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*daa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) daap->data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\*dosa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*doaa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\*\\) doaap->data\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:aa\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(aap.data \\+ \\(sizetype\\) \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\)\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*daa\\)\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(daap->data \\+ \\(sizetype\\) \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\)\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*doaa\\)\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\(\\*\\(integer\\(kind=4\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:\\*\\(integer\\(kind=4\\) \\*\\) \\(doaap->data \\+ \\(sizetype\\) \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\)\\)" 1 "original" } } + + +! gimple dump - check only those which are simple one-line checkable: + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&ss\\) shared\\(ss\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sp\\) shared\\(sp\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:sa\\) shared\\(sa\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\) shared\\(aa\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:dss\\) shared\\(dss\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:daa\\) shared\\(daa\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doss\\) shared\\(doss\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:doaa\\) shared\\(doaa\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&aa\\\[1\\\]\\) shared\\(aa\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsp;" 2 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dsa;" 3 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosp;" 2 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*dosa;" 3 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaaa->data;" 4 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = doaap->data;" 4 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*daa\\)\\\[1\\\];" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = &\\(\\*doaa\\)\\\[1\\\];" 1 "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-5.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-5.f90 new file mode 100644 index 0000000..6a32b6b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/depend-5.f90 @@ -0,0 +1,82 @@ +! { dg-do compile } +! { dg-additional-options "-fdump-tree-original" } + +! Check that depobj is correctly dereferenced in the depend clause. + +subroutine foo(dss, dsp, dsa, daa, daaa, daap, doss, dosp, dosa, doaa, doaaa, doaap) + !use omp_lib + use iso_c_binding, only: c_intptr_t + implicit none (type, external) + integer, parameter :: omp_depend_kind = 2*c_intptr_t + integer(omp_depend_kind) :: ss, sp, sa, aa(4), aaa(:), aap(:) + integer(omp_depend_kind) :: dss, dsp, dsa, daa(4), daaa(:), daap(:) + integer(omp_depend_kind) :: doss, dosp, dosa, doaa(4), doaaa(:), doaap(:) + optional :: doss, dosp, dosa, doaa, doaaa, doaap + allocatable :: sa, aaa, dsa, daaa, dosa, doaaa + pointer :: sp, aap, dsp, daap, dosp, doaap + + ! Assume the depend types are initialized ... + + !$omp parallel + !$omp single + !$omp task depend(depobj: ss) + !$omp end task + !$omp task depend(depobj: sp) + !$omp end task + !$omp task depend(depobj: sa) + !$omp end task + !$omp task depend(depobj: dss) + !$omp end task + !$omp task depend(depobj: dsp) + !$omp end task + !$omp task depend(depobj: dsa) + !$omp end task + !$omp task depend(depobj: doss) + !$omp end task + !$omp task depend(depobj: dosp) + !$omp end task + !$omp task depend(depobj: dosa) + !$omp end task + + !$omp task depend(depobj: aa(2)) + !$omp end task + !$omp task depend(depobj: aaa(2)) + !$omp end task + !$omp task depend(depobj: aap(2)) + !$omp end task + !$omp task depend(depobj: daa(2)) + !$omp end task + !$omp task depend(depobj: daaa(2)) + !$omp end task + !$omp task depend(depobj: daap(2)) + !$omp end task + !$omp task depend(depobj: doaa(2)) + !$omp end task + !$omp task depend(depobj: doaaa(2)) + !$omp end task + !$omp task depend(depobj: doaap(2)) + !$omp end task + !$omp end single + !$omp end parallel +end + + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:ss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*sp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*sa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*dss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dsp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dsa\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*doss\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dosp\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\*dosa\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:aa\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=16\\)\\\[0:\\\] \\* restrict\\) aaa.data\\)\\\[aaa.offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=16\\) \\*\\) \\(aap.data \\+ \\(sizetype\\) \\(\\(aap.offset \\+ aap.dim\\\[0\\\].stride \\* 2\\) \\* aap.span\\)\\)\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*daa\\)\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=16\\)\\\[0:\\\] \\* restrict\\) daaa->data\\)\\\[daaa->offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=16\\) \\*\\) \\(daap->data \\+ \\(sizetype\\) \\(\\(daap->offset \\+ daap->dim\\\[0\\\].stride \\* 2\\) \\* daap->span\\)\\)\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*doaa\\)\\\[1\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\(\\*\\(integer\\(kind=16\\)\\\[0:\\\] \\* restrict\\) doaaa->data\\)\\\[doaaa->offset \\+ 2\\\]\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:\\*\\(integer\\(kind=16\\) \\*\\) \\(doaap->data \\+ \\(sizetype\\) \\(\\(doaap->offset \\+ doaap->dim\\\[0\\\].stride \\* 2\\) \\* doaap->span\\)\\)\\)" 1 "original" } } diff --git a/libgomp/testsuite/libgomp.fortran/depend-4.f90 b/libgomp/testsuite/libgomp.fortran/depend-4.f90 new file mode 100644 index 0000000..80d00ca --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/depend-4.f90 @@ -0,0 +1,109 @@ +! { dg-additional-options "-fdump-tree-gimple" } +! +! { dg-additional-sources my-usleep.c } +! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" } +! +! Ensure that 'depend(...: var)' and 'depobj(...) depend(...: var)' +! depend on the same variable when 'var' is a pointer +! +program main + use omp_lib + use iso_c_binding + implicit none (external, type) + + interface + subroutine usleep(t) bind(C, name="my_usleep") + use iso_c_binding + integer(c_int), value :: t + end subroutine + end interface + + integer :: bbb + integer, target :: c + integer(omp_depend_kind) :: obj(2) + integer, pointer :: ppp + + integer :: x1, x2, x3 + + c = 42 + ppp => c + + if (.not. associated (ppp)) & + stop 0; + + x1 = 43 + x2 = 44 + x3 = 45 + !$omp depobj(obj(1)) depend(inout: ppp) + !$omp depobj(obj(2)) depend(in: bbb) + + !$omp parallel num_threads(5) + !$omp single + + !$omp task depend (out: ppp) + write (*,*) "task 1 (start)" + call usleep(40) + if (x1 /= 43) stop 11 + if (x2 /= 44) stop 12 + x1 = 11 + write (*,*) "task 1 (end)" + !$omp end task + + !$omp task depend(inout: ppp) + write (*,*) "task 2 (start)" + call usleep(30) + if (x1 /= 11) stop 21 + if (x2 /= 44) stop 22 + x1 = 111 + x2 = 222 + write (*,*) "task 2 (end)" + !$omp end task + + !$omp task depend(out: bbb) + write (*,*) "task 3 (start)" + call usleep(40) + if (x3 /= 45) stop 3 + x3 = 33 + write (*,*) "task 3 (end)" + !$omp end task + + !$omp task depend(depobj: obj(1), obj(2)) + write (*,*) "task 4 (start)" + if (x1 /= 111) stop 41 + if (x2 /= 222) stop 42 + if (x3 /= 33) stop 43 + call usleep(10) + x1 = 411 + x2 = 422 + x3 = 433 + write (*,*) "task 4 (end)" + !$omp end task + + !$omp task depend(in: ppp) + if (x1 /= 411) stop 51 + if (x2 /= 422) stop 52 + if (x3 /= 433) stop 53 + write (*,*) "task 5" + !$omp end task + + !$omp end single + !$omp end parallel + + ! expectation (task dependencies): + ! 1 - 2 \ + ! 4 - 5 + ! 3 ----/ + +end program main + +! Ensure that the pointer target address for ppp is taken +! but the address of bbb itself: + +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:ppp\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(inout:ppp\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(out:&bbb\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(depobj:&obj\\\[0\\\]\\) depend\\(depobj:&obj\\\[1\\\]\\)" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "#pragma omp task depend\\(in:ppp\\)" 1 "gimple" } } + +! { dg-final { scan-tree-dump-times "MEM\\\[\[^\r\n]+\\\] = ppp;" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "MEM\\\[\[^\r\n]+\\\] = &bbb;" 1 "gimple" } } -- 2.7.4