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.