aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-03-28 15:20:22 +0200
committerRichard Biener <rguenther@suse.de>2023-03-29 08:33:00 +0200
commitc9954996cd647daf0ba03e34dd279b97982f671f (patch)
treef51a515351d496e17ae4475d93848c2db3b81c9b /gcc
parent91293ffb6af18705ab7857dc47656bdd74a9ce31 (diff)
downloadgcc-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.cc24
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);