https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90806
--- Comment #13 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
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>}
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 latter passes the off.to_shwi test whereas the former does not.