https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103061
--- Comment #4 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- (In reply to Martin Liška from comment #1) > The following file is miscompiled: > > gfortran -c -o m_MergeSorts.fppized.o -I. -Iinclude -Inetcdf/include -O2 > -march=native -g -std=legacy m_MergeSorts.fppized.f90 > > where first bad debug counter value is: > > -fdbg-cnt=back_threadfull2:6 This has been a godsend. Thanks! I added -fdump-tree-threadfull2-details-threading to see the threader in action. Curiously, it's the same thread over and over, but I do see there various functions with the same IL (rsort, isort, etc): $ grep Registering.jump *full2 [7] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; [14] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; [21] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; [28] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; [36] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; [44] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; I guess it doesn't matter which registered thread we look at, since they're all the same: [7] Registering jump thread: (41, 20) incoming edge; (20, 21) nocopy; The screen full immediately before the above message has the path solver in action: *********** path_range_query ****************** path_range_query: compute_ranges for path: BB 41, BB 20 from bb20: Registering killing_def (path_oracle) lb_75 Registering value_relation (path_oracle) (_134 == lb_75) (bb41) Registering value_relation (_134 > M.10_120) (bb35) at _134 = M.10_120 + 1; Intersecting with existing (_134 > M.10_120) to produce (_134 > M.10_120) ... ... ... The threaded path is 41->20->21 and the conditional in question is at the end of BB20: =========== BB 20 ============ Imports: mstep_49 _71 lb_75 Exports: mstep_49 _71 lb_75 _117 _118 _119 M.10_120 _117 : mstep_49(I) lb_75(I) _118 : mstep_49(I) lb_75(I) _117 _119 : mstep_49(I) lb_75(I) _117 _118 M.10_120 : mstep_49(I) _71(I) lb_75(I) _117 _118 _119 _22 void * [1B, +INF] mstep_49 integer(kind=4) [1, 2147483646] _71 integer(kind=4) [2, +INF] lstep_114 integer(kind=4) [2, +INF] Relational : (_117 > lb_75) Relational : (_117 > mstep_49) Relational : (_119 > _118) Relational : (_119 > mstep_49) Relational : (_118 < _117) <bb 20> [local count: 56063503181]: # lb_75 = PHI <_134(41), 1(18)> _117 = mstep_49 + lb_75; _118 = _117 + -1; _119 = mstep_49 + _118; M.10_120 = MIN_EXPR <_119, _71>; if (lb_75 > M.10_120) goto <bb 21>; [11.00%] else goto <bb 22>; [89.00%] Because of the PHI, lb_75 is known to be _134 coming in from BB41, which the relation oracle registered: from bb20: Registering killing_def (path_oracle) lb_75 Registering value_relation (path_oracle) (_134 == lb_75) (bb41) The relation oracle also noted that _134 > M.10_120: Registering value_relation (_134 > M.10_120) (bb35) at _134 = M.10_120 + 1; So we can conclude that lb_75 > M.10_120 and thread the path. This assumes that _134 = M.10_120 + 1 does not overflow. These are integer(kind=4) types in Fortran. Is this a correct assumption? That is, is signed overflow undefined in overflow? Can we assume _134 > M.10_120? If so, then the threading is correct. If not, we need to fix that relationship :).