aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-parser.c36
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c26
-rw-r--r--gcc/gimplify.c4
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-11.C306
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-12.C9
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-13.C43
-rw-r--r--gcc/testsuite/g++.dg/gomp/atomic-14.C19
-rw-r--r--gcc/testsuite/gcc.dg/gomp/atomic-12.c306
-rw-r--r--gcc/testsuite/gcc.dg/gomp/atomic-13.c9
-rw-r--r--gcc/testsuite/gcc.dg/gomp/atomic-14.c43
13 files changed, 826 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 39eb13c..fe0a0d5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 031c688..13e6350 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -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)
{
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ac879d7..de8575c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b71d145..769d7dc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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)
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 32d07f0..897fe13 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index df1525d..62d329b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..618c4c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/atomic-11.C
@@ -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
index 0000000..6c1f965
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/atomic-12.C
@@ -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
index 0000000..f8fc9d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/atomic-13.C
@@ -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
index 0000000..ae1eb50d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/atomic-14.C
@@ -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
index 0000000..618c4c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/atomic-12.c
@@ -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
index 0000000..0146825
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/atomic-13.c
@@ -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
index 0000000..f8fc9d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/atomic-14.c
@@ -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;
+}