https://gcc.gnu.org/g:e94e91d6f37750cae671ea7f82ce55bda3f8f372
commit r16-5556-ge94e91d6f37750cae671ea7f82ce55bda3f8f372 Author: Andrew Pinski <[email protected]> Date: Thu Nov 20 23:14:24 2025 -0800 phiprop: allowing prop into loop if there is a phi already This is a small improvement over the original change for PR60183 where if we created a phi already we can reuse it always but since the order of this use might be before the use which was valid to transform. we need a vector to save the delayed ones. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/60183 gcc/ChangeLog: * tree-ssa-phiprop.cc (propagate_with_phi): Delay the decision of always rejecting proping into the loop until all are done. if there was some delay stmts and a phi was created fill them in. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/phiprop-5.c: New test. Signed-off-by: Andrew Pinski <[email protected]> Diff: --- gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c | 26 ++++++++++++++++++++++ gcc/tree-ssa-phiprop.cc | 37 ++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c new file mode 100644 index 000000000000..b76b17c046a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-5.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { weak_undefined } } } */ +/* { dg-options "-O1 -fdump-tree-phiprop1-details" } */ +/* { dg-add-options weak_undefined } */ + +/* PR tree-optimization/60183 */ + +unsigned char c; +extern unsigned char d __attribute__((weak)); +int j = 2; + +unsigned long +foo (void) +{ + unsigned char *y = &c; + int i; + unsigned w = 0; + for (i = 0; i < *y; i++) + { + w = *y; + y = &d; + } + return w; +} +/* the load from d can trap but the load always happen so this should be done. */ +/* { dg-final { scan-tree-dump "Removing dead stmt:" "phiprop1"} } */ +/* { dg-final { scan-tree-dump "Inserting PHI for result of load" "phiprop1"} } */ diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc index 124d06c81911..a2e039fb72d9 100644 --- a/gcc/tree-ssa-phiprop.cc +++ b/gcc/tree-ssa-phiprop.cc @@ -331,10 +331,12 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, can move the loads to the place of the ptr phi node. */ phi_inserted = false; changed = false; + auto_vec<gimple*> delayed_uses; FOR_EACH_IMM_USE_STMT (use_stmt, ui, ptr) { gimple *def_stmt; tree vuse; + bool delay = false; if (!dom_info_available_p (cfun, CDI_POST_DOMINATORS)) calculate_dominance_info (CDI_POST_DOMINATORS); @@ -344,7 +346,7 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, if (canpossible_trap && !dominated_by_p (CDI_POST_DOMINATORS, bb, gimple_bb (use_stmt))) - continue; + delay = true; /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) @@ -396,6 +398,9 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, insert aggregate copies on the edges instead. */ if (!is_gimple_reg_type (TREE_TYPE (gimple_assign_lhs (use_stmt)))) { + /* aggregate copies are too hard to handled if delayed. */ + if (delay) + goto next; if (!gimple_vdef (use_stmt)) goto next; @@ -450,10 +455,19 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, changed = true; } - + /* Further replacements are easy, just make a copy out of the + load. */ + else if (phi_inserted) + { + gimple_assign_set_rhs1 (use_stmt, res); + update_stmt (use_stmt); + changed = true; + } + else if (delay) + delayed_uses.safe_push (use_stmt); /* Found a proper dereference. Insert a phi node if this is the first load transformation. */ - else if (!phi_inserted) + else { res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n, dce_ssa_names); type = TREE_TYPE (res); @@ -470,19 +484,20 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi, phi_inserted = true; changed = true; } - else - { - /* Further replacements are easy, just make a copy out of the - load. */ - gimple_assign_set_rhs1 (use_stmt, res); - update_stmt (use_stmt); - changed = true; - } next:; /* Continue searching for a proper dereference. */ } + /* Update the delayed uses if there is any + as now we know this is safe to do. */ + if (phi_inserted) + for (auto use_stmt : delayed_uses) + { + gimple_assign_set_rhs1 (use_stmt, res); + update_stmt (use_stmt); + } + return changed; }
