re PR tree-optimization/92173 (ICE in optab_for_tree_code, at optabs-tree.c:81)
authorRichard Biener <rguenther@suse.de>
Tue, 22 Oct 2019 13:08:53 +0000 (13:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 22 Oct 2019 13:08:53 +0000 (13:08 +0000)
2019-10-22  Richard Biener  <rguenther@suse.de>

PR tree-optimization/92173
* tree-vect-loop.c (vectorizable_reduction): If
vect_transform_reduction cannot handle code-generation try without
the single-def-use-cycle optimization.  Pass optab_vector to
optab_for_tree_code to get vector shifts as that's what we'd
generate.

* gcc.dg/torture/pr92173.c: New testcase.

From-SVN: r277288

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vshift-5.c
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c

index 34ce686e1a0382bd986f29893d41042a88f68dd7..f8cfef70508389f91b75f5d4c29e18916fcb1833 100644 (file)
@@ -1,3 +1,12 @@
+2019-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/92173
+       * tree-vect-loop.c (vectorizable_reduction): If
+       vect_transform_reduction cannot handle code-generation try without
+       the single-def-use-cycle optimization.  Pass optab_vector to
+       optab_for_tree_code to get vector shifts as that's what we'd
+       generate.
+
 2019-10-22  Michael Matz  <matz@suse.de>
 
        PR middle-end/90796
index 9caf60787d4dab9152d039c9fe85ac0177c6b361..0581b5f50c910e854ec3f03780e110abbf90bcd4 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-22  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/92173
+       * gcc.dg/torture/pr92173.c: New testcase.
+
 2019-10-22  Michael Matz  <matz@suse.de>
 
        PR middle-end/90796
index daa5f1c5cd8e9f1ac2afe08d8ef9b2761c80031f..62e6328cb28468320960a6de4d45d7ab1800e2be 100644 (file)
@@ -40,6 +40,42 @@ f2 (void)
   a[3] = a3;
 }
 
+__attribute__((noinline, noclone)) void
+f2a (int x)
+{
+  long long a0, a1, a2, a3;
+  a0 = a[0];
+  a1 = a[1];
+  a2 = a[2];
+  a3 = a[3];
+  a0 = a0 << x;
+  a1 = a1 << 2;
+  a2 = a2 << 2;
+  a3 = a3 << 2;
+  a[0] = a0;
+  a[1] = a1;
+  a[2] = a2;
+  a[3] = a3;
+}
+
+__attribute__((noinline, noclone)) void
+f2b (int x)
+{
+  long long a0, a1, a2, a3;
+  a0 = a[0];
+  a1 = a[1];
+  a2 = a[2];
+  a3 = a[3];
+  a0 = a0 << 2;
+  a1 = a1 << 2;
+  a2 = a2 << x;
+  a3 = a3 << 2;
+  a[0] = a0;
+  a[1] = a1;
+  a[2] = a2;
+  a[3] = a3;
+}
+
 __attribute__((noinline, noclone)) void
 f3 (int x)
 {
@@ -77,5 +113,13 @@ main ()
   if (a[0] != (4LL << 7) || a[1] != (3LL << 8)
       || a[2] != (2LL << 9) || a[3] != (1LL << 10))
     abort ();
+  f2a (3);
+  if (a[0] != (4LL << 10) || a[1] != (3LL << 10)
+      || a[2] != (2LL << 11) || a[3] != (1LL << 12))
+    abort ();
+  f2b (3);
+  if (a[0] != (4LL << 12) || a[1] != (3LL << 12)
+      || a[2] != (2LL << 14) || a[3] != (1LL << 14))
+    abort ();
   return 0;
 }
