https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69564
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> --- Looks like since GCC 5 we wrap all loops in a while (1). Eventually this just confuses GCCs static prediction machinery but who knows. Old (not the problematic function!): { int i; int j; <<cleanup_point <<< Unknown tree: expr_stmt (void) (i = 0) >>>>>; goto <D.3610>; <D.3609>:; <<cleanup_point <<< Unknown tree: expr_stmt (void) (j = 0) >>>>>; goto <D.3608>; <D.3607>:; <<cleanup_point <<< Unknown tree: expr_stmt (void) (*(*(lu + (sizetype) ((long unsigned int) i * 8)) + (sizetype) ((long unsigned int) j * 8)) = *(*(A + (sizetype) ((long unsigned int) i * 8)) + (sizetype) ((long unsigned int) j * 8))) >>>>>; <<cleanup_point (void) j++ >>; <D.3608>:; if (j < N) goto <D.3607>; else goto <D.3605>; <D.3605>:; <<cleanup_point (void) i++ >>; <D.3610>:; if (i < M) goto <D.3609>; else goto <D.3603>; <D.3603>:; } New: { int i; int j; <<cleanup_point <<< Unknown tree: expr_stmt (void) (i = 0) >>>>>; while (1) { if (i >= M) goto <D.3704>; <<cleanup_point <<< Unknown tree: expr_stmt (void) (j = 0) >>>>>; while (1) { if (j >= N) goto <D.3706>; <<cleanup_point <<< Unknown tree: expr_stmt (void) (*(*(lu + (sizetype) ((long unsigned int) i * 8)) + (sizetype) ((long unsigned int) j * 8)) = *(*(A + (sizetype) ((long unsigned int) i * 8)) + (sizetype) ((long unsigned int) j * 8))) >>>>>; <<cleanup_point (void) j++ >>; } <D.3706>:; <<cleanup_point (void) i++ >>; } <D.3704>:; } Or more likely it's the increment after exit check and thus no longer do-while style loops.