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.

Reply via email to