Fix vector/scalar to vector/vector conversion (PR92515)
authorRichard Sandiford <richard.sandiford@arm.com>
Fri, 15 Nov 2019 14:37:57 +0000 (14:37 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 15 Nov 2019 14:37:57 +0000 (14:37 +0000)
r278235 broke conversions of vector/scalar shifts into vector/vector
shifts on targets that only provide the latter.  We need to record
whether a conversion is required in that case too.

Also, the old useless_type_conversion_p condition seemed unnecessarily
strong, since the shift amount can have a different signedness from
the shifted value and its vector type is never assumed to be identical
to vectype.  The patch therefore uses tree_nop_conversion_p instead.

2019-11-15  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR tree-optimization/92515
* tree-vect-stmts.c (vectorizable_shift): Record incompatible op1
types when converting a vector/scalar shift into a vector/vector one,
using tree_nop_conversion_p instead of useless_type_conversion_p.
Move the conversion code to the transform block.

From-SVN: r278295

gcc/ChangeLog
gcc/tree-vect-stmts.c

index 9784821..619afc5 100644 (file)
@@ -1,3 +1,11 @@
+2019-11-15  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/92515
+       * tree-vect-stmts.c (vectorizable_shift): Record incompatible op1
+       types when converting a vector/scalar shift into a vector/vector one,
+       using tree_nop_conversion_p instead of useless_type_conversion_p.
+       Move the conversion code to the transform block.
+
 2019-11-15  Matthew Malcomson  <matthew.malcomson@arm.com>
 
        * read-rtl-function.c
index a65b4cb..6164946 100644 (file)
@@ -5750,21 +5750,9 @@ vectorizable_shift (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                  the rhs being int, instead of the same type as the lhs,
                  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)
-               {
-                 if (!slp_node)
-                   op1 = fold_convert (TREE_TYPE (vectype), op1);
-               }
-             else if (!useless_type_conversion_p (TREE_TYPE (vectype),
-                                                  TREE_TYPE (op1)))
-               {
-                 if (vec_stmt && !slp_node)
-                   {
-                     op1 = fold_convert (TREE_TYPE (vectype), op1);
-                     op1 = vect_init_vector (stmt_info, op1,
-                                             TREE_TYPE (vectype), NULL);
-                   }
-               }
+             incompatible_op1_vectype_p
+               = !tree_nop_conversion_p (TREE_TYPE (vectype),
+                                         TREE_TYPE (op1));
             }
         }
     }
@@ -5819,6 +5807,14 @@ vectorizable_shift (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
     dump_printf_loc (MSG_NOTE, vect_location,
                      "transform binary/unary operation.\n");
 
+  if (incompatible_op1_vectype_p && !slp_node)
+    {
+      op1 = fold_convert (TREE_TYPE (vectype), op1);
+      if (dt[1] != vect_constant_def)
+       op1 = vect_init_vector (stmt_info, op1,
+                               TREE_TYPE (vectype), NULL);
+    }
+
   /* Handle def.  */
   vec_dest = vect_create_destination_var (scalar_dest, vectype);