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.

Reply via email to