This backport contains 1 patch from gcc main stream tree. The commit id of these patchs list as following in the order of time. c69325a5db450dbac198f76f1162734af05a1061 0001-sccvn-Fix-up-push_partial_def-little-endian-bitfield.patch diff -urpN a/gcc/testsuite/gcc.c-torture/execute/pr97764.c b/gcc/testsuite/gcc.c-torture/execute/pr97764.c --- a/gcc/testsuite/gcc.c-torture/execute/pr97764.c 1969-12-31 19:00:00.000000000 -0500 +++ b/gcc/testsuite/gcc.c-torture/execute/pr97764.c 2020-12-07 03:42:13.404000000 -0500 @@ -0,0 +1,14 @@ +/* PR tree-optimization/97764 */ +/* { dg-require-effective-target int32plus } */ + +struct S { int b : 3; int c : 28; int d : 1; }; + +int +main () +{ + struct S e = {}; + e.c = -1; + if (e.d) + __builtin_abort (); + return 0; +} diff -urpN a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c --- a/gcc/tree-ssa-sccvn.c 2020-12-07 03:43:37.792000000 -0500 +++ b/gcc/tree-ssa-sccvn.c 2020-12-07 03:42:13.404000000 -0500 @@ -2013,12 +2013,12 @@ vn_walk_cb_data::push_partial_def (const } else { - size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT); if (pd.offset >= 0) { /* LSB of this_buffer[0] byte should be at pd.offset bits in buffer. */ unsigned int msk; + size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT); amnt = pd.offset % BITS_PER_UNIT; if (amnt) shift_bytes_in_array_left (this_buffer, len + 1, amnt); @@ -2046,6 +2046,9 @@ vn_walk_cb_data::push_partial_def (const { amnt = (unsigned HOST_WIDE_INT) pd.offset % BITS_PER_UNIT; if (amnt) + size -= BITS_PER_UNIT - amnt; + size = MIN (size, (HOST_WIDE_INT) needed_len * BITS_PER_UNIT); + if (amnt) shift_bytes_in_array_left (this_buffer, len + 1, amnt); } memcpy (p, this_buffer + (amnt != 0), size / BITS_PER_UNIT);