https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115256
Hongyu Wang <hongyuw at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hongyuw at gcc dot gnu.org --- Comment #4 from Hongyu Wang <hongyuw at gcc dot gnu.org> --- Part of the dump for create_preheaders before DSE ------ <bb 6> [local count: 29277718]: # .MEM_153 = PHI <.MEM_161(4), .MEM_161(3)> # _15 = PHI <_17(4), 0(3)> # _120 = PHI <_19(4), 0(3)> if (_120 == 0) goto <bb 10>; [45.64%] else goto <bb 7>; [54.36%] <bb 7> [local count: 27536775]: # _66 = PHI <_15(6), _17(5)> # .MEM_125 = PHI <.MEM_153(6), .MEM_164(5)> _87 = (long unsigned int) _66; _88 = _87 * 4; _89 = _88 + 8; _110 = _89; # .MEM_167 = VDEF <.MEM_125> newmem_111 = malloc (_110); if (newmem_111 == 0B) goto <bb 8>; [0.04%] else goto <bb 9>; [99.96%] <bb 8> [local count: 11015]: # .MEM_168 = VDEF <.MEM_167> xmalloc_failed (_110); <bb 9> [local count: 27536775]: # .MEM_154 = PHI <.MEM_167(7), .MEM_168(8)> # .MEM_170 = VDEF <.MEM_154> MEM[(struct vec_prefix *)newmem_111].alloc = _66; # .MEM_171 = VDEF <.MEM_170> MEM[(struct vec_prefix *)newmem_111].num = 0; <bb 10> [local count: 39298950]: # _91 = PHI <0B(6), newmem_111(9)> # .MEM_152 = PHI <.MEM_153(6), .MEM_171(9)> # .MEM_174 = VDEF <.MEM_152> li.to_visit = _91; # VUSE <.MEM_174> _61 = cfun; # VUSE <.MEM_174> _62 = _61->x_current_loops; # VUSE <.MEM_174> _63 = _62->tree_root; <bb 11> [local count: 77159561]: # aloop_80 = PHI <_63(10), _108(26)> # .MEM_147 = PHI <.MEM_174(10), .MEM_90(26)> <bb 12> [local count: 701450557]: # aloop_64 = PHI <aloop_80(11), _71(16)> # .MEM_148 = PHI <.MEM_147(11), .MEM_149(16)> # VUSE <.MEM_148> _65 = aloop_64->num; if (_65 > 0) goto <bb 13>; [50.00%] else goto <bb 16>; [50.00%] <bb 13> [local count: 350725279]: if (_91 != 0B) goto <bb 14>; [70.00%] else goto <bb 15>; [30.00%] <bb 14> [local count: 245507696]: _67 = &MEM[(struct VEC_int_heap *)_91].base; <bb 15> [local count: 350725279]: # _68 = PHI <0B(13), _67(14)> # VUSE <.MEM_148> _69 = _68->num; _70 = _69 + 1; # .MEM_179 = VDEF <.MEM_148> _68->num = _70; # .MEM_180 = VDEF <.MEM_179> MEM <struct VEC_int_base> [(int *)_68].vec[_69] = _65; ------ The problem is, for the malloced stores, MEM[(struct vec_prefix *)newmem_111].alloc = _66; MEM[(struct vec_prefix *)newmem_111].num = 0; These 2 stmts are marked as dead store and eliminated, but actually there was a use chain ------ <bb 10> [local count: 39298950]: # _91 = PHI <0B(6), newmem_111(9)> # .MEM_152 = PHI <.MEM_153(6), .MEM_171(9)> # .MEM_174 = VDEF <.MEM_152> li.to_visit = _91; ... <bb 13> [local count: 350725279]: if (_91 != 0B) goto <bb 14>; [70.00%] else goto <bb 15>; [30.00%] <bb 14> [local count: 245507696]: _67 = &MEM[(struct VEC_int_heap *)_91].base; <bb 15> [local count: 350725279]: # _68 = PHI <0B(13), _67(14)> # VUSE <.MEM_148> _69 = _68->num; _70 = _69 + 1; # .MEM_179 = VDEF <.MEM_148> _68->num = _70; # .MEM_180 = VDEF <.MEM_179> MEM <struct VEC_int_base> [(int *)_68].vec[_69] = _65; ------ The source code has an implicit type casting li->to_visit = (VEC_int_heap_alloc(number_of_loops () )); ... (VEC_int_base_quick_push(((li->to_visit) ? &(li->to_visit)->base : 0),aloop->num )); Who casts the malloced pointer newmem_111 to (struct VEC_int_heap *), then cast again to (int *) in VEC_int_base_quick_push. But the store to newmem_111 was casted to (struct vec_prefix *) in VEC_int_heap_alloc. As such casting violates aliasing rule, -fno-strict-aliasing may be needed, otherwise TBAA cannot identify the ref and use actually aliases. The patch r15-571 allows analysis on multiple vdefs in dse_classify_store, and prior to the patch it directly returns DSE_STORE_MAYBE_PARTIAL_DEAD for multiple vdefs for this case, so the issue was just exposed by the patch.