re PR fortran/92977 (ICE in gfc_trans_omp_atomic, at fortran/trans-openmp.c:3526)
authorJakub Jelinek <jakub@redhat.com>
Wed, 18 Dec 2019 23:33:54 +0000 (00:33 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 18 Dec 2019 23:33:54 +0000 (00:33 +0100)
PR fortran/92977
* frontend-passes.c (in_omp_atomic): New variable.
(cfe_expr_0, matmul_to_var_expr, matmul_temp_args,
inline_matmul_assign, call_external_blas): Don't optimize in
EXEC_OMP_ATOMIC.
(optimize_namespace): Clear in_omp_atomic.
(gfc_code_walker): Set in_omp_atomic for EXEC_OMP_ATOMIC, save/restore
it around.

* gfortran.dg/gomp/pr92977.f90: New test.

From-SVN: r279554

gcc/fortran/ChangeLog
gcc/fortran/frontend-passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/gomp/pr92977.f90 [new file with mode: 0644]

index e45ec22bd9e799b541d6b3521918e739af4ee34d..12465bf43782a6a3afa97556f3241130d8901189 100644 (file)
@@ -1,3 +1,14 @@
+2019-12-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR fortran/92977
+       * frontend-passes.c (in_omp_atomic): New variable.
+       (cfe_expr_0, matmul_to_var_expr, matmul_temp_args,
+       inline_matmul_assign, call_external_blas): Don't optimize in
+       EXEC_OMP_ATOMIC.
+       (optimize_namespace): Clear in_omp_atomic.
+       (gfc_code_walker): Set in_omp_atomic for EXEC_OMP_ATOMIC, save/restore
+       it around.
+
 2019-12-19  Julian Brown  <julian@codesourcery.com>
            Maciej W. Rozycki  <macro@codesourcery.com>
            Tobias Burnus  <tobias@codesourcery.com>
index a20d9efa23190b4f9edf11f36717a8afa65740bb..5f83ad27c2cb2ae052cebe0d481b374e2c0d938c 100644 (file)
@@ -92,6 +92,10 @@ static int forall_level;
 
 static bool in_omp_workshare;
 
+/* Keep track of whether we are within an OMP atomic.  */
+
+static bool in_omp_atomic;
+
 /* Keep track of whether we are within a WHERE statement.  */
 
 static bool in_where;
@@ -913,9 +917,9 @@ cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
   gfc_expr *newvar;
   gfc_expr **ei, **ej;
 
-  /* Don't do this optimization within OMP workshare or ASSOC lists.  */
+  /* Don't do this optimization within OMP workshare/atomic or ASSOC lists.  */
 
-  if (in_omp_workshare || in_assoc_list)
+  if (in_omp_workshare || in_omp_atomic || in_assoc_list)
     {
       *walk_subtrees = 0;
       return 0;
@@ -1464,6 +1468,7 @@ optimize_namespace (gfc_namespace *ns)
   iterator_level = 0;
   in_assoc_list = false;
   in_omp_workshare = false;
+  in_omp_atomic = false;
 
   if (flag_frontend_optimize)
     {
@@ -2818,7 +2823,7 @@ matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
     return 0;
 
   if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
-      || in_where || in_assoc_list)
+      || in_omp_atomic || in_where || in_assoc_list)
     return 0;
 
   /* Check if this is already in the form c = matmul(a,b).  */
@@ -2880,7 +2885,7 @@ matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
     return 0;
 
   if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
-      || in_where)
+      || in_omp_atomic || in_where)
     return 0;
 
   /* This has some duplication with inline_matmul_assign.  This
@@ -3848,7 +3853,7 @@ inline_matmul_assign (gfc_code **c, int *walk_subtrees,
   /* For now don't do anything in OpenMP workshare, it confuses
      its translation, which expects only the allowed statements in there.
      We should figure out how to parallelize this eventually.  */
-  if (in_omp_workshare)
+  if (in_omp_workshare || in_omp_atomic)
     return 0;
 
   expr1 = co->expr1;
@@ -4385,7 +4390,7 @@ call_external_blas (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
   /* For now don't do anything in OpenMP workshare, it confuses
      its translation, which expects only the allowed statements in there. */
 
-  if (in_omp_workshare)
+  if (in_omp_workshare | in_omp_atomic)
     return 0;
 
   expr1 = co->expr1;
@@ -5047,6 +5052,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
          gfc_code *co;
          gfc_association_list *alist;
          bool saved_in_omp_workshare;
+         bool saved_in_omp_atomic;
          bool saved_in_where;
 
          /* There might be statement insertions before the current code,
@@ -5054,6 +5060,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 
          co = *c;
          saved_in_omp_workshare = in_omp_workshare;
+         saved_in_omp_atomic = in_omp_atomic;
          saved_in_where = in_where;
 
          switch (co->op)
@@ -5251,6 +5258,10 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
              WALK_SUBEXPR (co->ext.dt->extra_comma);
              break;
 
+           case EXEC_OMP_ATOMIC:
+             in_omp_atomic = true;
+             break;
+
            case EXEC_OMP_PARALLEL:
            case EXEC_OMP_PARALLEL_DO:
            case EXEC_OMP_PARALLEL_DO_SIMD:
@@ -5368,6 +5379,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
            select_level --;
 
          in_omp_workshare = saved_in_omp_workshare;
+         in_omp_atomic = saved_in_omp_atomic;
          in_where = saved_in_where;
        }
     }
index 55a550cb56fa3d03bef4c21a9ca12dfe1ed1ed72..7fd6710168ed552bd6be0c18438bd85b587d5fcb 100644 (file)
@@ -1,3 +1,8 @@
+2019-12-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR fortran/92977
+       * gfortran.dg/gomp/pr92977.f90: New test.
+
 2019-12-19  Julian Brown  <julian@codesourcery.com>
            Maciej W. Rozycki  <macro@codesourcery.com>
            Tobias Burnus  <tobias@codesourcery.com>
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr92977.f90 b/gcc/testsuite/gfortran.dg/gomp/pr92977.f90
new file mode 100644 (file)
index 0000000..0c31f47
--- /dev/null
@@ -0,0 +1,15 @@
+! PR fortran/92977
+! { dg-do compile }
+! { dg-additional-options "-O2" }
+
+program pr92977
+  integer :: n = 1
+  integer :: a
+!$omp atomic write
+  a = f(n) - f(n)
+contains
+  integer function f(x)
+    integer, intent(in) :: x
+    f = x
+  end
+end