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

Richard Biener <rguenth at gcc dot gnu.org> changed:

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

--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
With

(simplify      
 (vec_perm @0 @1 VECTOR_CST@2)
...

we have

           /* Generate a canonical form of the selector.  */
           if (!ins && sel.encoding () != builder)
             {
               /* Some targets are deficient and fail to expand a single
                  argument permutation while still allowing an equivalent
                  2-argument version.  */
               tree oldop2 = op2;
               if (sel.ninputs () == 2
                   || can_vec_perm_const_p (result_mode, op_mode, sel, false))
                 op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);
               else
                 {
                   vec_perm_indices sel2 (builder, 2, nelts);
                   if (can_vec_perm_const_p (result_mode, op_mode, sel2,
false))
                     op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2);
                   else
                     /* Not directly supported with either encoding,
                        so use the preferred form.  */
                     op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);

where the last case can generate a not supported permute and the ninputs == 2
guard is botched.  I think sth like the following was intended, but it
doesn't fix the testcase.

diff --git a/gcc/match.pd b/gcc/match.pd
index ad966766376..f5caa472411 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11043,15 +11043,14 @@ and,
                  argument permutation while still allowing an equivalent
                  2-argument version.  */
               tree oldop2 = op2;
-              if (sel.ninputs () == 2
-                  || can_vec_perm_const_p (result_mode, op_mode, sel, false))
+              if (can_vec_perm_const_p (result_mode, op_mode, sel, false))
                 op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);
-              else
+              else if (sel.ninputs () == 1)
                 {
                   vec_perm_indices sel2 (builder, 2, nelts);
                   if (can_vec_perm_const_p (result_mode, op_mode, sel2,
false))
                     op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel2);
-                  else
+                  else if (optimize_vectors_before_lowering_p ())
                     /* Not directly supported with either encoding,
                        so use the preferred form.  */
                     op2 = vec_perm_indices_to_tree (TREE_TYPE (op2), sel);

I'll note that RTL expansion does

  /* Always specify two input vectors here and leave the target to handle
     cases in which the inputs are equal.  Not all backends can cope with
     the single-input representation when testing for a double-input
     target instruction.  */
  vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));

so the above target support checks might be "wrong" in this sense if it
matters at all which the above suggests.

Reply via email to