aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-05-02 12:01:51 +0200
committerRichard Biener <rguenther@suse.de>2022-05-02 13:16:59 +0200
commit41e3db05d697405256b6002d8432955a93d249f1 (patch)
tree40b90a111fceeacd1629f52b7d936c8713ff767e /gcc
parent86d821ddf5615e693ead667b2580898f46de8eb9 (diff)
downloadgcc-41e3db05d697405256b6002d8432955a93d249f1.zip
gcc-41e3db05d697405256b6002d8432955a93d249f1.tar.gz
gcc-41e3db05d697405256b6002d8432955a93d249f1.tar.bz2
tree-optimization/104240 - SLP discovery with swapped comparisons
The following extends SLP discovery to handle swapped operands in comparisons. 2022-05-02 Richard Biener <rguenther@suse.de> PR tree-optimization/104240 * tree-vect-slp.cc (op1_op0_map): New. (vect_get_operand_map): Handle compares. (vect_build_slp_tree_1): Support swapped operands for tcc_comparison. * gcc.dg/vect/bb-slp-pr104240.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c14
-rw-r--r--gcc/tree-vect-slp.cc19
2 files changed, 32 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c
new file mode 100644
index 0000000..78905a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_cond_mixed } */
+
+void foo (int *c, float *x, float *y)
+{
+ c[0] = x[0] < y[0];
+ c[1] = y[1] > x[1];
+ c[2] = x[2] < y[2];
+ c[3] = x[3] < y[3];
+}
+
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 0d400c0..2685bc1 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -462,6 +462,7 @@ static const int cond_expr_maps[3][5] = {
static const int arg1_map[] = { 1, 1 };
static const int arg2_map[] = { 1, 2 };
static const int arg1_arg4_map[] = { 2, 1, 4 };
+static const int op1_op0_map[] = { 2, 1, 0 };
/* For most SLP statements, there is a one-to-one mapping between
gimple arguments and child nodes. If that is not true for STMT,
@@ -482,6 +483,9 @@ vect_get_operand_map (const gimple *stmt, unsigned char swap = 0)
if (gimple_assign_rhs_code (assign) == COND_EXPR
&& COMPARISON_CLASS_P (gimple_assign_rhs1 (assign)))
return cond_expr_maps[swap];
+ if (TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison
+ && swap)
+ return op1_op0_map;
}
gcc_assert (!swap);
if (auto call = dyn_cast<const gcall *> (stmt))
@@ -1116,6 +1120,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
&& (alt_stmt_code == PLUS_EXPR
|| alt_stmt_code == MINUS_EXPR)
&& rhs_code == alt_stmt_code)
+ && !(first_stmt_code.is_tree_code ()
+ && rhs_code.is_tree_code ()
+ && (TREE_CODE_CLASS (tree_code (first_stmt_code))
+ == tcc_comparison)
+ && (swap_tree_comparison (tree_code (first_stmt_code))
+ == tree_code (rhs_code)))
&& !(STMT_VINFO_GROUPED_ACCESS (stmt_info)
&& (first_stmt_code == ARRAY_REF
|| first_stmt_code == BIT_FIELD_REF
@@ -1313,6 +1323,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
continue;
}
}
+
+ if (rhs_code.is_tree_code ()
+ && TREE_CODE_CLASS ((tree_code)rhs_code) == tcc_comparison
+ && (swap_tree_comparison ((tree_code)first_stmt_code)
+ == (tree_code)rhs_code))
+ swap[i] = 1;
}
matches[i] = true;
@@ -1326,7 +1342,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
with the permute we are going to use. */
if (alt_stmt_code != ERROR_MARK
&& (!alt_stmt_code.is_tree_code ()
- || TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference))
+ || (TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference
+ && TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_comparison)))
{
*two_operators = true;
}