https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102895
--- Comment #2 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- (In reply to Richard Biener from comment #1) > There's identical IL before the vrp2 pass (the one after strlen) but on the > GCC 11 branch vrp2 eliminates the call to foo while on trunk it does not. > > On the branch VRP registers > > Registering jump thread: (2, 3) incoming edge; (3, 4) normal; > > which elides the call but vrp-thread2 does not do this: > > Registering value_relation (_5 > a.4_4) (bb5) at _5 = a.4_4 + 1; > Registering value_relation (_19 > a.4_13) (bb4) at _19 = a.4_13 + 1; > [4] Registering jump thread: (2, 3) incoming edge; (3, 4) normal; > Failure in thread_through_loop_header: Cancelling jump thread: (2, 3) > incoming edge; (3, 4) normal; > > on the branch this threading destroys the loop structure It seems there were other threads in play before the loop restriction changes went in. In the branch we have: $ gcc a.c -O2 -fdump-tree-all-details -c abulafia:~/bld/t/gcc$ grep thread a.c.* a.c.124t.dom2: Registering jump thread: (10, 5) incoming edge; (5, 12) normal; a.c.124t.dom2: Registering jump thread: (9, 3) incoming edge; (3, 4) normal; a.c.189t.dom3: Registering jump thread: (2, 3) incoming edge; (3, 4) normal; a.c.192t.vrp2: Registering jump thread: (2, 3) incoming edge; (3, 4) normal; DOM2 was getting 2 threads, but in mainline we have: ./cc1 a.c -O2 -fdump-tree-all-details -quiet abulafia:~/bld/t/gcc$ grep thread a.c.* a.c.128t.dom2:Threading through latch before loop opts would create non-empty latch: Cancelling jump thread: (10, 5) incoming edge; (5, 12) normal; a.c.128t.dom2:Path rotates loop: Cancelling jump thread: (9, 3) incoming edge; (3, 4) normal; a.c.193t.dom3: [3] Registering jump thread: (2, 3) incoming edge; (3, 4) normal; a.c.193t.dom3:Failure in thread_through_loop_header: Cancelling jump thread: (2, 3) incoming edge; (3, 4) normal; a.c.197t.vrp-thread2: [4] Registering jump thread: (2, 3) incoming edge; (3, 4) normal; a.c.197t.vrp-thread2:Failure in thread_through_loop_header: Cancelling jump thread: (2, 3) incoming edge; (3, 4) normal; Those DOM2 threads were cancelled because of the loop restrictions we put in. Since jump threads in one pass open the possibilities of further jump threads by other passes, it could be that the missing DOM2 threads are causing VRP2 to miss out. However, vrp-thread2 *does* find and register the path. It's the block copier that is complaining: a.c.197t.vrp-thread2: [4] Registering jump thread: (2, 3) incoming edge; (3, 4) normal; a.c.197t.vrp-thread2:Failure in thread_through_loop_header: Cancelling jump thread: (2, 3) incoming edge; (3, 4) normal; Note that these "Failure in thread_through_loop_header" messages are new debugging aids in this release, but the cancel_thread was present nevertheless. It was just silent. I would guess it's either the missing DOM threads that has cascading effects, or something in the block copier (fwd_jt_path_registry::). FWIW, there have been no changes in the block copier in this release.