https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85692

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Untested patch:

--- gcc/tree-ssa-forwprop.c.jj  2018-01-04 22:08:04.492684761 +0100
+++ gcc/tree-ssa-forwprop.c     2018-05-08 16:07:09.356121105 +0200
@@ -2004,7 +2004,7 @@ simplify_vector_constructor (gimple_stmt
 {
   gimple *stmt = gsi_stmt (*gsi);
   gimple *def_stmt;
-  tree op, op2, orig, type, elem_type;
+  tree op, op2, orig[2], type, elem_type;
   unsigned elem_size, i;
   unsigned HOST_WIDE_INT nelts;
   enum tree_code code, conv_code;
@@ -2023,7 +2023,8 @@ simplify_vector_constructor (gimple_stmt
   elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));

   vec_perm_builder sel (nelts, nelts, 1);
-  orig = NULL;
+  orig[0] = NULL;
+  orig[1] = NULL;
   conv_code = ERROR_MARK;
   maybe_ident = true;
   FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
@@ -2063,25 +2064,35 @@ simplify_vector_constructor (gimple_stmt
        return false;
       op1 = gimple_assign_rhs1 (def_stmt);
       ref = TREE_OPERAND (op1, 0);
-      if (orig)
+      unsigned int j;
+      for (j = 0; j < 2; ++j)
        {
-         if (ref != orig)
-           return false;
-       }
-      else
-       {
-         if (TREE_CODE (ref) != SSA_NAME)
-           return false;
-         if (! VECTOR_TYPE_P (TREE_TYPE (ref))
-             || ! useless_type_conversion_p (TREE_TYPE (op1),
-                                             TREE_TYPE (TREE_TYPE (ref))))
-           return false;
-         orig = ref;
+         if (!orig[j])
+           {
+             if (TREE_CODE (ref) != SSA_NAME)
+               return false;
+             if (! VECTOR_TYPE_P (TREE_TYPE (ref))
+                 || ! useless_type_conversion_p (TREE_TYPE (op1),
+                                                 TREE_TYPE (TREE_TYPE (ref))))
+               return false;
+             if (j && !useless_type_conversion_p (TREE_TYPE (orig[0]),
+                                                  TREE_TYPE (ref)))
+               return false;
+             orig[j] = ref;
+             break;
+           }
+         else if (ref == orig[j])
+           break;
        }
+      if (j == 2)
+       return false;
+
       unsigned int elt;
       if (maybe_ne (bit_field_size (op1), elem_size)
          || !constant_multiple_p (bit_field_offset (op1), elem_size, &elt))
        return false;
+      if (j)
+       elt += nelts;
       if (elt != i)
        maybe_ident = false;
       sel.quick_push (elt);
@@ -2089,14 +2100,14 @@ simplify_vector_constructor (gimple_stmt
   if (i < nelts)
     return false;

-  if (! VECTOR_TYPE_P (TREE_TYPE (orig))
+  if (! VECTOR_TYPE_P (TREE_TYPE (orig[0]))
       || maybe_ne (TYPE_VECTOR_SUBPARTS (type),
-                  TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig))))
+                  TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0]))))
     return false;

   tree tem;
   if (conv_code != ERROR_MARK
-      && (! supportable_convert_operation (conv_code, type, TREE_TYPE (orig),
+      && (! supportable_convert_operation (conv_code, type, TREE_TYPE
(orig[0]),
                                           &tem, &conv_code)
          || conv_code == CALL_EXPR))
     return false;
@@ -2104,16 +2115,16 @@ simplify_vector_constructor (gimple_stmt
   if (maybe_ident)
     {
       if (conv_code == ERROR_MARK)
-       gimple_assign_set_rhs_from_tree (gsi, orig);
+       gimple_assign_set_rhs_from_tree (gsi, orig[0]);
       else
-       gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
+       gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0],
                                        NULL_TREE, NULL_TREE);
     }
   else
     {
       tree mask_type;

-      vec_perm_indices indices (sel, 1, nelts);
+      vec_perm_indices indices (sel, orig[1] ? 2 : 1, nelts);
       if (!can_vec_perm_const_p (TYPE_MODE (type), indices))
        return false;
       mask_type
@@ -2124,16 +2135,19 @@ simplify_vector_constructor (gimple_stmt
                       GET_MODE_SIZE (TYPE_MODE (type))))
        return false;
       op2 = vec_perm_indices_to_tree (mask_type, indices);
+      if (!orig[1])
+       orig[1] = orig[0];
       if (conv_code == ERROR_MARK)
-       gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
+       gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig[0],
+                                       orig[1], op2);
       else
        {
          gimple *perm
-           = gimple_build_assign (make_ssa_name (TREE_TYPE (orig)),
-                                  VEC_PERM_EXPR, orig, orig, op2);
-         orig = gimple_assign_lhs (perm);
+           = gimple_build_assign (make_ssa_name (TREE_TYPE (orig[0])),
+                                  VEC_PERM_EXPR, orig[0], orig[1], op2);
+         orig[0] = gimple_assign_lhs (perm);
          gsi_insert_before (gsi, perm, GSI_SAME_STMT);
-         gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
+         gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0],
                                          NULL_TREE, NULL_TREE);
        }
     }

Reply via email to