middle-end: Fix PR103007, add missing check on complex fms detection.
authorTamar Christina <tamar.christina@arm.com>
Tue, 2 Nov 2021 13:26:36 +0000 (13:26 +0000)
committerTamar Christina <tamar.christina@arm.com>
Tue, 2 Nov 2021 13:28:15 +0000 (13:28 +0000)
The complex FMS detection is missing a check on if the nodes of the VEC_PERM
has the amount of children we expect before it recurses.

This check is there on MUL and FMA but was missing for FMS, due to this the
compiler goes on further than it should and hits an assert.

gcc/ChangeLog:

PR tree-optimization/103007
* tree-vect-slp-patterns.c (complex_fms_pattern::matches): Add elem
check.

gcc/testsuite/ChangeLog:

PR tree-optimization/103007
* g++.dg/pr103007.C: New test.

gcc/testsuite/g++.dg/pr103007.C [new file with mode: 0644]
gcc/tree-vect-slp-patterns.c

diff --git a/gcc/testsuite/g++.dg/pr103007.C b/gcc/testsuite/g++.dg/pr103007.C
new file mode 100644 (file)
index 0000000..1631a85
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+typedef float MushMeshVector[4];
+struct MushMeshQuaternionPair {
+  void VectorRotate(MushMeshVector &);
+  MushMeshVector m_first;
+  MushMeshVector m_second;
+};
+void 
+MushMeshQuaternionPair::
+VectorRotate(MushMeshVector &ioVec)  {
+  ioVec[2] = (2 - m_first[1] + m_first[3] * 0);
+  ioVec[3] = (m_first[3] + m_first[1] - m_first[2] * 0);
+  float c = ioVec[2], d = ioVec[3];
+  ioVec[2] = (0 - d * m_second[1]);
+  ioVec[3] = (2 - c * m_second[1]);
+}
+
index 99dea82..e08a15e 100644 (file)
@@ -1197,13 +1197,17 @@ complex_fms_pattern::matches (complex_operation_t op,
 
   auto childs = SLP_TREE_CHILDREN (nodes[0]);
   auto l0node = SLP_TREE_CHILDREN (childs[0]);
-  auto l1node = SLP_TREE_CHILDREN (childs[1]);
 
   /* Now operand2+4 may lead to another expression.  */
   auto_vec<slp_tree> left_op, right_op;
   left_op.safe_splice (SLP_TREE_CHILDREN (l0node[1]));
   right_op.safe_splice (SLP_TREE_CHILDREN (nodes[1]));
 
+  /* If these nodes don't have any children then they're
+     not ones we're interested in.  */
+  if (left_op.length () != 2 || right_op.length () != 2)
+    return IFN_LAST;
+
   bool is_neg = vect_normalize_conj_loc (left_op);
 
   bool conj_first_operand = false;