https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118864
ak at gcc dot gnu.org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ak at gcc dot gnu.org --- Comment #3 from ak at gcc dot gnu.org --- For cross jumping it would be in old_insns_match_p I think FWIW I tried to write a patch there for noreturn, but it didn't fix the original issue in PR118198, likely due to some other code transformations diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc index d28d2323191..b784d5eca7a 100644 --- a/gcc/cfgcleanup.cc +++ b/gcc/cfgcleanup.cc @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "rtl-iter.h" #include "regs.h" +#include "calls.h" #include "function-abi.h" #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) @@ -1207,6 +1208,11 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2)) return dir_none; + /* Avoid merging noreturn to improve backtraces. */ + if (rtx call = get_call_rtx_from (i1); + call && find_reg_note (call, REG_NORETURN, NULL)) + return dir_none; + /* For address sanitizer, never crossjump __asan_report_* builtins, otherwise errors might be reported on incorrect lines. */ if (flag_sanitize & SANITIZE_ADDRESS) diff --git a/gcc/tree-ssa-tail-merge.cc b/gcc/tree-ssa-tail-merge.cc index d897970079c..fc23672930d 100644 --- a/gcc/tree-ssa-tail-merge.cc +++ b/gcc/tree-ssa-tail-merge.cc @@ -1312,6 +1312,10 @@ merge_stmts_p (gimple *stmt1, gimple *stmt2) if (lookup_stmt_eh_lp_fn (cfun, stmt1) != lookup_stmt_eh_lp_fn (cfun, stmt2)) return false; + /* Don't merge noreturn to give accurate backtraces. */ + if (is_gimple_call (stmt1) && (gimple_call_flags (stmt1) & ECF_NORETURN)) + return false; + if (is_gimple_call (stmt1) && gimple_call_internal_p (stmt1)) switch (gimple_call_internal_fn (stmt1))