Hi, While looking through bug reports, I noticed someone had reported that LTO caused the vectorizer not to kick in. Originally it was not obvious why it would change the behavior since this was a simple program with nothing out of the ordinary. Well it turned out paths leading to the exit(0); at the end of main was being marked as cold and in the LTO case the funciton (which had loop which should have been vectorized) was considered local and being marked as cold as it was only called now from the path leading to the exit(0); Since exit(0); is considered a normal exit path, there is no reason to mark it as being as a cold path; let the other predicate handle it.
So this patch changes the predicate for exit(0) not to mark the paths leading up to that function call as being cold. Note this patch only disables that when the argument is a literal zero so if we a PHI node which contains the exit value, we still cause those paths to be considered cold; this will be for another patch. OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions. Also tested it with SPEC CPU 2006 with no performance regressions. Thanks, Andrew Pinski ChangeLog: * predict.c (is_exit_with_zero_arg): New function. (tree_bb_level_predictions): Don't consider paths leading to exit(0) as nottaken.
Index: gcc/predict.c =================================================================== --- gcc/predict.c (revision 240299) +++ gcc/predict.c (working copy) @@ -2513,6 +2513,21 @@ } } +/* Returns TRUE if the STMT is exit(0) like statement. */ + +static bool +is_exit_with_zero_arg (const gimple *stmt) +{ + /* This is not exit, _exit or _Exit. */ + if (!gimple_call_builtin_p (stmt, BUILT_IN_EXIT) + && !gimple_call_builtin_p (stmt, BUILT_IN__EXIT) + && !gimple_call_builtin_p (stmt, BUILT_IN__EXIT2)) + return false; + + /* Argument is an interger zero. */ + return integer_zerop (gimple_call_arg (stmt, 0)); +} + /* Try to guess whether the value of return means error code. */ static enum br_predictor @@ -2639,7 +2654,9 @@ if (is_gimple_call (stmt)) { - if (gimple_call_noreturn_p (stmt) && has_return_edges) + if (gimple_call_noreturn_p (stmt) + && has_return_edges + && !is_exit_with_zero_arg (stmt)) predict_paths_leading_to (bb, PRED_NORETURN, NOT_TAKEN); decl = gimple_call_fndecl (stmt);