index 20ea1059a2d1ae177795ede8870ba64017749e44..864db64d20025ff4691172d8bc9434f3f8eded01 100644 (file)
@@ -475,8 +475,11 @@ again:
       /* Check the types of the definitions.  */
       switch (dt)
        {
-       case vect_constant_def:
        case vect_external_def:
+         /* Make sure to demote the overall operand to external.  */
+         oprnd_info->first_dt = vect_external_def;
+         /* Fallthru.  */
+       case vect_constant_def:
          oprnd_info->def_stmts.quick_push (NULL);
          oprnd_info->ops.quick_push (oprnd);
          break;
@@ -1504,9 +1507,10 @@ static void
 vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
                     slp_tree node, hash_set<slp_tree> &visited)
 {
-  int i;
+  unsigned i;
   stmt_vec_info stmt_info;
   slp_tree child;
+  tree op;
 
   if (visited.add (node))
     return;
@@ -1514,11 +1518,23 @@ vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
   dump_metadata_t metadata (dump_kind, loc.get_impl_location ());
   dump_user_location_t user_loc = loc.get_user_location ();
   dump_printf_loc (metadata, user_loc, "node%s %p (max_nunits=%u)\n",
-                  SLP_TREE_DEF_TYPE (node) != vect_internal_def
-                  ? " (external)" : "", node,
+                  SLP_TREE_DEF_TYPE (node) == vect_external_def
+                  ? " (external)"
+                  : (SLP_TREE_DEF_TYPE (node) == vect_constant_def
+                     ? " (constant)"
+                     : ""), node,
                   estimated_poly_value (node->max_nunits));
-  FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
-    dump_printf_loc (metadata, user_loc, "\tstmt %d %G", i, stmt_info->stmt);
+  if (SLP_TREE_SCALAR_STMTS (node).exists ())
+    FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
+      dump_printf_loc (metadata, user_loc, "\tstmt %u %G", i, stmt_info->stmt);
+  else
+    {
+      dump_printf_loc (metadata, user_loc, "\t{ ");
+      FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
+       dump_printf (metadata, "%T%s ", op,
+                    i < SLP_TREE_SCALAR_OPS (node).length () - 1 ? "," : "");
+      dump_printf (metadata, "}\n");
+    }
   if (SLP_TREE_CHILDREN (node).is_empty ())
     return;
   dump_printf_loc (metadata, user_loc, "\tchildren");
index 7f6100e0ec603420e5e2c9e8d7a5e54e63afad4d..a44c3deb082e19ebe4c6f17c3ab324b87addc4b6 100644 (file)
@@ -5670,8 +5670,11 @@ vectorizable_shift (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
 
       if (!op1_vectype)
        op1_vectype = get_same_sized_vectype (TREE_TYPE (op1), vectype_out);
-      if (op1_vectype == NULL_TREE
-         || TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
+      if ((op1_vectype == NULL_TREE
+          || TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
+         && (!slp_node
+             || SLP_TREE_DEF_TYPE
+                  (SLP_TREE_CHILDREN (slp_node)[1]) != vect_constant_def))
        {
          if (dump_enabled_p ())
            dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@@ -5710,7 +5713,10 @@ vectorizable_shift (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                  so make sure the scalar is the right type if we are
                 dealing with vectors of long long/long/short/char.  */
               if (dt[1] == vect_constant_def)
-                op1 = fold_convert (TREE_TYPE (vectype), op1);
+               {
+                 if (!slp_node)
+                   op1 = fold_convert (TREE_TYPE (vectype), op1);
+               }
              else if (!useless_type_conversion_p (TREE_TYPE (vectype),
                                                   TREE_TYPE (op1)))
                {
@@ -5821,6 +5827,23 @@ vectorizable_shift (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                     }
                 }
             }
+         else if (slp_node
+                  && !useless_type_conversion_p (TREE_TYPE (vectype),
+                                                 TREE_TYPE (op1)))
+           {
+             /* Convert the scalar constant shift amounts in-place.  */
+             slp_tree shift = SLP_TREE_CHILDREN (slp_node)[1];
+             gcc_assert (SLP_TREE_DEF_TYPE (shift) == vect_constant_def);
+             for (unsigned i = 0;
+                  i < SLP_TREE_SCALAR_OPS (shift).length (); ++i)
+               {
+                 SLP_TREE_SCALAR_OPS (shift)[i]
+                   = fold_convert (TREE_TYPE (vectype),
+                                   SLP_TREE_SCALAR_OPS (shift)[i]);
+                 gcc_assert ((TREE_CODE (SLP_TREE_SCALAR_OPS (shift)[i])
+                              == INTEGER_CST));
+               }
+           }
 
           /* vec_oprnd1 is available if operand 1 should be of a scalar-type
              (a special case for certain kind of vector shifts); otherwise,