summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-07-10 13:40:12 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-07-10 13:40:12 +0000
commit95efa2279195e2b86afc986fd6e917c2704575d0 (patch)
tree105e4c3b8bf6849304983cdf0bfab3986c711b34 /gcc/tree-ssa-sccvn.c
parent8389386c6d55d57afc3ae01f71546ac4468f7926 (diff)
re PR tree-optimization/91126 (Incorrect constant propagation of BIT_FIELD_REF)
2019-07-10 Richard Biener <rguenther@suse.de> 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
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c25
1 files changed, 23 insertions, 2 deletions
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 <scalar_mode> (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 <fixed_size_mode>
+ (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 <scalar_mode> (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 <fixed_size_mode> (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;