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

--- Comment #4 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
Here are some debugging tips for when I'm not around ;-).

When the jump threader is suspected, I find it useful to do some bisecting to
find the actual jump thread that is causing the problem.  Note that sometimes
it's a combination of threaded paths, but most of the time it's just one.

First I make sure the problem goes away without jump threading:

abulafia:~/bld/t/gcc$ ./xgcc -B./ a.c -O2 -fno-thread-jumps
abulafia:~/bld/t/gcc$ ./a.out
abulafia:~/bld/t/gcc$ 

And then I start playing -fdbg-cnt games, which ultimately led me to:

abulafia:~/bld/t/gcc$ ./xgcc -B./ a.c -O2 -fdbg-cnt=registered_jump_thread:4-4
-fdump-tree-all-details-threading
***dbgcnt: lower limit 4 reached for registered_jump_thread.***
***dbgcnt: upper limit 4 reached for registered_jump_thread.***
abulafia:~/bld/t/gcc$ ./a.out
Aborted (core dumped)

The 4th jump threaded path reproduces the problem.

I then look at the dump file with the dbgcnt message (*.vrp-thread1):

***dbgcnt: lower limit 4 reached for registered_jump_thread.***
***dbgcnt: upper limit 4 reached for registered_jump_thread.***
  [4] Registering jump thread: (3, 5) incoming edge;  (5, 7) joiner (7, 8)
normal (8, 9) nocopy; 

The block immediately preceding this message is the path solver in action:

*********** path_range_query ******************
 Registering value_relation (path_oracle) (_4 < a.4_14) (bb3)
 Registering value_relation (path_oracle) (_3 == iftmp.3_15) (bb3)
 Registering value_relation (path_oracle) (_5 == iftmp.6_13) (bb3)

path_range_query: compute_ranges for path: BB 3, BB 5, BB 7
range_defined_in_block (BB5) for iftmp.3_15 is char [0, 0]
range_defined_in_block (BB5) for _5 is unsigned char [0, 0]
range_defined_in_block (BB5) for iftmp.3_15 is char [0, 0]
range_defined_in_block (BB7) for iftmp.6_13 is unsigned char [0, 0]

Path is (length=3):

=========== BB 3 ============
Imports: b.1_2  a.4_14  
Exports: b.1_2  _3  _4  a.4_14  
         _3 : b.1_2(I)  
         _4 : b.1_2(I)  _3  
    <bb 3> [local count: 1073741824]:
  L:
    d.0_1 = d;
    b.1_2 = b;
    _3 = (char) b.1_2;
    _4 = (int) _3;
    a.4_14 = a;
    if (_4 >= a.4_14)
      goto <bb 4>; [50.00%]
    else
      goto <bb 5>; [50.00%]

_4 : int [-128, 127]
3->4  (T) _4 :  int [-128, 127]
3->4  (T) a.4_14 :      int [-INF, 127]
3->5  (F) _4 :  int [-128, 127]
3->5  (F) a.4_14 :      int [-127, +INF]

=========== BB 5 ============
Imports: d.0_1  
Exports: d.0_1  
d.0_1   int VARYING
b.1_2   int VARYING
    <bb 5> [local count: 1073741824]:
    # iftmp.3_15 = PHI <_3(3), 0(4)>
    _5 = (unsigned char) iftmp.3_15;
    if (d.0_1 == 0)
      goto <bb 6>; [50.00%]
    else
      goto <bb 7>; [50.00%]

5->6  (T) d.0_1 :       int [0, 0]
5->7  (F) d.0_1 :       int [-INF, -1][1, +INF]
etc
etc
etc

The solver decided that iftmp.3_15 is [0, 0] along the path:

  range_defined_in_block (BB5) for iftmp.3_15 is char [0, 0]

This makes absolutely no sense.  The iftmp.3_15 SSA is _3 on the 3->5 edge, and
we have no knowledge of _3 in BB3.  Well, unless we had some global range for
_3 from a previous *vrp pass, but that's not the case here.

The problem here is that since we didn't have a range so far for _3, we decided
to ask for the ranger's range on entry to the path.  This is incorrect, because
_3 is not live on entry.  Assuming it is had us calling range_on_edge on each
incoming edge to BB3, which ranger was happy to return UNDEFINED for.  This was
an oversight.  We should never call range_on_path_entry for things defined in
the path.  The other call to range_on_path_entry had an appropriate gate.  The
one when calculating PHIs did not.

Reply via email to