http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377

--- Comment #9 from davidxl at google dot com ---
(In reply to Richard Biener from comment #5)
> Confirmed with the C++ FE, works with the C FE.  Does not warn on trunk (for
> no good reason I think, the reason seems to be presence of loop structure
> and thus some extra BBs).
> 
> Difference:
> 
> trunk:
> 
> [WORKLIST]: add to initial list: out_2 = PHI <out_8(D)(2), out_1(8)>
> [CHECK]: examining phi: out_2 = PHI <out_8(D)(2), out_1(8)>
> 
> Use in stmt out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> is guarded by :
> if (pop_first_bucket.2_10 != 0)
> 
> [CHECK] Found def edge 0 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> 
> [CHECK] Found def edge 1 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> Operand defs of phi out_2 = PHI <out_8(D)(2), out_1(8)>
> is guarded by :
> if (out_12 != 0)
> [CHECK]: Found unguarded use: out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> [WORKLIST]: Update worklist with phi: out_1 = PHI <out_12(4), out_12(5),
> out_2(3)>
> [CHECK]: examining phi: out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> 
> Use in stmt out_2 = PHI <out_8(D)(2), out_1(8)>
> is guarded by :
>  (.NOT.) if (iftmp.1_3 != 0)
> 
> [CHECK] Found def edge 0 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> 
> [CHECK] Found def edge 1 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> Operand defs of phi out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> is guarded by :
> if (pop_first_bucket.2_10 != 0)
> (.AND.)
> if (out_12 != 0)
> (.OR.)
> if (pop_first_bucket.2_10 != 0)
> (.AND.)
>  (.NOT.) if (out_12 != 0)
> 
> Normalized to
> Operand defs of phi out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> is guarded by :
> if (pop_first_bucket.2_10 != 0)
> ...
> 
> vs. 4.8 branch:
> 
> [WORKLIST]: add to initial list: out_2 = PHI <out_8(D)(2), out_1(6)>
> [CHECK]: examining phi: out_2 = PHI <out_8(D)(2), out_1(6)>
> 
> Use in stmt out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> is guarded by :
> if (pop_first_bucket.2_10 != 0)
> 
> [CHECK] Found def edge 0 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> 
> [CHECK] Found def edge 1 in out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> Operand defs of phi out_2 = PHI <out_8(D)(2), out_1(6)>
> is guarded by :
> if (out_12 != 0)
> [CHECK]: Found unguarded use: out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> [WORKLIST]: Update worklist with phi: out_1 = PHI <out_12(4), out_12(5),
> out_2(3)>
> [CHECK]: examining phi: out_1 = PHI <out_12(4), out_12(5), out_2(3)>
> [CHECK]: Found unguarded use: out_2 = PHI <out_8(D)(2), out_1(6)>
> [CHECK]: Found unguarded use: _4 = PHI <out_1(6), 0(7)>
> [WORKLIST]: Update worklist with phi: _4 = PHI <out_1(6), 0(7)>
> [CHECK]: examining phi: _4 = PHI <out_1(6), 0(7)>
> [CHECK]: Found unguarded use: return _4;
> 
> The IL difference is that we have
> 
>   <bb 6>:
>   # out_1 = PHI <out_12(4), out_12(5), out_2(3)>
>   # iftmp.1_3 = PHI <1(4), 0(5), 0(3)>
>   if (iftmp.1_3 != 0)
>     goto <bb 7>;
>   else
>     goto <bb 8>;
> 
>   <bb 7>:
>   out_13 = out_1;
>   goto <bb 10>;
> ...
>   <bb 10>:
>   # _4 = PHI <out_13(7), 0(9)>
>   return _4;
> 
> which doesn't warn vs.
> 
>   <bb 6>:
>   # out_1 = PHI <out_12(4), out_12(5), out_2(3)>
>   # iftmp.1_3 = PHI <1(4), 0(5), 0(3)>
>   if (iftmp.1_3 != 0)
>     goto <bb 8>;
>   else
>     goto <bb 7>;
> ...
>   <bb 8>:
>   # _4 = PHI <out_1(6), 0(7)>
>   return _4;
> 
> which does.  The issue seems to be that the analysis doesn't consider
> the PHI uses in
> 
>   if (iftmp.1_3 != 0)
>     goto <bb 8>;
>   else
>     goto <bb 7>;
> 
>   <bb 7>:
>   # out_2 = PHI <out_8(D)(2), out_1(6)>
> 
> guarded by anything (the out_1 use is guarded by iftmp.1_3 == 0).
> 
> David - the code does
> 
>       if (gimple_code (use_stmt) == GIMPLE_PHI)
>         use_bb = gimple_phi_arg_edge (use_stmt,
>                                       PHI_ARG_INDEX_FROM_USE (use_p))->src;
>       else
>         use_bb = gimple_bb (use_stmt);
> 
>       if (is_use_properly_guarded (use_stmt,
>                                    use_bb,
> ...
> 
> so it chooses the source block (as approximation?).
> 
> Splitting all edges results in us no longer warning here and:
> 
> Use in stmt out_2 = PHI <out_8(D)(15), out_1(16)>
> is guarded by :
>  (.NOT.) if (iftmp.1_3 != 0)
> 
> Can you see to fix that please?  Thanks.


Your analysis is correct -- the use is indeed guarded. I forgot why I chose to
use the phi arg's source BB. Will take a look.

David

Reply via email to