https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69109
--- Comment #2 from vries at gcc dot gnu.org --- -funswitch-loops introduces degenerate phis in a loop latch (bb 9): ... ;; basic block 9, loop depth 1, count 0, freq 4900, maybe hot ;; prev block 8, next block 10, flags: (NEW, REACHABLE) ;; pred: 10 [99.0%] (TRUE_VALUE,EXECUTABLE) # j_1 = PHI <j_11(10)> # .MEM_2 = PHI <.MEM_10(10)> ;; succ: 10 [100.0%] (FALLTHRU,EXECUTABLE) ;; basic block 10, loop depth 1, count 0, freq 4950, maybe hot ;; prev block 9, next block 11, flags: (NEW, REACHABLE) ;; pred: 9 [100.0%] (FALLTHRU,EXECUTABLE) ;; 3 [100.0%] (FALLTHRU) # RANGE [0, 256] NONZERO 511 # j_17 = PHI <j_1(9), 0(3)> # .MEM_18 = PHI <.MEM_2(9), .MEM_4(D)(3)> # RANGE [0, 255] NONZERO 255 _7 = (sizetype) j_17; # PT = nonlocal _9 = fastmap_8(D) + _7; # .MEM_10 = VDEF <.MEM_18> *_9 = 1; # RANGE [1, 256] NONZERO 511 j_11 = j_17 + 1; if (j_11 != 256) goto <bb 9>; else goto <bb 11>; ;; succ: 9 [99.0%] (TRUE_VALUE,EXECUTABLE) ;; 11 [1.0%] (FALSE_VALUE,EXECUTABLE) ... The degenerate PHI is introduced by cleanup_tree_cfg triggered by TODO_cleanup_cfg. The j_1 PHI is removed by pass_copy_prop before parloops, but the .MEM_2 PHI not. Adding pass_phi_only_cprop after pass_tree_unswitch gets rid of both (even if it is only verbose about getting rid of the j_1 PHI). Anyway, transform_to_exit_first_loop_alt asserts because it doesn't know how to handle a phi in the latch.