From c9954996cd647daf0ba03e34dd279b97982f671f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 28 Mar 2023 15:20:22 +0200 Subject: [PATCH] tree-optimization/109154 - improve if-conversion for vectorization With multi-argument PHIs and now doing VN on the if-converted blocks the optimization of CSEing condition and negated condition doesn't work well anymore. The following restores this a little bit for the case of a single inverted condition into a COND_EXPR where we can instead swap the COND_EXPR arms. The same optimization is already done for the case of two-argument PHIs. This avoids one comparison/mask for the testcase at hand. PR tree-optimization/109154 * tree-if-conv.cc (gen_phi_arg_condition): Handle single inverted condition specially by inverting at the caller. (gen_phi_arg_condition): Swap COND_EXPR arms if requested. --- gcc/tree-if-conv.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc index ca1abd8..3494dcc 100644 --- a/gcc/tree-if-conv.cc +++ b/gcc/tree-if-conv.cc @@ -1873,11 +1873,12 @@ convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi, return rhs; } -/* Produce condition for all occurrences of ARG in PHI node. */ +/* Produce condition for all occurrences of ARG in PHI node. Set *INVERT + as to whether the condition is inverted. */ static tree gen_phi_arg_condition (gphi *phi, vec *occur, - gimple_stmt_iterator *gsi) + gimple_stmt_iterator *gsi, bool *invert) { int len; int i; @@ -1885,6 +1886,7 @@ gen_phi_arg_condition (gphi *phi, vec *occur, tree c; edge e; + *invert = false; len = occur->length (); gcc_assert (len > 0); for (i = 0; i < len; i++) @@ -1896,6 +1898,13 @@ gen_phi_arg_condition (gphi *phi, vec *occur, cond = c; break; } + /* If we have just a single inverted predicate, signal that and + instead invert the COND_EXPR arms. */ + if (len == 1 && TREE_CODE (c) == TRUTH_NOT_EXPR) + { + c = TREE_OPERAND (c, 0); + *invert = true; + } c = force_gimple_operand_gsi (gsi, unshare_expr (c), true, NULL_TREE, true, GSI_SAME_STMT); if (cond != NULL_TREE) @@ -2116,9 +2125,14 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi) lhs = make_temp_ssa_name (type, NULL, "_ifc_"); else lhs = res; - cond = gen_phi_arg_condition (phi, indexes, gsi); - rhs = fold_build_cond_expr (type, unshare_expr (cond), - arg0, arg1); + bool invert; + cond = gen_phi_arg_condition (phi, indexes, gsi, &invert); + if (invert) + rhs = fold_build_cond_expr (type, unshare_expr (cond), + arg1, arg0); + else + rhs = fold_build_cond_expr (type, unshare_expr (cond), + arg0, arg1); new_stmt = gimple_build_assign (lhs, rhs); gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT); update_stmt (new_stmt); -- 2.7.4