http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60429
--- Comment #18 from Richard Biener <rguenth at gcc dot gnu.org> --- Seems to be a PTA issue: InsertionSort_pETEchase.29_82, points-to vars: { } InsertionSort_pETEchase.29_86, points-to non-local, points-to escaped, points-to vars: { } p1_155, points-to NULL, points-to vars: { } <bb 30>: InsertionSort_pETEchase.29_82->next = p1_84; p1_155->next = InsertionSort_pETEchase.28_85; InsertionSort_pETEchase.29_86 = InsertionSort_pETEchase.28_85->back; InsertionSort_pETEchase.29_86->next = p1_155; p1_155->back = &InsertionSort_pETEchaseBackTMP; taking _155 as example # p1_155 = PHI <_35(57), p1_58(60)> _35, points-to NULL, points-to vars: { } p1_58, points-to vars: { } _35 = MEM[(struct _EdgeTableEntry * *)&AET + 16B]; # p1_58 = PHI <p1_84(59), p1_84(30), p1_87(34)> p1_84 = p1_155->next; p1_87 = p1_155->next; so it's a cycle seeded only by MEM[(struct _EdgeTableEntry * *)&AET + 16B]; _35 = { NULL } same as AET.128+64 _35 = AET.128+64 # p1_150 = PHI <&AET(47), p1_151(49)> # p1_151 = PHI <p1_19(47), p1_45(49)> p1_45 = p1_151->next; fn3_tmp = p1_45; p1_151->next = p1_47; p1_151->back = p1_150; p1_150 = &AET.0+96 *p1_150 + 128 = p1_151 Note that valgrind shows loads of errors (with the reduced testcase at least) that show invalid reads and writes even at -O0. So we may just optimistically optimize based on that undefined behavior. At least I can't see anything wrong with what PTA derives ...