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.