diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-02-07 14:37:26 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2019-02-07 14:37:26 +0000 |
commit | a3b7eab5777578ee2c99a1ac665999b48fc53d17 (patch) | |
tree | b652b1297b02ef284c6f9d5b8f02bf8ceed50a91 | |
parent | c1f69134d620b81fb42721eb27a0464980632517 (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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-omp.c | 7 | ||||
-rw-r--r-- | gcc/gimplify.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/atomic-23.c | 47 |
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; +} |