aboutsummaryrefslogtreecommitdiff
path: root/libgomp/testsuite/libgomp.c-c++-common/atomic-20.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-09-10 20:41:33 +0200
committerJakub Jelinek <jakub@redhat.com>2021-09-10 20:41:33 +0200
commit8122fbff770bcff183a9c3c72e8092c0ca32150b (patch)
treece01fc417dc7920da04a312ab2abcd350adec6c0 /libgomp/testsuite/libgomp.c-c++-common/atomic-20.c
parentb7f84702b364d49824ca97d4a2fc01567301d784 (diff)
downloadgcc-8122fbff770bcff183a9c3c72e8092c0ca32150b.zip
gcc-8122fbff770bcff183a9c3c72e8092c0ca32150b.tar.gz
gcc-8122fbff770bcff183a9c3c72e8092c0ca32150b.tar.bz2
openmp: Implement OpenMP 5.1 atomics, so far for C only
This patch implements OpenMP 5.1 atomics (with clarifications from upcoming 5.2). The most important changes are that it is now possible to write (for C/C++, for Fortran it was possible before already) min/max atomics and more importantly compare and exchange in various forms. Also, acq_rel is now allowed on read/write and acq_rel/acquire are allowed on update, and there are new compare, weak and fail clauses. 2021-09-10 Jakub Jelinek <jakub@redhat.com> gcc/ * tree-core.h (enum omp_memory_order): Add OMP_MEMORY_ORDER_MASK, OMP_FAIL_MEMORY_ORDER_UNSPECIFIED, OMP_FAIL_MEMORY_ORDER_RELAXED, OMP_FAIL_MEMORY_ORDER_ACQUIRE, OMP_FAIL_MEMORY_ORDER_RELEASE, OMP_FAIL_MEMORY_ORDER_ACQ_REL, OMP_FAIL_MEMORY_ORDER_SEQ_CST and OMP_FAIL_MEMORY_ORDER_MASK enumerators. (OMP_FAIL_MEMORY_ORDER_SHIFT): Define. * gimple-pretty-print.c (dump_gimple_omp_atomic_load, dump_gimple_omp_atomic_store): Print [weak] for weak atomic load/store. * gimple.h (enum gf_mask): Change GF_OMP_ATOMIC_MEMORY_ORDER to 6-bit mask, adjust GF_OMP_ATOMIC_NEED_VALUE value and add GF_OMP_ATOMIC_WEAK. (gimple_omp_atomic_weak_p, gimple_omp_atomic_set_weak): New inline functions. * tree.h (OMP_ATOMIC_WEAK): Define. * tree-pretty-print.c (dump_omp_atomic_memory_order): Adjust for fail memory order being encoded in the same enum and also print fail clause if present. (dump_generic_node): Print weak clause if OMP_ATOMIC_WEAK. * gimplify.c (goa_stabilize_expr): Add target_expr and rhs arguments, handle pre_p == NULL case as a test mode that only returns value but doesn't change gimplify nor change anything otherwise, adjust recursive calls, add MODIFY_EXPR, ADDR_EXPR, COND_EXPR, TARGET_EXPR and CALL_EXPR handling, adjust COMPOUND_EXPR handling for __builtin_clear_padding calls, for !rhs gimplify as lvalue rather than rvalue. (gimplify_omp_atomic): Adjust goa_stabilize_expr caller. Handle COND_EXPR rhs. Set weak flag on gimple load/store for OMP_ATOMIC_WEAK. * omp-expand.c (omp_memory_order_to_fail_memmodel): New function. (omp_memory_order_to_memmodel): Adjust for fail clause encoded in the same enum. (expand_omp_atomic_cas): New function. (expand_omp_atomic_pipeline): Use omp_memory_order_to_fail_memmodel function. (expand_omp_atomic): Attempt to optimize atomic compare and exchange using expand_omp_atomic_cas. gcc/c-family/ * c-common.h (c_finish_omp_atomic): Add r and weak arguments. * c-omp.c: Include gimple-fold.h. (c_finish_omp_atomic): Add r and weak arguments. Add support for OpenMP 5.1 atomics. gcc/c/ * c-parser.c (c_parser_conditional_expression): If omp_atomic_lhs and cond.value is >, < or == with omp_atomic_lhs as one of the operands, don't call build_conditional_expr, instead build a COND_EXPR directly. (c_parser_binary_expression): Avoid calling parser_build_binary_op if omp_atomic_lhs even in more cases for >, < or ==. (c_parser_omp_atomic): Update function comment for OpenMP 5.1 atomics, parse OpenMP 5.1 atomics and fail, compare and weak clauses, allow acq_rel on atomic read/write and acq_rel/acquire clauses on update. * c-typeck.c (build_binary_op): For flag_openmp only handle MIN_EXPR/MAX_EXPR. gcc/cp/ * parser.c (cp_parser_omp_atomic): Allow acq_rel on atomic read/write and acq_rel/acquire clauses on update. * semantics.c (finish_omp_atomic): Adjust c_finish_omp_atomic caller. gcc/testsuite/ * c-c++-common/gomp/atomic-17.c (foo): Add tests for atomic read, write or update with acq_rel clause and atomic update with acquire clause. * c-c++-common/gomp/atomic-18.c (foo): Adjust expected diagnostics wording, remove tests moved to atomic-17.c. * c-c++-common/gomp/atomic-21.c: Expect only 2 omp atomic release and 2 omp atomic acq_rel directives instead of 4 omp atomic release. * c-c++-common/gomp/atomic-25.c: New test. * c-c++-common/gomp/atomic-26.c: New test. * c-c++-common/gomp/atomic-27.c: New test. * c-c++-common/gomp/atomic-28.c: New test. * c-c++-common/gomp/atomic-29.c: New test. * c-c++-common/gomp/atomic-30.c: New test. * c-c++-common/goacc-gomp/atomic.c: Expect 1 omp atomic release and 1 omp atomic_acq_rel instead of 2 omp atomic release directives. * gcc.dg/gomp/atomic-5.c: Adjust expected error diagnostic wording. * g++.dg/gomp/atomic-18.C:Expect 4 omp atomic release and 1 omp atomic_acq_rel instead of 5 omp atomic release directives. libgomp/ * testsuite/libgomp.c-c++-common/atomic-19.c: New test. * testsuite/libgomp.c-c++-common/atomic-20.c: New test. * testsuite/libgomp.c-c++-common/atomic-21.c: New test.
Diffstat (limited to 'libgomp/testsuite/libgomp.c-c++-common/atomic-20.c')
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/atomic-20.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/libgomp/testsuite/libgomp.c-c++-common/atomic-20.c b/libgomp/testsuite/libgomp.c-c++-common/atomic-20.c
new file mode 100644
index 0000000..571a714
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/atomic-20.c
@@ -0,0 +1,203 @@
+// { dg-do run { target c } }
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+float x = 6.0f;
+
+int
+main ()
+{
+ float v;
+ int r;
+ #pragma omp atomic compare
+ x = x > 8.0f ? 8.0f : x;
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ #pragma omp atomic compare
+ x = x > 4.0f ? 4.0f : x;
+ #pragma omp atomic read
+ v = x;
+ if (v != 4.0f)
+ abort ();
+ #pragma omp atomic compare capture
+ v = x = x < 8.0f ? 8.0f : x;
+ if (v != 8.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 8)
+ abort ();
+ #pragma omp atomic capture compare
+ { v = x; x = x < 12.0f ? 12.0f : x; }
+ if (v != 8.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic capture compare
+ { v = x; x = x < 4.0f ? 4.0f : x; }
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic compare
+ x = x == 12.0 ? 16.0L : x;
+ #pragma omp atomic read
+ v = x;
+ if (v != 16.0)
+ abort ();
+ r = 57;
+ #pragma omp atomic compare capture
+ v = x = x == 15.0f ? r + 7.0f : x;
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic capture, update, compare seq_cst fail(acquire)
+ { v = x; x = x == 73.0L - r ? 12.0f : x; }
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic update, compare, capture
+ { x = x == 69.0 - r ? 6.0f : x; v = x; }
+ if (v != 6.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ #pragma omp atomic compare
+ if (x > 8.0f) { x = 8.0f; }
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ #pragma omp atomic compare
+ if (x > 4.0) { x = 4.0; }
+ #pragma omp atomic read
+ v = x;
+ if (v != 4.0f)
+ abort ();
+ #pragma omp atomic compare capture
+ { if (x < 8.0f) { x = 8.0f; } v = x; }
+ if (v != 8.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 8.0f)
+ abort ();
+ #pragma omp atomic capture compare
+ { v = x; if (x < 12.0f) { x = 12.0f; } }
+ if (v != 8.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic capture compare
+ { v = x; if (x < 4.0L) { x = 4.0L; } }
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic compare
+ if (x == 12.0f) { x = 16.0L; }
+ #pragma omp atomic read
+ v = x;
+ if (v != 16.0f)
+ abort ();
+ r = 57.0;
+ #pragma omp atomic compare capture
+ { if (x == 15.0f) { x = r + 7.0f; } v = x; }
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic capture, update, compare seq_cst fail(acquire)
+ { v = x; if (x == 73.0L - r) { x = 12.0L; } }
+ if (v != 16.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12.0f)
+ abort ();
+ #pragma omp atomic update, compare, capture
+ { if (x == 69.0L - r) { x = 6.0; } v = x; }
+ if (v != 6.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ v = 24;
+ #pragma omp atomic compare capture
+ if (x == 12.0f) { x = 16.0f; } else { v = x; }
+ if (v != 6.0f)
+ abort ();
+ v = 32.0f;
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ v = 147.0f;
+ #pragma omp atomic capture compare
+ if (x == 6.0f) { x = 57.0f; } else { v = x; }
+ if (v != 147.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 57.0f)
+ abort ();
+ #pragma omp atomic update, capture, compare, weak, seq_cst, fail (relaxed)
+ { r = x == 137.0f; if (r) { x = 174.0f; } }
+ if (r)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 57.0f)
+ abort ();
+ #pragma omp atomic compare capture fail (relaxed)
+ { r = x == 57.0f; if (r) { x = 6.0f; } }
+ if (r != 1)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ v = -5.0f;
+ #pragma omp atomic capture compare
+ { r = x == 17.0L; if (r) { x = 25.0; } else { v = x; } }
+ if (r || v != 6.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 6.0f)
+ abort ();
+ v = 15.0f;
+ #pragma omp atomic capture compare
+ { r = x == 6.0f; if (r) { x = 23.0f; } else { v = x; } }
+ if (r != 1 || v != 15.0f)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 23.0f)
+ abort ();
+ return 0;
+}