On Sun, Jul 27, 2025 at 8:43 PM Andrew Pinski <quic_apin...@quicinc.com> wrote: > > When I added the factor operations to ifcvt, I messed how handling of removing > the phi nodes. The fix is we need to remove the phi node that was factored out > as we factored out the operator because otherwise scev can go when it comes > to detecting if the new args are from a reduction. > > Also the need to change the interface for is_cond_scalar_reduction as the > phi node that was being passed after the factoring no longer exists so need > to pass the parts that were being used.
OK. Richard. > PR tree-optimization/121236 > > gcc/ChangeLog: > > * tree-if-conv.cc (is_cond_scalar_reduction): Instead of phi argument, > pass bb and res of the phi. > (factor_out_operators): Add iterator for the phi. Remove the phi > if this is the first time. Return if we had removed the phi. > (predicate_scalar_phi): Add the phi iterator argument. > Update call to is_cond_scalar_reduction. > Update call to factor_out_operators and set the return value to true > when factor_out_operators returns true. > (predicate_all_scalar_phis): Don't remove the phi if > predicate_scalar_phi > already removed it. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/pr121236-1.c: New test. > > Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> > --- > gcc/testsuite/gcc.dg/torture/pr121236-1.c | 20 ++++++++ > gcc/tree-if-conv.cc | 60 +++++++++++++---------- > 2 files changed, 55 insertions(+), 25 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr121236-1.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr121236-1.c > b/gcc/testsuite/gcc.dg/torture/pr121236-1.c > new file mode 100644 > index 00000000000..2b397e34078 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr121236-1.c > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* PR tree-optimization/121236 */ > + > + > +unsigned func_26(short *p_27, int gg, int p) { > + unsigned l_184 = 0; > + unsigned m = 0; > + for (int g_59 = 0; g_59 < 10; g_59++) > + { > + if (gg) > + l_184--; > + else > + { > + m |= l_184 |= p; > + (l_184)--; > + } > + } > + return m; > +} > + > diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc > index ba25c19c50c..a8b800ba09e 100644 > --- a/gcc/tree-if-conv.cc > +++ b/gcc/tree-if-conv.cc > @@ -1755,7 +1755,7 @@ strip_nop_cond_scalar_reduction (bool has_nop, tree op) > EXTENDED is true if PHI has > 2 arguments. */ > > static bool > -is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree > arg_1, > +is_cond_scalar_reduction (basic_block bb, tree phi_res, gimple **reduc, tree > arg_0, tree arg_1, > tree *op0, tree *op1, bool extended, bool* has_nop, > gimple **nop_reduc) > { > @@ -1763,7 +1763,6 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, > tree arg_0, tree arg_1, > gimple *stmt; > gimple *header_phi = NULL; > enum tree_code reduction_op; > - basic_block bb = gimple_bb (phi); > class loop *loop = bb->loop_father; > edge latch_e = loop_latch_edge (loop); > imm_use_iterator imm_iter; > @@ -1791,7 +1790,7 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, > tree arg_0, tree arg_1, > if (gimple_bb (header_phi) != loop->header) > return false; > > - if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi)) > + if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != phi_res) > return false; > > if (gimple_code (stmt) != GIMPLE_ASSIGN > @@ -1889,7 +1888,7 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, > tree arg_0, tree arg_1, > continue; > if (use_stmt == SSA_NAME_DEF_STMT (r_op1)) > continue; > - if (use_stmt != phi) > + if (use_stmt != SSA_NAME_DEF_STMT (phi_res)) > return false; > } > } > @@ -2199,8 +2198,8 @@ commutative: > and *RES to the new values if the factoring happened. > Loops until all of the factoring is completed. */ > > -static void > -factor_out_operators (tree *res, gimple_stmt_iterator *gsi, > +static bool > +factor_out_operators (gimple_stmt_iterator *pgsi, tree *res, > gimple_stmt_iterator *gsi, > tree *arg0, tree *arg1, gphi *phi) > { > gimple_match_op arg0_op, arg1_op; > @@ -2208,28 +2207,28 @@ factor_out_operators (tree *res, gimple_stmt_iterator > *gsi, > > again: > if (TREE_CODE (*arg0) != SSA_NAME || TREE_CODE (*arg1) != SSA_NAME) > - return; > + return repeated; > > if (operand_equal_p (*arg0, *arg1)) > - return; > + return repeated; > > /* If either args have > 1 use, then this transformation actually > increases the number of expressions evaluated at runtime. */ > if (repeated > ? (!has_zero_uses (*arg0) || !has_zero_uses (*arg1)) > : (!has_single_use (*arg0) || !has_single_use (*arg1))) > - return; > + return repeated; > > gimple *arg0_def_stmt = SSA_NAME_DEF_STMT (*arg0); > if (!gimple_extract_op (arg0_def_stmt, &arg0_op)) > - return; > + return repeated; > > /* At this point there should be no ssa names occuring in abnormals. */ > gcc_assert (!arg0_op.operands_occurs_in_abnormal_phi ()); > > gimple *arg1_def_stmt = SSA_NAME_DEF_STMT (*arg1); > if (!gimple_extract_op (arg1_def_stmt, &arg1_op)) > - return; > + return repeated; > > /* At this point there should be no ssa names occuring in abnormals. */ > gcc_assert (!arg1_op.operands_occurs_in_abnormal_phi ()); > @@ -2238,15 +2237,15 @@ again: > or the number operands. */ > if (arg1_op.code != arg0_op.code > || arg1_op.num_ops != arg0_op.num_ops) > - return; > + return repeated; > > tree new_arg0, new_arg1; > int opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1); > if (opnum == -1) > - return; > + return repeated; > > if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1))) > - return; > + return repeated; > tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL); > > /* Create the operation stmt if possible and insert it. */ > @@ -2262,7 +2261,7 @@ again: > if (!result) > { > release_ssa_name (new_res); > - return; > + return repeated; > } > gsi_insert_seq_before (gsi, seq, GSI_CONTINUE_LINKING); > > @@ -2277,6 +2276,10 @@ again: > fprintf (dump_file, ".\n"); > } > > + /* Remove the phi and move to the next phi arg if needed. */ > + if (!repeated) > + remove_phi_node (pgsi, false); > + > /* Remove the old operation(s) that has single use. */ > gimple_stmt_iterator gsi_for_def; > > @@ -2400,8 +2403,9 @@ cmp_arg_entry (const void *p1, const void *p2, void * > /* data. */) > vectorization. */ > > > -static void > -predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi, bool > loop_versioned) > +static bool > +predicate_scalar_phi (gimple_stmt_iterator *phi_gsi, gphi *phi, > + gimple_stmt_iterator *gsi, bool loop_versioned) > { > gimple *new_stmt = NULL, *reduc, *nop_reduc; > tree rhs, res, arg0, arg1, op0, op1, scev; > @@ -2411,10 +2415,11 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > basic_block bb; > unsigned int i; > bool has_nop; > + bool removed_phi = false; > > res = gimple_phi_result (phi); > if (virtual_operand_p (res)) > - return; > + return removed_phi; > > if ((rhs = degenerate_phi_result (phi)) > || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father, > @@ -2431,7 +2436,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > new_stmt = gimple_build_assign (res, rhs); > gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); > update_stmt (new_stmt); > - return; > + return removed_phi; > } > > bb = gimple_bb (phi); > @@ -2477,9 +2482,13 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > > /* Factor out operand if possible. This can only be done easily > for PHI with 2 elements. */ > - factor_out_operators (&res, gsi, &arg0, &arg1, phi); > + if (factor_out_operators (phi_gsi, &res, gsi, &arg0, &arg1, phi)) > + { > + phi = nullptr; > + removed_phi = true; > + } > > - if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1, > + if (is_cond_scalar_reduction (bb, res, &reduc, arg0, arg1, > &op0, &op1, false, &has_nop, > &nop_reduc)) > { > @@ -2508,7 +2517,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > fprintf (dump_file, "new phi replacement stmt\n"); > print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); > } > - return; > + return removed_phi; > } > > /* Create hashmap for PHI node which contain vector of argument indexes > @@ -2576,7 +2585,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > /* Gimplify the condition to a valid cond-expr conditonal operand. */ > cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true, > NULL_TREE, true, GSI_SAME_STMT); > - if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1, > + if (!(is_cond_scalar_reduction (bb, res, &reduc, arg0 , arg1, > &op0, &op1, true, &has_nop, > &nop_reduc))) > rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond), > swap ? arg1 : arg0, > @@ -2606,6 +2615,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator > *gsi, bool loop_versioned) > fprintf (dump_file, "new extended phi replacement stmt\n"); > print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM); > } > + return removed_phi; > } > > /* Replaces in LOOP all the scalar phi nodes other than those in the > @@ -2642,8 +2652,8 @@ predicate_all_scalar_phis (class loop *loop, bool > loop_versioned) > gsi_next (&phi_gsi); > else > { > - predicate_scalar_phi (phi, &gsi, loop_versioned); > - remove_phi_node (&phi_gsi, false); > + if (!predicate_scalar_phi (&phi_gsi, phi, &gsi, loop_versioned)) > + remove_phi_node (&phi_gsi, false); > } > } > } > -- > 2.43.0 >