From: Andrew Pinski Date: Tue, 23 Sep 2025 19:14:47 +0000 (-0700) Subject: fab/forwprop: Move optimize_unreachable to forwprop [PR121762] X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=415f21fed2c5411cc6a378317f7142b22a623358;p=thirdparty%2Fgcc.git fab/forwprop: Move optimize_unreachable to forwprop [PR121762] This moves the optimize_unreachable to forwprop from fab. There is a slightly optimization here in that the first statement is checked and outside of the main fold loop. And if the statement is __builtin_unreachable, then call optimize_unreachable. Changes since v1: * v2: simplified the check for BUILT_IN_UNREACHABLE to just use gimple_call_builtin_p. Move the code after checking for not executable blocks. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/121762 gcc/ChangeLog: * tree-ssa-ccp.cc (optimize_unreachable): Move to tree-ssa-forwprop.cc (pass_fold_builtins::execute): Remove handling of __builtin_unreachable. * tree-ssa-forwprop.cc (optimize_unreachable): New function from tree-ssa-ccp.cc. Change argument to bb. Remove check on first statement being the __builtin_unreachable since it is handled already. (pass_forwprop::execute): Handle first statement as being __builtin_unreachable by calling optimize_unreachable. Signed-off-by: Andrew Pinski --- diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 739d3be9129..b69a8b64a61 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -3202,58 +3202,6 @@ optimize_stdarg_builtin (gimple_stmt_iterator *gsi, gimple *call) } } -/* Attemp to make the block of __builtin_unreachable I unreachable by changing - the incoming jumps. Return true if at least one jump was changed. */ - -static bool -optimize_unreachable (gimple_stmt_iterator i) -{ - basic_block bb = gsi_bb (i); - gimple_stmt_iterator gsi; - gimple *stmt; - edge_iterator ei; - edge e; - bool ret; - - if (flag_sanitize & SANITIZE_UNREACHABLE) - return false; - gsi = gsi_start_nondebug_after_labels_bb (bb); - /* Only handle the case that __builtin_unreachable is the first - statement in the block. We rely on DCE to remove stmts - without side-effects before __builtin_unreachable. */ - if (*gsi != *i) - return false; - - ret = false; - FOR_EACH_EDGE (e, ei, bb->preds) - { - gsi = gsi_last_bb (e->src); - if (gsi_end_p (gsi)) - continue; - - stmt = gsi_stmt (gsi); - if (gcond *cond_stmt = dyn_cast (stmt)) - { - if (e->flags & EDGE_TRUE_VALUE) - gimple_cond_make_false (cond_stmt); - else if (e->flags & EDGE_FALSE_VALUE) - gimple_cond_make_true (cond_stmt); - else - gcc_unreachable (); - update_stmt (cond_stmt); - } - else - { - /* Todo: handle other cases. Note that unreachable switch case - statements have already been removed. */ - continue; - } - - ret = true; - } - - return ret; -} /* Convert _1 = __atomic_fetch_or_* (ptr_6, 1, _3); @@ -4235,12 +4183,6 @@ pass_fold_builtins::execute (function *fun) tree result = NULL_TREE; switch (DECL_FUNCTION_CODE (callee)) { - - case BUILT_IN_UNREACHABLE: - if (optimize_unreachable (i)) - cfg_changed = true; - break; - case BUILT_IN_ATOMIC_ADD_FETCH_1: case BUILT_IN_ATOMIC_ADD_FETCH_2: case BUILT_IN_ATOMIC_ADD_FETCH_4: diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 941b01f3d0e..9307e216207 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -4906,6 +4906,49 @@ public: bool m_full_walk = false; }; // class pass_forwprop +/* Attemp to make the BB block of __builtin_unreachable unreachable by changing + the incoming jumps. Return true if at least one jump was changed. */ + +static bool +optimize_unreachable (basic_block bb) +{ + gimple_stmt_iterator gsi; + gimple *stmt; + edge_iterator ei; + edge e; + bool ret; + + ret = false; + FOR_EACH_EDGE (e, ei, bb->preds) + { + gsi = gsi_last_bb (e->src); + if (gsi_end_p (gsi)) + continue; + + stmt = gsi_stmt (gsi); + if (gcond *cond_stmt = dyn_cast (stmt)) + { + if (e->flags & EDGE_TRUE_VALUE) + gimple_cond_make_false (cond_stmt); + else if (e->flags & EDGE_FALSE_VALUE) + gimple_cond_make_true (cond_stmt); + else + gcc_unreachable (); + update_stmt (cond_stmt); + } + else + { + /* Todo: handle other cases. Note that unreachable switch case + statements have already been removed. */ + continue; + } + + ret = true; + } + + return ret; +} + unsigned int pass_forwprop::execute (function *fun) { @@ -4973,6 +5016,21 @@ pass_forwprop::execute (function *fun) if (!any) continue; + /* Remove conditions that go directly to unreachable when this is the last forwprop. */ + if (last_p + && !(flag_sanitize & SANITIZE_UNREACHABLE)) + { + gimple_stmt_iterator gsi; + gsi = gsi_start_nondebug_after_labels_bb (bb); + if (!gsi_end_p (gsi) + && gimple_call_builtin_p (*gsi, BUILT_IN_UNREACHABLE) + && optimize_unreachable (bb)) + { + cfg_changed = true; + continue; + } + } + /* Record degenerate PHIs in the lattice. */ for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))