commit: 25603f8e2ac7815ea0d33bb3bb67add54eec017a Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Sat Apr 5 15:33:23 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Sat Apr 5 15:33:23 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=25603f8e
15.0.0: add another tailcall patch Bug: https://gcc.gnu.org/PR119614 Signed-off-by: Sam James <sam <AT> gentoo.org> 15.0.0/gentoo/88_all_PR119614.patch | 134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/15.0.0/gentoo/88_all_PR119614.patch b/15.0.0/gentoo/88_all_PR119614.patch new file mode 100644 index 0000000..e577f8f --- /dev/null +++ b/15.0.0/gentoo/88_all_PR119614.patch @@ -0,0 +1,134 @@ +https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119614#c12 + +2025-04-05 Jakub Jelinek <[email protected]> + + PR tree-optimization/119614 + * tree-tailcall.cc (find_tail_calls): Remember edges which have been + walked through if !ass_var. Perform IPA-VRP workaround even when + ret_var is not TREE_CONSTANT, in that case check in a loop if it is + a PHI result and in that case look at the PHI argument from + corresponding edge in the edge vector. + + * g++.dg/opt/pr119613.C: Change { c || c++11 } in obviously C++ only + test to just c++11. + * g++.dg/opt/pr119614.C: New test. + +--- a/gcc/tree-tailcall.cc 2025-04-04 20:52:34.450015821 +0200 ++++ b/gcc/tree-tailcall.cc 2025-04-05 14:50:50.106693562 +0200 +@@ -920,6 +920,7 @@ find_tail_calls (basic_block bb, struct + auto_bitmap to_move_defs; + auto_vec<gimple *> to_move_stmts; + bool is_noreturn = gimple_call_noreturn_p (call); ++ auto_vec<edge> edges; + + abb = bb; + agsi = gsi; +@@ -933,6 +934,8 @@ find_tail_calls (basic_block bb, struct + { + edge e = single_non_eh_succ_edge (abb); + ass_var = propagate_through_phis (ass_var, e); ++ if (!ass_var) ++ edges.safe_push (e); + abb = e->dest; + agsi = gsi_start_bb (abb); + } +@@ -1040,9 +1043,7 @@ find_tail_calls (basic_block bb, struct + /* If IPA-VRP proves called function always returns a singleton range, + the return value is replaced by the only value in that range. + For tail call purposes, pretend such replacement didn't happen. */ +- if (ass_var == NULL_TREE +- && !tail_recursion +- && TREE_CONSTANT (ret_var)) ++ if (ass_var == NULL_TREE && !tail_recursion) + if (tree type = gimple_range_type (call)) + if (tree callee = gimple_call_fndecl (call)) + if ((INTEGRAL_TYPE_P (type) +@@ -1052,9 +1053,43 @@ find_tail_calls (basic_block bb, struct + type) + && useless_type_conversion_p (TREE_TYPE (ret_var), type) + && ipa_return_value_range (val, callee) +- && val.singleton_p (&valr) +- && operand_equal_p (ret_var, valr, 0)) +- ok = true; ++ && val.singleton_p (&valr)) ++ { ++ tree rv = ret_var; ++ unsigned int i = edges.length (); ++ /* If ret_var is equal to valr, we can tail optimize. */ ++ if (operand_equal_p (ret_var, valr, 0)) ++ ok = true; ++ else ++ /* Otherwise, if ret_var is a PHI result, try to find out ++ if valr isn't propagated through PHIs on the path from ++ call's bb to SSA_NAME_DEF_STMT (ret_var)'s bb. */ ++ while (TREE_CODE (rv) == SSA_NAME ++ && gimple_code (SSA_NAME_DEF_STMT (rv)) == GIMPLE_PHI) ++ { ++ tree nrv = NULL_TREE; ++ gimple *g = SSA_NAME_DEF_STMT (rv); ++ for (; i; --i) ++ { ++ if (edges[i - 1]->dest == gimple_bb (g)) ++ { ++ nrv ++ = gimple_phi_arg_def_from_edge (g, ++ edges[i - 1]); ++ --i; ++ break; ++ } ++ } ++ if (nrv == NULL_TREE) ++ break; ++ if (operand_equal_p (nrv, valr, 0)) ++ { ++ ok = true; ++ break; ++ } ++ rv = nrv; ++ } ++ } + if (!ok) + { + maybe_error_musttail (call, +--- a/gcc/testsuite/g++.dg/opt/pr119613.C 2025-04-04 20:51:42.482706589 +0200 ++++ b/gcc/testsuite/g++.dg/opt/pr119613.C 2025-04-05 14:57:31.157353618 +0200 +@@ -1,5 +1,5 @@ + // PR middle-end/119613 +-// { dg-do compile { target { musttail && { c || c++11 } } } } ++// { dg-do compile { target { musttail && c++11 } } } + // { dg-options "-O0" } + + struct S { S () {} }; +--- a/gcc/testsuite/g++.dg/opt/pr119614.C 2025-04-05 14:57:16.276551780 +0200 ++++ b/gcc/testsuite/g++.dg/opt/pr119614.C 2025-04-05 14:56:46.020954674 +0200 +@@ -0,0 +1,30 @@ ++// PR tree-optimization/119614 ++// { dg-do compile { target musttail } } ++// { dg-options "-O2" } ++ ++struct S {} b; ++char *foo (); ++int e, g; ++void bar (); ++void corge (S); ++ ++[[gnu::noinline]] char * ++baz () ++{ ++ bar (); ++ return 0; ++} ++ ++const char * ++qux () ++{ ++ if (e) ++ { ++ S a = b; ++ corge (a); ++ if (g) ++ return 0; ++ [[gnu::musttail]] return baz (); ++ } ++ return foo (); ++}
