aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-02-07 14:37:26 +0000
committerJakub Jelinek <jakub@redhat.com>2019-02-07 14:37:26 +0000
commita3b7eab5777578ee2c99a1ac665999b48fc53d17 (patch)
treeb652b1297b02ef284c6f9d5b8f02bf8ceed50a91
parentc1f69134d620b81fb42721eb27a0464980632517 (diff)
Backported from mainline
2019-01-22 Jakub Jelinek <jakub@redhat.com> PR middle-end/88968 * gimplify.c (gimplify_omp_atomic): Handle bitfield atomics with non-integral DECL_BIT_FIELD_REPRESENTATIVEs. * c-omp.c (c_finish_omp_atomic): For bitfield atomics, update type variable after using BIT_FIELD_REF. * c-c++-common/gomp/atomic-23.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-8-branch@268628 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-omp.c7
-rw-r--r--gcc/gimplify.c33
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-23.c47
6 files changed, 95 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca9fab01cbe..d86c34024cf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -3,6 +3,10 @@
Backported from mainline
2019-01-22 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/88968
+ * gimplify.c (gimplify_omp_atomic): Handle bitfield atomics with
+ non-integral DECL_BIT_FIELD_REPRESENTATIVEs.
+
PR target/88905
* optabs.c (add_equal_note): Add op0_mode argument, use it instead of
GET_MODE (op0).
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 8e96c27b543..742bd67598e 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,6 +1,12 @@
2019-02-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2019-01-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/88968
+ * c-omp.c (c_finish_omp_atomic): For bitfield atomics, update type
+ variable after using BIT_FIELD_REF.
+
2019-01-14 Jakub Jelinek <jakub@redhat.com>
* c-cppbuiltin.c (c_cpp_builtin): Define __cpp_guaranteed_copy_elision
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index d8695f517af..8922759124d 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -373,8 +373,11 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
}
}
if (blhs)
- x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
- bitsize_int (bitsize), bitsize_int (bitpos));
+ {
+ x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
+ bitsize_int (bitsize), bitsize_int (bitpos));
+ type = TREE_TYPE (blhs);
+ }
x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
loc, x, NULL_TREE);
if (rhs1 && rhs1 != orig_lhs)
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4d3268bfcf7..b2b6f22f47e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -11057,9 +11057,36 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
loadstmt = gimple_build_omp_atomic_load (tmp_load, addr);
gimplify_seq_add_stmt (pre_p, loadstmt);
- if (rhs && gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
- != GS_ALL_DONE)
- return GS_ERROR;
+ if (rhs)
+ {
+ /* BIT_INSERT_EXPR is not valid for non-integral bitfield
+ representatives. Use BIT_FIELD_REF on the lhs instead. */
+ if (TREE_CODE (rhs) == BIT_INSERT_EXPR
+ && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
+ {
+ tree bitpos = TREE_OPERAND (rhs, 2);
+ tree op1 = TREE_OPERAND (rhs, 1);
+ tree bitsize;
+ tree tmp_store = tmp_load;
+ if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
+ tmp_store = get_initialized_tmp_var (tmp_load, pre_p, NULL);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
+ bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
+ else
+ bitsize = TYPE_SIZE (TREE_TYPE (op1));
+ gcc_assert (TREE_OPERAND (rhs, 0) == tmp_load);
+ tree t = build2_loc (EXPR_LOCATION (rhs),
+ MODIFY_EXPR, void_type_node,
+ build3_loc (EXPR_LOCATION (rhs), BIT_FIELD_REF,
+ TREE_TYPE (op1), tmp_store, bitsize,
+ bitpos), op1);
+ gimplify_and_add (t, pre_p);
+ rhs = tmp_store;
+ }
+ if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
+ != GS_ALL_DONE)
+ return GS_ERROR;
+ }
if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
rhs = tmp_load;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d1f9e2f90c6..6a4fd8a5098 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -3,6 +3,9 @@
Backported from mainline
2019-01-22 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/88968
+ * c-c++-common/gomp/atomic-23.c: New test.
+
PR target/88905
* gcc.dg/pr88905.c: New test.
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-23.c b/gcc/testsuite/c-c++-common/gomp/atomic-23.c
new file mode 100644
index 00000000000..969cbf9c084
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-23.c
@@ -0,0 +1,47 @@
+/* PR middle-end/88968 */
+/* { dg-do compile } */
+
+struct __attribute__((packed)) S {
+ unsigned int a : 16;
+ unsigned int b : 1;
+} s;
+
+void
+f1 (void)
+{
+#pragma omp atomic
+ ++s.a;
+}
+
+int
+f2 (void)
+{
+ int r;
+#pragma omp atomic capture
+ {
+ r = s.a;
+ s.a = 0;
+ }
+ return r;
+}
+
+int
+f3 (void)
+{
+ int r;
+#pragma omp atomic capture
+ {
+ r = s.a;
+ s.a = s.a + 32;
+ }
+ return r;
+}
+
+int
+f4 (void)
+{
+ int r;
+#pragma omp atomic capture
+ r = s.a = s.a + 32;
+ return r;
+}