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.