aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-11-08 09:43:26 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2024-11-12 08:33:58 +0100
commit61cd1c43b82dc9d4c3edf122d22887fdce340223 (patch)
treeca74e11b310c61c963dc524fdb655b7eaec73449
parent0b27a7dd050262a7d64d87863201e4ebbde88386 (diff)
downloadgcc-61cd1c43b82dc9d4c3edf122d22887fdce340223.zip
gcc-61cd1c43b82dc9d4c3edf122d22887fdce340223.tar.gz
gcc-61cd1c43b82dc9d4c3edf122d22887fdce340223.tar.bz2
tree-optimization/117484 - issue with SLP discovery of permuted .MASK_LOAD
When we do SLP discovery of a .MASK_LOAD for a dataref group with gaps the discovery for the mask will have gaps as well and this was unexpected in a few places. The following re-organizes things slightly to accomodate for this. PR tree-optimization/117484 * tree-vect-slp.cc (vect_build_slp_tree_2): Handle gaps in mask discovery. Fix condition to release the load permutation. (vect_lower_load_permutations): Assert we get no load permutation for the unpermuted node. * tree-vect-slp-patterns.cc (linear_loads_p): Properly identify loads (without permutation). (compatible_complex_nodes_p): Likewise. * gcc.dg/vect/pr117484-1.c: New testcase. * gcc.dg/vect/pr117484-2.c: Likewise.
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr117484-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr117484-2.c16
-rw-r--r--gcc/tree-vect-slp-patterns.cc14
-rw-r--r--gcc/tree-vect-slp.cc22
4 files changed, 52 insertions, 13 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr117484-1.c b/gcc/testsuite/gcc.dg/vect/pr117484-1.c
new file mode 100644
index 0000000..453556c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr117484-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+extern int a;
+extern short b[];
+extern signed char c[], d[];
+int main()
+{
+ for (long j = 3; j < 1024; j += 3)
+ if (c[j] ? b[j] : 0) {
+ b[j] = d[j - 2];
+ a = d[j];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr117484-2.c b/gcc/testsuite/gcc.dg/vect/pr117484-2.c
new file mode 100644
index 0000000..baffe75
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr117484-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+int a;
+extern int d[];
+extern int b[];
+extern _Bool c[];
+extern char h[];
+int main()
+{
+ for (int i = 0; i < 1024; i += 4)
+ if (h[i] || c[i])
+ {
+ a = d[i];
+ b[i] = d[i - 3];
+ }
+}
diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc
index 8adae8a..d62682b 100644
--- a/gcc/tree-vect-slp-patterns.cc
+++ b/gcc/tree-vect-slp-patterns.cc
@@ -221,9 +221,15 @@ linear_loads_p (slp_tree_to_load_perm_map_t *perm_cache, slp_tree root)
perm_cache->put (root, retval);
/* If it's a load node, then just read the load permute. */
- if (SLP_TREE_LOAD_PERMUTATION (root).exists ())
+ if (SLP_TREE_DEF_TYPE (root) == vect_internal_def
+ && SLP_TREE_CODE (root) != VEC_PERM_EXPR
+ && STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (root))
+ && DR_IS_READ (STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (root))))
{
- retval = is_linear_load_p (SLP_TREE_LOAD_PERMUTATION (root));
+ if (SLP_TREE_LOAD_PERMUTATION (root).exists ())
+ retval = is_linear_load_p (SLP_TREE_LOAD_PERMUTATION (root));
+ else
+ retval = PERM_EVENODD;
perm_cache->put (root, retval);
return retval;
}
@@ -798,8 +804,8 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache,
return false;
}
- if (!SLP_TREE_LOAD_PERMUTATION (a).exists ()
- || !SLP_TREE_LOAD_PERMUTATION (b).exists ())
+ if (!STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a))
+ || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b)))
{
for (unsigned i = 0; i < gimple_num_args (a_stmt); i++)
{
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index d3efd53..eebac19 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -2019,14 +2019,15 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
= STMT_VINFO_GROUPED_ACCESS (stmt_info)
? DR_GROUP_FIRST_ELEMENT (stmt_info) : stmt_info;
bool any_permute = false;
- bool any_null = false;
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), j, load_info)
{
int load_place;
if (! load_info)
{
- load_place = j;
- any_null = true;
+ if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+ load_place = j;
+ else
+ load_place = 0;
}
else if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
load_place = vect_get_place_in_interleaving_chain
@@ -2037,11 +2038,6 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
any_permute |= load_place != j;
load_permutation.quick_push (load_place);
}
- if (any_null)
- {
- gcc_assert (!any_permute);
- load_permutation.release ();
- }
if (gcall *stmt = dyn_cast <gcall *> (stmt_info->stmt))
{
@@ -2096,6 +2092,8 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
followed by 'node' being the desired final permutation. */
if (unperm_load)
{
+ gcc_assert
+ (!SLP_TREE_LOAD_PERMUTATION (unperm_load).exists ());
lane_permutation_t lperm;
lperm.create (group_size);
for (unsigned j = 0; j < load_permutation.length (); ++j)
@@ -2116,6 +2114,10 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
}
else
{
+ if (!any_permute
+ && STMT_VINFO_GROUPED_ACCESS (stmt_info)
+ && group_size == DR_GROUP_SIZE (first_stmt_info))
+ load_permutation.release ();
SLP_TREE_LOAD_PERMUTATION (node) = load_permutation;
return node;
}
@@ -2690,7 +2692,8 @@ out:
tree op0;
tree uniform_val = op0 = oprnd_info->ops[0];
for (j = 1; j < oprnd_info->ops.length (); ++j)
- if (!operand_equal_p (uniform_val, oprnd_info->ops[j]))
+ if (oprnd_info->ops[j]
+ && !operand_equal_p (uniform_val, oprnd_info->ops[j]))
{
uniform_val = NULL_TREE;
break;
@@ -4525,6 +4528,7 @@ vect_lower_load_permutations (loop_vec_info loop_vinfo,
group_lanes,
&max_nunits, matches, &limit,
&tree_size, bst_map);
+ gcc_assert (!SLP_TREE_LOAD_PERMUTATION (l0).exists ());
if (ld_lanes_lanes != 0)
{