https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106422
Alexander Monakov <amonakov at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |amonakov at gcc dot gnu.org --- Comment #3 from Alexander Monakov <amonakov at gcc dot gnu.org> --- Thanks for the report and reduced testcase. There are at least two issues here: 1. Somehow GCC thinks that attribute-leaf functions cannot resume an earlier returns_twice function. This is a wrong belief, causing GCC to omit ABNORMAL_DISPATCHER and associated edges for even simple testcases like #include <unistd.h> #include <signal.h> void f() { if (!vfork()) raise(SIGKILL); } (when a block with a returns_twice function does not have abnormal edges, we could say that it's fine to duplicate because all other calls that might have resumed its execution have been eliminated, but with the above issue corrected there will always be an edge from the function itself, e.g. a later vfork can cause an earlier vfork at the same call site to resume) 2. It seems backward jump threading uses can_copy_bbs_p and copy_bbs, which disallows duplicating a returns_twice call, while forward jump threading calls duplicate_block without checking apparently?