https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108016
--- Comment #3 from Jeffrey A. Law <law at gcc dot gnu.org> --- So just a couple thoughts. If we look at the .expand dump we have: (insn 23 22 24 6 (set (mem/c:QI (plus:DI (reg/f:DI 129 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [1 MEM <unsigned char> [(struct pair *)&D.19566 + 4B]+0 S1 A32]) (reg:QI 146 [ _2 ])) -1 (nil)) [ ... ] (insn 25 24 26 6 (set (reg:DI 151) (zero_extend:DI (mem/c:SI (plus:DI (reg/f:DI 129 virtual-stack-vars) (const_int -8 [0xfffffffffffffff8])) [1 D.19566+0 S4 A64]))) "j.C":3:49 discrim 4 -1 (nil)) Which may be an indication we have something marked as TREE_ADDRESSABLE. But it's often hard to recover better behavior if we generate code like this from the start. Ah, yes. If we look at the .optimized dump: _9 = .ADD_OVERFLOW (a_3(D), b_4(D)); _1 = REALPART_EXPR <_9>; _10 = IMAGPART_EXPR <_9>; _2 = _10 != 0; _8 = VIEW_CONVERT_EXPR<unsigned char>(_2); D.19566.first = _1; MEM <unsigned char> [(struct pair *)&D.19566 + 4B] = _8; return D.19566; So I'd first look at why we created an explicit store through memory rather than simple x.y assignment like we see for D.19566.first.