https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84859
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- Mine. We can handle the case of a single store in the BBs more generally and bypass the limit. The limit was added in r171381 where it was imposed on all transforms when the function was changed to handle the case of more than one stmt (store) in each BB. Previously the transform for the single stores case was always performed. Thus, for example like the following. Could be simplified somewhat iff the stores need to be the last stmt in the BBs (like it was before said re-org). last_and_only_stmt isn't enough here as we have a feeding scalar stmt around in one BB. Opinions? Index: gcc/tree-ssa-phiopt.c =================================================================== --- gcc/tree-ssa-phiopt.c (revision 258552) +++ gcc/tree-ssa-phiopt.c (working copy) @@ -2061,8 +2061,6 @@ static bool cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, basic_block join_bb) { - gimple *then_assign = last_and_only_stmt (then_bb); - gimple *else_assign = last_and_only_stmt (else_bb); vec<data_reference_p> then_datarefs, else_datarefs; vec<ddr_p> then_ddrs, else_ddrs; gimple *then_store, *else_store; @@ -2073,14 +2071,49 @@ cond_if_else_store_replacement (basic_bl tree then_lhs, else_lhs; basic_block blocks[3]; - if (MAX_STORES_TO_SINK == 0) + /* Handle the case with single store in THEN_BB and ELSE_BB. That is + cheap enough to always handle. */ + gphi *vphi = NULL; + for (gphi_iterator si = gsi_start_phis (join_bb); !gsi_end_p (si); + gsi_next (&si)) + if (virtual_operand_p (gimple_phi_result (si.phi ()))) + { + vphi = si.phi (); + break; + } + if (!vphi) return false; + gimple *then_assign = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE + (vphi, single_succ_edge (then_bb))); + gimple *else_assign = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE + (vphi, single_succ_edge (else_bb))); + + /* Verify there are no other stores or loads in the BBs. That allows us + to elide dependence checking. */ + use_operand_p use_p; + imm_use_iterator imm_iter; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (then_assign)) + if (USE_STMT (use_p) != then_assign + && gimple_bb (USE_STMT (use_p)) == then_bb) + { + then_assign = NULL; + break; + } + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (else_assign)) + if (USE_STMT (use_p) != else_assign + && gimple_bb (USE_STMT (use_p)) == else_bb) + { + else_assign = NULL; + break; + } - /* Handle the case with single statement in THEN_BB and ELSE_BB. */ if (then_assign && else_assign) return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, then_assign, else_assign); + if (MAX_STORES_TO_SINK == 0) + return false; + /* Find data references. */ then_datarefs.create (1); else_datarefs.create (1);