From: Jakub Jelinek Date: Fri, 20 Oct 2017 07:35:48 +0000 (+0200) Subject: re PR target/82158 (_Noreturn functions that do return clobber caller's registers... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=356fcc67fba52b6d923ab72769247300b847478d;p=gcc.git re PR target/82158 (_Noreturn functions that do return clobber caller's registers on ARM32 (but not other arches)) PR target/82158 * tree-cfg.c (pass_warn_function_return::execute): In noreturn functions when optimizing replace GIMPLE_RETURN stmts with calls to __builtin_unreachable (). * gcc.dg/tree-ssa/noreturn-1.c: New test. From-SVN: r253926 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f28e70a3776..42d98733299 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2017-10-20 Jakub Jelinek + PR target/82158 + * tree-cfg.c (pass_warn_function_return::execute): In noreturn + functions when optimizing replace GIMPLE_RETURN stmts with + calls to __builtin_unreachable (). + PR sanitizer/82595 * config/gnu-user.h (LIBTSAN_EARLY_SPEC): Add libtsan_preinit.o for -fsanitize=thread link of executables. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d3b3be3699d..35cc34e6cb2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-10-20 Jakub Jelinek + PR target/82158 + * gcc.dg/tree-ssa/noreturn-1.c: New test. + PR target/82370 * gcc.target/i386/avx-pr82370.c: New test. * gcc.target/i386/avx2-pr82370.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/noreturn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/noreturn-1.c new file mode 100644 index 00000000000..ae7ee42fabc --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/noreturn-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } * +/* { dg-options "-O2 -fdump-tree-ssa -std=gnu11" } */ +/* { dg-final { scan-tree-dump-times "__builtin_unreachable" 4 "ssa" } } */ + +void bar1 (void); +void bar2 (void); +void bar3 (void); +void bar4 (void); + +_Noreturn void +foo1 (int *p, int y) +{ + bar1 (); + *p = y; + return; /* { dg-warning "function declared 'noreturn' has a 'return' statement" } */ +} /* { dg-warning "'noreturn' function does return" "" { target *-*-* } .-1 } */ + +_Noreturn void +foo2 (int *p, int y) +{ + bar2 (); + *p = y; +} /* { dg-warning "'noreturn' function does return" } */ + +_Noreturn void +foo3 (int *p, int y) +{ + if (y > 10) + return; /* { dg-warning "function declared 'noreturn' has a 'return' statement" } */ + bar3 (); + *p = y; + return; /* { dg-warning "function declared 'noreturn' has a 'return' statement" } */ +} /* { dg-warning "'noreturn' function does return" } */ + +_Noreturn void +foo4 (int *p, int y) +{ + if (y > 10) + return; /* { dg-warning "function declared 'noreturn' has a 'return' statement" } */ + bar4 (); + *p = y; +} /* { dg-warning "'noreturn' function does return" } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index a7c7348ed29..ae1cdb33f53 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -9077,13 +9077,29 @@ pass_warn_function_return::execute (function *fun) && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0) { location = UNKNOWN_LOCATION; - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) + for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (fun)->preds); + (e = ei_safe_edge (ei)); ) { last = last_stmt (e->src); if ((gimple_code (last) == GIMPLE_RETURN || gimple_call_builtin_p (last, BUILT_IN_RETURN)) - && (location = gimple_location (last)) != UNKNOWN_LOCATION) + && location == UNKNOWN_LOCATION + && (location = gimple_location (last)) != UNKNOWN_LOCATION + && !optimize) break; + /* When optimizing, replace return stmts in noreturn functions + with __builtin_unreachable () call. */ + if (optimize && gimple_code (last) == GIMPLE_RETURN) + { + tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE); + gimple *new_stmt = gimple_build_call (fndecl, 0); + gimple_set_location (new_stmt, gimple_location (last)); + gimple_stmt_iterator gsi = gsi_for_stmt (last); + gsi_replace (&gsi, new_stmt, true); + remove_edge (e); + } + else + ei_next (&ei); } if (location == UNKNOWN_LOCATION) location = cfun->function_end_locus;