https://gcc.gnu.org/bugzilla/show_bug.cgi?id=23970
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Unswitching does this as a separate transform now, the "hoist guards" transform. It's even done completely separate now: unsigned int tree_ssa_unswitch_loops (function *fun) { bool changed_unswitch = false; bool changed_hoist = false; auto_edge_flag ignored_edge_flag (fun); ranger = enable_ranger (fun); /* Go through all loops starting from innermost, hoisting guards. */ for (auto loop : loops_list (fun, LI_FROM_INNERMOST)) { if (loop->inner) changed_hoist |= tree_unswitch_outer_loop (loop); } /* Go through innermost loops, unswitching on invariant predicates within those. */ ... the question is how we'd call the "cheap" unswitching transform. I guess simply testing optimize > 2 || opt_enabled or so isn't quite desirable. Note it's possible to separate this into an entirely separate pass as well.