https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115991
--- Comment #13 from Sergei Trofimovich <slyfox at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #1)
> BUT BUT ivopts does:
>
> _30 = (unsigned int) &hdr;
> ivtmp.22_24 = -_30;
>
> which does not make sense.
>
> So I think this is a bug in IV_OPTs in the first place.
Can you help me understand what is wrong with this bit? Is it a correctness
issue or an optimization issue?
I think it was picked by this candidate IV:
Candidate 5:
Var befor: ivtmp.20
Var after: ivtmp.20
Incr POS: at end
IV struct:
Type: unsigned int
Base: -(unsigned int) &hdr
Step: 4
Object: (void *) &hdr
Biv: N
Overflowness wrto loop niter: Overflow
It's not pretty, but in the context of calculated offsets it does not look too
broken to me and always gets added to &hdr (or a dereference happens on the
address itself):
<bb 2> [local count: 26541933]:
_30 = (unsigned int) &hdr;
ivtmp.20_29 = -_30;
goto <bb 5>; [100.00%]
<bb 7> [local count: 214748368]:
_20 = &hdr + 16;
<bb 3> [local count: 858993456]:
# _data_26 = PHI <_data_18(8), &hdr(7)>
_25 = (unsigned int) &hdr;
_16 = ivtmp.20_21;
_6 = (unsigned int) _data_26;
_addr_24 = _6 + _16;
_1 = MEM[(u32 *)_data_26];
_2 = (long int) _addr_24;
f_l_u32 (_2, _1);
<bb 5> [local count: 241290301]:
# ivtmp.20_21 = PHI <ivtmp.20_29(2), ivtmp.20_22(4)>
_31 = (unsigned int) &hdr;
offset_5 = ivtmp.20_21 + _31;
_3 = b ();
if (_3 != 0)
goto <bb 7>; [89.00%]
else
goto <bb 6>; [11.00%]
<bb 6> [local count: 26541933]:
# offset_28 = PHI <offset_5(5)>
_4 = (long int) offset_28;
f_l_u32 (_4, 0);
My guess is that on arm64 this candidate does not have as a good cost as other
alternatives and the other one is picked instead.