From 95efa2279195e2b86afc986fd6e917c2704575d0 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 10 Jul 2019 13:40:12 +0000 Subject: [PATCH] re PR tree-optimization/91126 (Incorrect constant propagation of BIT_FIELD_REF) 2019-07-10 Richard Biener PR tree-optimization/91126 * tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust native encoding offset for BYTES_BIG_ENDIAN. (vn_reference_lookup_3): Likewise. * gcc.dg/torture/pr91126.c: New testcase. From-SVN: r273355 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr91126.c | 28 ++++++++++++++++++++++++++ gcc/tree-ssa-sccvn.c | 25 +++++++++++++++++++++-- 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr91126.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac390d65ae7..9b32482db5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-07-10 Richard Biener + + PR tree-optimization/91126 + * tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust + native encoding offset for BYTES_BIG_ENDIAN. + (vn_reference_lookup_3): Likewise. + 2019-07-10 Richard Biener * tree-ssa-sccvn.c (vn_reference_lookup_3): Look at valueized diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 840d9c1f251..e531f0a3b97 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-10 Richard Biener + + PR tree-optimization/91126 + * gcc.dg/torture/pr91126.c: New testcase. + 2019-07-10 Richard Biener * gcc.dg/torture/ssa-fre-5.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/torture/pr91126.c b/gcc/testsuite/gcc.dg/torture/pr91126.c new file mode 100644 index 00000000000..8e34815b9a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr91126.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +struct S +{ + __INT32_TYPE__ a : 24; + __INT32_TYPE__ b : 8; +} s; + +int +main() +{ + s.a = 0xfefefe; + s.b = 0xfe; + unsigned char c; + c = ((unsigned char *)&s)[0]; + if (c != 0xfe) + __builtin_abort (); + c = ((unsigned char *)&s)[1]; + if (c != 0xfe) + __builtin_abort (); + c = ((unsigned char *)&s)[2]; + if (c != 0xfe) + __builtin_abort (); + c = ((unsigned char *)&s)[3]; + if (c != 0xfe) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 777cf58e43b..73c77d1df4b 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1832,10 +1832,20 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse, 0, MIN ((HOST_WIDE_INT)sizeof (buffer), pd.size)); else { + unsigned pad = 0; + if (BYTES_BIG_ENDIAN + && is_a (TYPE_MODE (TREE_TYPE (pd.rhs)))) + { + /* On big-endian the padding is at the 'front' so + just skip the initial bytes. */ + fixed_size_mode mode = as_a + (TYPE_MODE (TREE_TYPE (pd.rhs))); + pad = GET_MODE_SIZE (mode) - pd.size; + } len = native_encode_expr (pd.rhs, buffer + MAX (0, pd.offset), sizeof (buffer - MAX (0, pd.offset)), - MAX (0, -pd.offset)); + MAX (0, -pd.offset) + pad); if (len <= 0 || len < (pd.size - MAX (0, -pd.offset))) { @@ -2588,9 +2598,20 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, tree rhs = gimple_assign_rhs1 (def_stmt); if (TREE_CODE (rhs) == SSA_NAME) rhs = SSA_VAL (rhs); + unsigned pad = 0; + if (BYTES_BIG_ENDIAN + && is_a (TYPE_MODE (TREE_TYPE (rhs)))) + { + /* On big-endian the padding is at the 'front' so + just skip the initial bytes. */ + fixed_size_mode mode + = as_a (TYPE_MODE (TREE_TYPE (rhs))); + pad = GET_MODE_SIZE (mode) - size2i / BITS_PER_UNIT; + } len = native_encode_expr (rhs, buffer, sizeof (buffer), - (offseti - offset2i) / BITS_PER_UNIT); + ((offseti - offset2i) / BITS_PER_UNIT + + pad)); if (len > 0 && len * BITS_PER_UNIT >= maxsizei) { tree type = vr->type; -- 2.30.2