diff options
author | Richard Biener <rguenther@suse.de> | 2023-03-28 15:20:22 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-03-29 08:33:00 +0200 |
commit | c9954996cd647daf0ba03e34dd279b97982f671f (patch) | |
tree | f51a515351d496e17ae4475d93848c2db3b81c9b /gcc | |
parent | 91293ffb6af18705ab7857dc47656bdd74a9ce31 (diff) | |
download | gcc-c9954996cd647daf0ba03e34dd279b97982f671f.zip gcc-c9954996cd647daf0ba03e34dd279b97982f671f.tar.gz gcc-c9954996cd647daf0ba03e34dd279b97982f671f.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/tree-if-conv.cc | 24 |
1 files 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<int> *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<int> *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<int> *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); |