From: Andrew Pinski Date: Fri, 3 Oct 2025 21:09:57 +0000 (-0700) Subject: phiopt: allow store placement of `= {}` [PR122153] X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14a825d4891f12ae0e2595b6b08a3555518f5dcb;p=thirdparty%2Fgcc.git phiopt: allow store placement of `= {}` [PR122153] Currently cselim and cselim-limited are able to handle stores which have a rhs of a ssa name or a constant. This extends that support to also allow `= {}`. The sink pass will also commonalize the store but in some cases this is too late in the pipeline. Doing it in phiopt1 allows for better inlining estimates too. This is also the first step in improving/fixing PR 122083 such that we do an early inlining which is now not happening for GCC 15+. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/122153 gcc/ChangeLog: * tree-ssa-phiopt.cc (cond_if_else_store_replacement_1): Handle stores of empty constructors too. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr122153-1.c: New test. Signed-off-by: Andrew Pinski --- diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr122153-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr122153-1.c new file mode 100644 index 00000000000..d6e7527aaa6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr122153-1.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt1" } */ +/* PR tree-optimization/122153 */ +struct s1 +{ + int t; +}; +void g(struct s1*); +struct s1 f(int *a, int c, int d) +{ + struct s1 r; + int t1; + if (c < d) + { + r = (struct s1){}; + t1 = c; + } + else + { + r = (struct s1){}; + t1 = d; + } + g(&r); + r.t = t1; + return r; +} +/* the `r = {};` store should be commonialized out of the conditional + and produce a MIN_EXPR in phiopt1. */ + +/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } */ diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index e1c9e1296c0..bdd1f7396da 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -3645,6 +3645,7 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, gimple_stmt_iterator gsi; gphi *newphi; gassign *new_stmt; + bool empty_constructor = false; if (then_assign == NULL || !gimple_assign_single_p (then_assign) @@ -3659,8 +3660,7 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, return false; lhs = gimple_assign_lhs (then_assign); - if (!is_gimple_reg_type (TREE_TYPE (lhs)) - || !operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0)) + if (!operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0)) return false; lhs_base = get_base_address (lhs); @@ -3673,6 +3673,16 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, then_locus = gimple_location (then_assign); else_locus = gimple_location (else_assign); + if (!is_gimple_reg_type (TREE_TYPE (lhs))) + { + if (!operand_equal_p (then_rhs, else_rhs)) + return false; + /* Currently only handle commoning of `= {}`. */ + if (TREE_CODE (then_rhs) != CONSTRUCTOR) + return false; + empty_constructor = true; + } + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf(dump_file, "factoring out stores:\n\tthen:\n"); @@ -3699,12 +3709,17 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, /* 2) Create a PHI node at the join block, with one argument holding the old RHS, and the other holding the temporary where we stored the old memory contents. */ - name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore"); - newphi = create_phi_node (name, join_bb); - add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus); - add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus); + if (empty_constructor) + name = unshare_expr (then_rhs); + else + { + name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore"); + newphi = create_phi_node (name, join_bb); + add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus); + add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus); + } - new_stmt = gimple_build_assign (lhs, gimple_phi_result (newphi)); + new_stmt = gimple_build_assign (lhs, name); /* Update the vdef for the new store statement. */ tree newvphilhs = make_ssa_name (gimple_vop (cfun)); tree vdef = gimple_phi_result (vphi); @@ -3715,16 +3730,21 @@ cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, update_stmt (vphi); if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf(dump_file, "to use phi:\n"); - print_gimple_stmt (dump_file, newphi, 0, - TDF_VOPS|TDF_MEMSYMS); - fprintf(dump_file, "\n"); + if (!empty_constructor) + { + fprintf(dump_file, "to use phi:\n"); + print_gimple_stmt (dump_file, newphi, 0, + TDF_VOPS|TDF_MEMSYMS); + fprintf(dump_file, "\n"); + } + else + fprintf(dump_file, "to:\n"); print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS); fprintf(dump_file, "\n\n"); } - /* 3) Insert that PHI node. */ + /* 3) Insert that new store. */ gsi = gsi_after_labels (join_bb); if (gsi_end_p (gsi)) {