https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102129
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2021-08-31 Keywords| |wrong-code Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- For the testcase in the description it's TER that causes code motion of the possibly trapping expression. ssa_is_replaceable_p already tests stmt_could_throw_p (that's including externally throwing) but fails to check for traps. In principle code motion would need to be restricted only up to the next stmt that possibly terminates and only if we are supposed to preserve (the order of) traps and external throwing stmts (with respect to possible observers). The question is whether it is important to preserve as much TER as possible (for optimization purposes). If that's not the case then the following fixes this bug. diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 1a133a09177..484f401ce68 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -64,8 +64,10 @@ ssa_is_replaceable_p (gimple *stmt) if (!is_gimple_assign (stmt)) return false; - /* If the statement may throw an exception, it cannot be replaced. */ - if (stmt_could_throw_p (cfun, stmt)) + /* If the statement may throw an exception or it could trap, + it cannot be replaced. */ + if (stmt_could_throw_p (cfun, stmt) + || gimple_could_trap_p (stmt)) return false; /* Punt if there is more than 1 def. */