https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89546
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- When get_tail is esra optimized the old way, main is: int n1$tail$head$payload; struct type D.9885; struct tuple D.9880; struct type D.9879; struct type D.9878; struct type D.9875; <bb 2> [local count: 1073741825]: MEM[(struct tuple *)&D.9885] = 3; MEM[(struct tuple *)&D.9885 + 4B] = 2; MEM[(struct tuple *)&D.9885 + 8B] = 4; D.9875.tail = D.9885; D.9885 ={v} {CLOBBER}; D.9878 = MEM[(const struct tuple &)&D.9875 + 8]; D.9879.tail = D.9878; D.9878 ={v} {CLOBBER}; D.9880.head = MEM[(const struct type_n &)&D.9879 + 4]; n1$tail$head$payload_32 = MEM[(struct tuple *)&D.9880]; D.9880 ={v} {CLOBBER}; D.9879 ={v} {CLOBBER}; D.9875 ={v} {CLOBBER}; if (n1$tail$head$payload_32 != 2) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1072883002]: return 0; and the testcase works. If it is esra optimized the new way, I get: int n1$tail$head$payload; struct type n1; <bb 2> [local count: 1073741825]: MEM[(struct &)&n1] ={v} {CLOBBER}; n1$tail$head$payload_90 = MEM[(struct tuple *)&n1 + 4B]; if (n1$tail$head$payload_90 != 2) goto <bb 3>; [0.00%] else goto <bb 4>; [99.96%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1072883002]: n1 ={v} {CLOBBER}; return 0; which is undefined, so unless the testcase is UB (but passes e.g. on x86_64-linux too, valgrind is quiet on it, -fsanitize=address,undefined too), something went wrong during GIMPLE optimizations.