https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90806
--- Comment #15 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Eric Botcazou from comment #13) > The divergence appears to stem from get_ref_base_and_extent: > > case MEM_REF: > [...] > /* Hand back the decl for MEM[&decl, off]. */ > if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) > { > if (integer_zerop (TREE_OPERAND (exp, 1))) > exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); > else > { > poly_offset_int off = mem_ref_offset (exp); > off <<= LOG2_BITS_PER_UNIT; > off += bit_offset; > poly_int64 off_hwi; > if (off.to_shwi (&off_hwi)) > { > bit_offset = off_hwi; > exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); > } > } > } > > 628 poly_offset_int off = mem_ref_offset (exp); > (gdb) p debug_generic_expr(exp) > MEM[(char *)&ar3 + -9223372036854775808B] > > which yields on the one hand: > > (gdb) p off > $60 = {<poly_int_pod<1, generic_wide_int<fixed_wide_int_storage<128> > >> = { > coeffs = {{<fixed_wide_int_storage<128>> = {val = {-9223372036854775808, > 140737332966384, 140733193388032}, len = 1}, > static is_sign_extended = true}}}, <No data fields>} > > and on the other hand: > > (gdb) p off > $25 = {<poly_int_pod<1, generic_wide_int<fixed_wide_int_storage<128> > >> = { > coeffs = {{<fixed_wide_int_storage<128>> = {val = {-9223372036854775808, > 8097070, -9223372036854775808}, len = 1}, > static is_sign_extended = true}}}, <No data fields>} Note that's identical data (only val[] up to len - 1 is relevant data). > Then > off <<= LOG2_BITS_PER_UNIT; > > yields on the one hand: > > (gdb) p off > $67 = {<poly_int_pod<1, generic_wide_int<fixed_wide_int_storage<128> > >> = { > coeffs = {{<fixed_wide_int_storage<128>> = {val = {0, -4, > 140737488342640}, len = 2}, > static is_sign_extended = true}}}, <No data fields>} > > and on the other hand: > > $36 = {<poly_int_pod<1, generic_wide_int<fixed_wide_int_storage<128> > >> = { > coeffs = {{<fixed_wide_int_storage<128>> = {val = {0, 824633720995, > 140737334083072}, len = 1}, > static is_sign_extended = true}}}, <No data fields>} the first result is a large zero-extended value (len == 2) while the second is simply zero. I suppose we might run into the issue that left-shift of negative values is undefined? Thus the "optimization" to replace the multiplication by BITS_PER_UNIT by a seemingly more cheap left-shift fires back. So, does changing the code to off *= BITS_PER_UNIT; fix the issue? > The latter passes the off.to_shwi test whereas the former does not.