From: Jakub Jelinek Date: Tue, 7 Feb 2023 09:34:45 +0000 (+0100) Subject: ipa-split: Don't split returns_twice functions [PR106923] X-Git-Tag: basepoints/gcc-14~1479 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5321d53279a60ee589a3c9779beb46503f9fc49f;p=thirdparty%2Fgcc.git ipa-split: Don't split returns_twice functions [PR106923] As discussed in the PR, returns_twice functions are rare/special beasts that need special treatment in the cfg, and inside of their bodies we don't know which part actually works the weird returns twice way (either in the fork/vfork sense, or in the setjmp) and aren't updating ab edges to reflect that. I think easiest is just to never split these, like we already never split noreturn or malloc functions. 2023-02-07 Jakub Jelinek PR tree-optimization/106923 * ipa-split.cc (execute_split_functions): Don't split returns_twice functions. * gcc.dg/pr106923.c: New test. --- diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc index 0113461065cc..6730f4f9d0e3 100644 --- a/gcc/ipa-split.cc +++ b/gcc/ipa-split.cc @@ -1715,10 +1715,11 @@ execute_split_functions (void) struct cgraph_node *node = cgraph_node::get (current_function_decl); if (flags_from_decl_or_type (current_function_decl) - & (ECF_NORETURN|ECF_MALLOC)) + & (ECF_NORETURN|ECF_MALLOC|ECF_RETURNS_TWICE)) { if (dump_file) - fprintf (dump_file, "Not splitting: noreturn/malloc function.\n"); + fprintf (dump_file, "Not splitting: noreturn/malloc/returns_twice " + "function.\n"); return 0; } if (MAIN_NAME_P (DECL_NAME (current_function_decl))) diff --git a/gcc/testsuite/gcc.dg/pr106923.c b/gcc/testsuite/gcc.dg/pr106923.c new file mode 100644 index 000000000000..1c89f418810c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106923.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/106923 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -finline-small-functions -fpartial-inlining --param max-inline-insns-single=1 --param uninlined-function-insns=10000" } */ + +int n; + +int +baz (void); + +__attribute__ ((returns_twice)) int +bar (void) +{ + if (baz ()) + ++n; + + return 0; +} + +int +foo (void) +{ + return bar (); +}