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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at redhat dot com
   Target Milestone|8.4                         |10.0

--- Comment #2 from Jeffrey A. Law <law at redhat dot com> ---
My tester had tripped over this a while back.  I'd been meaning to dig into it
since it was clearly a false positive.

With the reduced testcase (I'll attach it shortly) the key path is blocks
2->9->4->6 which have the following contents:


;;   basic block 2, loop depth 0
;;    pred:       ENTRY
  _1 = vptr_14(D) == 0;
  _2 = ownvptr_15(D) != 0;
  _3 = _1 | _2;
  if (_3 != 0)
    goto <bb 9>; [67.00%]
  else
    goto <bb 3>; [33.00%]

;;   basic block 9, loop depth 0
;;    pred:       2
  if (vptr_14(D) != 0)
    goto <bb 4>; [33.33%]
  else
    goto <bb 8>; [66.67%]


;;   basic block 4, loop depth 0
;;    pred:       9
  if (ownvptr_15(D) != 0)
    goto <bb 5>; [100.00%]
  else
    goto <bb 6>; [0.00%]

;;   basic block 6, loop depth 0
;;    pred:       4
;;                3
  # definition_36 = PHI <0(4), definition_17(3)>
  # vstring_38 = PHI <0B(4), vstring_19(3)>
  _5 = strlen (vstring_38);
  _6 = _5 + 3;
  vtable_21 = xmalloc (_6);
  sprintf (vtable_21, "~%%%s", vstring_38);
  if (definition_36 != 0)
    goto <bb 7>; [97.40%]
  else
    goto <bb 8>; [2.60%]


We can obviously see the path 2->4->9->6 is not feasible, but DOM isn't going
to be able to make that determination.  ie when we traverse 2->4 it knows that
_3 is true, but it doesn't know if that's because _1 is true or because _2 is
true and it's incapable of tracking the relationship between them.

DOM is going to thread the edge 4->6 to target bb8.  This will result in the
path morphing a bit into 2->8->4->9.  The key blocks look like this after DOM
has completed:

;;   basic block 2, loop depth 0
;;    pred:       ENTRY
  _1 = vptr_14(D) == 0;
  _2 = ownvptr_15(D) != 0;
  _3 = _1 | _2;
  if (_3 != 0)
    goto <bb 8>; [67.00%]
  else
    goto <bb 3>; [33.00%]


;;   basic block 8, loop depth 0
;;    pred:       2
  if (vptr_14(D) != 0)
    goto <bb 4>; [33.33%]
  else
    goto <bb 7>; [66.67%]

;;   basic block 4, loop depth 0
;;    pred:       8
  if (_2 != 0)
    goto <bb 5>; [100.00%]
  else
    goto <bb 9>; [0.00%]

;;   basic block 9, loop depth 0
;;    pred:       4
  # definition_37 = PHI <0(4)>
  # vstring_11 = PHI <0B(4)>
  _33 = strlen (vstring_11);
  _35 = _33 + 3;
  vtable_31 = xmalloc (_35);
  sprintf (vtable_31, "~%%%s", vstring_11);
  goto <bb 7>; [100.00%]

bb9 is a clone of what was previously bb6, but it's isolated so that we
threading could change it without affecting the non-threaded path.

But the key issue remains, DOM can't track the relationship between vptr and
ownvptr.

This is actually the kind of thing I'd like to be able to use the predicate
analysis found in tree-ssa-uninit.c to fix.

Anyway, there's very very little chance this will be fixed for gcc-9. 
Deferring out.

Reply via email to