Fortran: OpenMP - fix simd with (last)private (PR97061)
authorTobias Burnus <tobias@codesourcery.com>
Wed, 16 Sep 2020 14:23:13 +0000 (16:23 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Wed, 16 Sep 2020 14:23:13 +0000 (16:23 +0200)
gcc/fortran/ChangeLog:

PR fortran/97061
* trans-openmp.c (gfc_trans_omp_do): Handle simd with (last)private.

gcc/testsuite/ChangeLog:

PR fortran/97061
* gfortran.dg/gomp/openmp-simd-6.f90: New test.

gcc/fortran/trans-openmp.c
gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 [new file with mode: 0644]

index 9ec0df204ac43c18525379cddbde6ea1393aaa1d..378088a9d040e417183eb9aa85a57590ed27f8c0 100644 (file)
@@ -4401,20 +4401,29 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
       if (clauses)
        {
          gfc_omp_namelist *n = NULL;
-         if (op != EXEC_OMP_DISTRIBUTE)
-           for (n = clauses->lists[(op == EXEC_OMP_SIMD && collapse == 1)
-                                   ? OMP_LIST_LINEAR : OMP_LIST_LASTPRIVATE];
+         if (op == EXEC_OMP_SIMD && collapse == 1)
+           for (n = clauses->lists[OMP_LIST_LINEAR];
                 n != NULL; n = n->next)
              if (code->ext.iterator->var->symtree->n.sym == n->sym)
-               break;
-         if (n != NULL)
-           dovar_found = 1;
-         else if (n == NULL && op != EXEC_OMP_SIMD)
+               {
+                 dovar_found = 3;
+                 break;
+               }
+         if (n == NULL && op != EXEC_OMP_DISTRIBUTE)
+           for (n = clauses->lists[OMP_LIST_LASTPRIVATE];
+                n != NULL; n = n->next)
+             if (code->ext.iterator->var->symtree->n.sym == n->sym)
+               {
+                 dovar_found = 2;
+                 break;
+               }
+         if (n == NULL)
            for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
              if (code->ext.iterator->var->symtree->n.sym == n->sym)
-               break;
-         if (n != NULL)
-           dovar_found++;
+               {
+                 dovar_found = 1;
+                 break;
+               }
        }
 
       /* Evaluate all the expressions in the iterator.  */
@@ -4512,7 +4521,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
       if (orig_decls)
        TREE_VEC_ELT (orig_decls, i) = dovar_decl;
 
-      if (dovar_found == 2
+      if (dovar_found == 3
          && op == EXEC_OMP_SIMD
          && collapse == 1
          && !simple)
@@ -4536,7 +4545,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
              omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
            }
          if (!simple)
-           dovar_found = 2;
+           dovar_found = 3;
        }
       else if (!dovar_found && !simple)
        {
@@ -4544,7 +4553,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
          OMP_CLAUSE_DECL (tmp) = dovar_decl;
          omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
        }
-      if (dovar_found == 2)
+      if (dovar_found > 1)
        {
          tree c = NULL;
 
@@ -4612,7 +4621,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
        }
       if (!simple)
        {
-         if (op != EXEC_OMP_SIMD)
+         if (op != EXEC_OMP_SIMD || dovar_found == 1)
            tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
          else if (collapse == 1)
            {
diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90
new file mode 100644 (file)
index 0000000..361e0da
--- /dev/null
@@ -0,0 +1,62 @@
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/97061
+
+integer function f3 (a1, b1, u)
+  implicit none
+  integer :: a1, b1, d1
+  integer u(0:1023)
+  !$omp teams distribute parallel do simd default(none) firstprivate (a1, b1) shared(u) lastprivate(d1) 
+  do d1 = a1, b1-1
+      u(d1) = 5
+  end do
+end
+
+subroutine foo(n, m, u)
+  implicit none
+  integer :: hh, ii, jj, n, m
+  integer u(0:1023)
+  !$omp simd private(ii)
+  do ii = n, m
+    u(ii) = 5
+  end do
+  !$omp simd linear(jj:1)
+  do jj = 2, m+n
+    u(jj) = 6
+  end do
+  !$omp simd
+  do hh = 2, m+n
+    u(hh) = 6
+  end do
+end
+
+subroutine bar(n, m, u)
+  implicit none
+  integer :: kkk, lll, ooo, ppp, n, m
+  integer u(:,:)
+  !$omp simd lastprivate(kkk) lastprivate(lll) collapse(2)
+  do kkk = n, m
+    do lll = n, m
+      u(kkk, lll) = 5
+    end do
+  end do
+  !$omp simd private(kkk) private(lll) collapse(2)
+  do ooo = n, m
+    do ppp = n, m
+      u(ooo, ppp) = 5
+    end do
+  end do
+end
+
+
+! { dg-final { scan-tree-dump-times "#pragma omp teams firstprivate\\(a1\\) firstprivate\\(b1\\) shared\\(u\\) default\\(none\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp distribute lastprivate\\(d1\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a1\\) firstprivate\\(b1\\) lastprivate\\(d1\\) shared\\(u\\) default\\(none\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd lastprivate\\(d1\\)" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp simd private\\(ii\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(jj:1\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(hh:1\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd lastprivate\\(kkk\\) lastprivate\\(lll\\) collapse\\(2\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd private\\(kkk\\) private\\(lll\\) collapse\\(2\\)" 1 "original" } }