https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110538
--- Comment #3 from Jeffrey A. Law <law at gcc dot gnu.org> --- Thread references removed edge: Cancelling jump thread: (9, 10) incoming edge; (10, 8) joiner (8, 6) normal; Thread references removed edge: Cancelling jump thread: (2, 3) incoming edge; (3, 9) joiner (9, 10) nocopy (10, 8) normal; Thread references removed edge: Cancelling jump thread: (2, 3) incoming edge; (3, 10) joiner (10, 8) normal; Thread references removed edge: Cancelling jump thread: (3, 10) incoming edge; (10, 8) normal; [ ... ] Merging blocks 10 and 8 Removing basic block 11 ;; basic block 11, loop depth 1 ;; pred: goto <bb 3>; [100.00%] ;; succ: 3 So one of the edges in the jump threading path gets removed. As a result the threader throws the path away. At least that's my best guess. We could possibly defer block merging until after threading. No idea how hard that might be. The sequencing is a bit painful, but IIRC the key is that we must remove unreachables in the CFG before threading (due to how unreachables interact with the dominator tree updates).