Hi,

As discussed on IRC: This patches fixes the calculation of the scalar costs of 
SLP vectorization. I’ve added a test case and the auto_vec allocation is now 
reused for all children of a node.

diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c 
b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c
new file mode 100644
index 0000000..5121a88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-slp-details" } */
+
+#define N 4
+
+int s1[N], s2[N], s3[N];
+void escape(int, int, int, int);
+
+void
+foo ()
+{
+  int t1, t2, t3, t4;
+
+  t1 = s1[0] + s2[0] + s3[0];
+  t2 = s1[1] + s2[1] + s3[1];
+  t3 = s1[2] + s2[2] + s3[2];
+  t4 = s1[3] + s2[3] + s3[3];
+
+  s3[0] = t1 - s1[0] * s2[0];
+  s3[1] = t2 - s1[1] * s2[1];
+  s3[2] = t3 - s1[2] * s2[2];
+  s3[3] = t4 - s1[3] * s2[3];
+
+  escape (t1, t2, t3, t4);
+}
+
+/* { dg-final { scan-tree-dump-not "vectorization is not profitable" "slp2" } 
} */
+/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 04ecaab..cffd19b 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2690,9 +2690,17 @@ vect_bb_slp_scalar_cost (basic_block bb,
      scalar_cost += stmt_cost;
    }

+  auto_vec<bool, 20> subtree_life;
+
  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
    if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
-      scalar_cost += vect_bb_slp_scalar_cost (bb, child, life);
+      {
+       /* Do not directly pass LIFE to the recursive call, copy it to
+          confine changes in the callee to the current child/subtree.  */
+       subtree_life.safe_splice (*life);
+       scalar_cost += vect_bb_slp_scalar_cost (bb, child, &subtree_life);
+       subtree_life.truncate (0);
+      }

  return scalar_cost;
}

> On 04 Aug 2017, at 12:19, Richard Biener <richard.guent...@gmail.com> wrote:
> 
> On Fri, Aug 4, 2017 at 12:08 PM, Dominik Inführ
> <dominik.infu...@theobroma-systems.com> wrote:
>> Hi,
>> 
>> vect_bb_slp_scalar_cost computes the scalar cost of a SLP node. If there are 
>> non-scalar uses of a definition, the costs for it and its operands 
>> (children) are ignored. The vector LIFE is used to keep track of this and an 
>> element is set to true, such that the def and its children are ignored. But 
>> as soon as an element is set to true it is never undone, that means the 
>> following sibling and parent nodes of the current node also stay ignored.
> 
> Yes, that's intended.  They are live as well because they are needed
> to compute the live scalar.
> 
> This seems wrong to me, a simple fix would be to clone LIFE for every
> vector, such that changes to LIFE stay in the subtree:
>> 
>> diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
>> index 032a9444a5a..f919645f28b 100644
>> --- a/gcc/tree-vect-slp.c
>> +++ b/gcc/tree-vect-slp.c
>> @@ -2590,6 +2590,11 @@ vect_bb_slp_scalar_cost (basic_block bb,
>>   gimple *stmt;
>>   slp_tree child;
>> 
>> +  auto_vec<bool, 20> subtree_life;
>> +  subtree_life.safe_splice (*life);
>> +
>> +  life = &subtree_life;
>> +
>>   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
>>     {
>>       unsigned stmt_cost;
>> 
>> 

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to