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 tree-optimization/68548] bogus "may be used uninitialized" (predicate analysis)


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68548

Jeffrey A. Law <law at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at redhat dot com

--- Comment #2 from Jeffrey A. Law <law at redhat dot com> ---
True that tree-ssa-uninit.c is now powerful enough to grok this case.

But my first preference for any kind of Wuninitialized false positive is to
first think of it as a missed optimization.  Fix the missed optimization and
the false positive goes away for free.

In this particular case there's a couple potential approaches.

;;   basic block 2, loop depth 0, count 0, freq 10000, maybe hot
;;    prev block 0, next block 3, flags: (NEW, REACHABLE, VISITED)
;;    pred:       ENTRY [100.0%]  (FALLTHRU,EXECUTABLE)
  _1 = writemask_5(D) & 1;
  if (_1 != 0)
    goto <bb 4>;
  else
    goto <bb 3>;
;;    succ:       4 [50.0%]  (TRUE_VALUE,EXECUTABLE)
;;                3 [50.0%]  (FALSE_VALUE,EXECUTABLE)

;;   basic block 3, loop depth 0, count 0, freq 5000, maybe hot
;;    prev block 2, next block 4, flags: (NEW, VISITED)
;;    pred:       2 [50.0%]  (FALSE_VALUE,EXECUTABLE)
;;    succ:       4 [100.0%]  (FALLTHRU,EXECUTABLE)

;;   basic block 4, loop depth 0, count 0, freq 10000, maybe hot
;;    prev block 3, next block 5, flags: (NEW, REACHABLE, VISITED)
;;    pred:       3 [100.0%]  (FALLTHRU,EXECUTABLE)
;;                2 [50.0%]  (TRUE_VALUE,EXECUTABLE)
  # data0_3 = PHI <data0_6(D)(3), data_7(D)(2)>
  _2 = ~writemask_5(D);
  remaining_8 = _2 & 1;
  if (remaining_8 == 0)
    goto <bb 5>;
  else
    goto <bb 6>;

One would be to realize that remaining_8 can be expressed in terms of _1.  If
that's done we expose the redundant test and we end up with the only path to
bar() being the one where data0 is initialized.  This can be modeled in DOM and
is about ~20 lines of code.  Not sure how often it'd trigger in the real world.

Another would be to utilize bitwise inference in jump threading in conjunction
with the ASSERT_EXPRs from VRP.  That essentially allows us to construct jump
threads 2->3->4->6 and 2->4->5 which result in the only path to bar() being one
were data0 is initialized.  This is probably more effective, but requires
extending the VRP related jump threading bits whereas I'd rather be relying
upon those less.  But it might be the most tractable for gcc-7.

A third approach would be to extend the backward jump threader to walk through
some binary and unary ops.  I've got some prototype code to do that, but it's
not gcc-7 material.

A fourth approach would be to take the bitwise inference stuff and do it in the
DOM threader instead (which will likely last longer than the VRP threader).  My
worry in this case is that we won't have the ASSERT_EXPRs or range information
on the appropriate edges that would allow us to identify the jump threads.

A fifth approach would be to extend tree-ssa-uninit.c.  But I'd really prefer
to explore opportunities to remove the useless test and unexecutable paths
through the CFG first.

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