This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/58377] spurious "may be unused" warning with -Og


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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
      Known to work|                            |4.9.0
            Version|unknown                     |4.8.1
   Last reconfirmed|                            |2013-09-10
          Component|middle-end                  |c++
                 CC|                            |xinliangli at gmail dot com
     Ever confirmed|0                           |1
            Summary|spurious "may be used       |spurious "may be unused"
                   |uninitialized" warning with |warning with -Og
                   |-Og                         |

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]