re PR middle-end/45423 (#pragma omp atomic on bool has issues)
authorJakub Jelinek <jakub@redhat.com>
Mon, 30 Aug 2010 17:16:29 +0000 (19:16 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 30 Aug 2010 17:16:29 +0000 (19:16 +0200)
PR middle-end/45423
* gimplify.c (goa_stabilize_expr): Handle TRUTH_NOT_EXPR
and TRUTH_{AND,OR,XOR}_EXPR.
* c-parser.c (c_parser_omp_atomic): Handle boolean
{PRE,POST}_{INC,DEC}REMENT.
cp/
* parser.c (cp_parser_omp_atomic): Handle boolean
{PRE,POST}_INCREMENT.
testsuite/
* gcc.dg/gomp/atomic-12.c: New test.
* gcc.dg/gomp/atomic-13.c: New test.
* gcc.dg/gomp/atomic-14.c: New test.
* g++.dg/gomp/atomic-11.C: New test.
* g++.dg/gomp/atomic-12.C: New test.
* g++.dg/gomp/atomic-13.C: New test.
* g++.dg/gomp/atomic-14.C: New test.

From-SVN: r163653

13 files changed:
gcc/ChangeLog
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/atomic-11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/atomic-12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/atomic-13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/atomic-14.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-14.c [new file with mode: 0644]

index 39eb13c..fe0a0d5 100644 (file)
@@ -1,3 +1,11 @@
+2010-08-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/45423
+       * gimplify.c (goa_stabilize_expr): Handle TRUTH_NOT_EXPR
+       and TRUTH_{AND,OR,XOR}_EXPR.
+       * c-parser.c (c_parser_omp_atomic): Handle boolean
+       {PRE,POST}_{INC,DEC}REMENT.
+
 2010-08-30  Nathan Froyd  <froydnj@codesourcery.com>
 
        * config/xtensa/xtensa-protos.h (function_arg_advance): Delete.
index 031c688..13e6350 100644 (file)
@@ -8004,6 +8004,42 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
       rhs = integer_one_node;
       break;
 
+    case COMPOUND_EXPR:
+      if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
+         && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
+         && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
+         && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
+         && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
+                                             (TREE_OPERAND (lhs, 1), 0), 0)))
+            == BOOLEAN_TYPE)
+       /* Undo effects of boolean_increment for post {in,de}crement.  */
+       lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
+      /* FALLTHRU */
+    case MODIFY_EXPR:
+      if (TREE_CODE (lhs) == MODIFY_EXPR
+         && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
+       {
+         /* Undo effects of boolean_increment.  */
+         if (integer_onep (TREE_OPERAND (lhs, 1)))
+           {
+             /* This is pre or post increment.  */
+             rhs = TREE_OPERAND (lhs, 1);
+             lhs = TREE_OPERAND (lhs, 0);
+             code = NOP_EXPR;
+             break;
+           }
+         if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
+             && TREE_OPERAND (lhs, 0)
+                == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
+           {
+             /* This is pre or post decrement.  */
+             rhs = TREE_OPERAND (lhs, 1);
+             lhs = TREE_OPERAND (lhs, 0);
+             code = NOP_EXPR;
+             break;
+           }
+       }
+      /* FALLTHRU */
     default:
       switch (c_parser_peek_token (parser)->type)
        {
index ac879d7..de8575c 100644 (file)
@@ -1,3 +1,9 @@
+2010-08-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/45423
+       * parser.c (cp_parser_omp_atomic): Handle boolean
+       {PRE,POST}_INCREMENT.
+
 2010-08-29  Jason Merrill  <jason@redhat.com>
 
        PR c++/44991
index b71d145..769d7dc 100644 (file)
@@ -22494,6 +22494,32 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
       rhs = integer_one_node;
       break;
 
+    case COMPOUND_EXPR:
+      if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
+        && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
+        && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
+        && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
+        && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
+                                            (TREE_OPERAND (lhs, 1), 0), 0)))
+           == BOOLEAN_TYPE)
+       /* Undo effects of boolean_increment for post {in,de}crement.  */
+       lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
+      /* FALLTHRU */
+    case MODIFY_EXPR:
+      if (TREE_CODE (lhs) == MODIFY_EXPR
+        && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
+       {
+        /* Undo effects of boolean_increment.  */
+        if (integer_onep (TREE_OPERAND (lhs, 1)))
+          {
+            /* This is pre or post increment.  */
+            rhs = TREE_OPERAND (lhs, 1);
+            lhs = TREE_OPERAND (lhs, 0);
+            code = NOP_EXPR;
+            break;
+          }
+       }
+      /* FALLTHRU */
     default:
       switch (cp_lexer_peek_token (parser->lexer)->type)
        {
index 32d07f0..897fe13 100644 (file)
@@ -6405,8 +6405,12 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
        {
        case TRUTH_ANDIF_EXPR:
        case TRUTH_ORIF_EXPR:
+       case TRUTH_AND_EXPR:
+       case TRUTH_OR_EXPR:
+       case TRUTH_XOR_EXPR:
          saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
                                         lhs_addr, lhs_var);
+       case TRUTH_NOT_EXPR:
          saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
                                         lhs_addr, lhs_var);
          break;
index df1525d..62d329b 100644 (file)
@@ -1,3 +1,14 @@
+2010-08-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/45423
+       * gcc.dg/gomp/atomic-12.c: New test.
+       * gcc.dg/gomp/atomic-13.c: New test.
+       * gcc.dg/gomp/atomic-14.c: New test.
+       * g++.dg/gomp/atomic-11.C: New test.
+       * g++.dg/gomp/atomic-12.C: New test.
+       * g++.dg/gomp/atomic-13.C: New test.
+       * g++.dg/gomp/atomic-14.C: New test.
+
 2010-08-30  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * g++.dg/debug/dwarf2/nested-2.C: Allow for single / as comment
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-11.C b/gcc/testsuite/g++.dg/gomp/atomic-11.C
new file mode 100644 (file)
index 0000000..618c4c8
--- /dev/null
@@ -0,0 +1,306 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple -g0" } */
+/* atomicvar should never be referenced in between the barrier and
+   following #pragma omp atomic_load.  */
+/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
+
+#ifdef __cplusplus
+bool atomicvar, c;
+#else
+_Bool atomicvar, c;
+#endif
+int i, atomicvar2, c2;
+
+int
+foo (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++atomicvar;
+  #pragma omp barrier
+#ifndef __cplusplus
+  #pragma omp atomic
+    atomicvar--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --atomicvar;
+  #pragma omp barrier
+#endif
+  return 0;
+}
+
+int
+bar (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++atomicvar2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --atomicvar2;
+  #pragma omp barrier
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-12.C b/gcc/testsuite/g++.dg/gomp/atomic-12.C
new file mode 100644 (file)
index 0000000..6c1f965
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -O2" } */
+/* atomicvar should never be referenced in between the barrier and
+   following #pragma omp atomic_load.  */
+/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
+
+#include "atomic-11.C"
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-13.C b/gcc/testsuite/g++.dg/gomp/atomic-13.C
new file mode 100644 (file)
index 0000000..f8fc9d8
--- /dev/null
@@ -0,0 +1,43 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#ifdef __cplusplus
+bool *baz ();
+#else
+_Bool *baz ();
+#endif
+int *bar ();
+
+int
+foo (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    (*bar ())++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++(*bar ());
+  #pragma omp barrier
+  #pragma omp atomic
+    (*bar ())--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --(*bar ());
+  #pragma omp barrier
+  #pragma omp atomic
+    (*baz ())++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++(*baz ());
+#ifndef __cplusplus
+  #pragma omp barrier
+  #pragma omp atomic
+    (*baz ())--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --(*baz ());
+  #pragma omp barrier
+#endif
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/atomic-14.C b/gcc/testsuite/g++.dg/gomp/atomic-14.C
new file mode 100644 (file)
index 0000000..ae1eb50
--- /dev/null
@@ -0,0 +1,19 @@
+// PR middle-end/45423
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+bool *baz (), atomicvar;
+
+int
+foo (void)
+{
+  #pragma omp atomic
+    (*baz ())--;       // { dg-error "invalid use of Boolean" }
+  #pragma omp atomic
+    --(*baz ());       // { dg-error "invalid use of Boolean" }
+  #pragma omp atomic
+    atomicvar--;       // { dg-error "invalid use of Boolean" }
+  #pragma omp atomic
+    --atomicvar;       // { dg-error "invalid use of Boolean" }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-12.c b/gcc/testsuite/gcc.dg/gomp/atomic-12.c
new file mode 100644 (file)
index 0000000..618c4c8
--- /dev/null
@@ -0,0 +1,306 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple -g0" } */
+/* atomicvar should never be referenced in between the barrier and
+   following #pragma omp atomic_load.  */
+/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
+
+#ifdef __cplusplus
+bool atomicvar, c;
+#else
+_Bool atomicvar, c;
+#endif
+int i, atomicvar2, c2;
+
+int
+foo (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar |= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar ^= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar &= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar += c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar -= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar *= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar /= c;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar <<= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar >>= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++atomicvar;
+  #pragma omp barrier
+#ifndef __cplusplus
+  #pragma omp atomic
+    atomicvar--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --atomicvar;
+  #pragma omp barrier
+#endif
+  return 0;
+}
+
+int
+bar (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 |= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 ^= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 &= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 += c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 -= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 *= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= -1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 /= c2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 <<= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 0;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 1;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= 2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2 >>= i;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++atomicvar2;
+  #pragma omp barrier
+  #pragma omp atomic
+    atomicvar2--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --atomicvar2;
+  #pragma omp barrier
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-13.c b/gcc/testsuite/gcc.dg/gomp/atomic-13.c
new file mode 100644 (file)
index 0000000..0146825
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-gimple -g0 -O2" } */
+/* atomicvar should never be referenced in between the barrier and
+   following #pragma omp atomic_load.  */
+/* { dg-final { scan-tree-dump-not "barrier\[^#\]*atomicvar" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
+
+#include "atomic-12.c"
diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-14.c b/gcc/testsuite/gcc.dg/gomp/atomic-14.c
new file mode 100644 (file)
index 0000000..f8fc9d8
--- /dev/null
@@ -0,0 +1,43 @@
+/* PR middle-end/45423 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#ifdef __cplusplus
+bool *baz ();
+#else
+_Bool *baz ();
+#endif
+int *bar ();
+
+int
+foo (void)
+{
+  #pragma omp barrier
+  #pragma omp atomic
+    (*bar ())++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++(*bar ());
+  #pragma omp barrier
+  #pragma omp atomic
+    (*bar ())--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --(*bar ());
+  #pragma omp barrier
+  #pragma omp atomic
+    (*baz ())++;
+  #pragma omp barrier
+  #pragma omp atomic
+    ++(*baz ());
+#ifndef __cplusplus
+  #pragma omp barrier
+  #pragma omp atomic
+    (*baz ())--;
+  #pragma omp barrier
+  #pragma omp atomic
+    --(*baz ());
+  #pragma omp barrier
+#endif
+  return 0;
+}