Currently, simplify_vector_constructor () tries to rewrite a CONSTRUCTOR
expression into a VEC_PERM_EXPR, as long as constructor elements all come
from 1 or 2 source vectors.  While doing so, it protects against creating
VEC_PERM_EXPRs unsupported by the target by calling can_vec_perm_const_p
() before enacting the transformation and bailing when that returns false.

However, we can instead allow those VEC_PERM_EXPRs to be created if we
know that a later vector lowering pass will legitimize them for us.  IOW,
only if the target doesn't support the resulting permute and the
PROP_gimple_lvec property is already set, do we give up.  This patch
inserts the required checks.

This also allows us to remove the unnecessary vect_int requirement
(wrongly added in r16-5244-g5a2319b71e4d30) from forwprop-43.c.

Regtested on aarch64 and x86_64, and on arm with
RUNTESTFLAGS=--target_board=unix/-mfpu=vfpv3-d16/-march=armv7-a.

        PR tree-optimization/122679

gcc/ChangeLog:

        * tree-ssa-forwprop.cc (simplify_vector_constructor): Check the
        PROP_gimple_lvec property before bailing.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/forwprop-43.c: Remove the vect_int check.
---
 gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c | 1 -
 gcc/tree-ssa-forwprop.cc                    | 6 ++++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c 
b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
index bfda376e1f7..0e802ea5107 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
@@ -1,7 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -fdump-tree-forwprop1" } */
 /* { dg-require-effective-target stdint_types } */
-/* { dg-require-effective-target vect_int } */
 /* { dg-additional-options "-fgimple" } */
 
 #include <stdint.h>
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index bdc63a7a71b..6c847ee7ff3 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -4173,7 +4173,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
                           ? 0 : refnelts) + i);
       vec_perm_indices indices (sel, orig[1] ? 2 : 1, refnelts);
       machine_mode vmode = TYPE_MODE (perm_type);
-      if (!can_vec_perm_const_p (vmode, vmode, indices))
+      if (!can_vec_perm_const_p (vmode, vmode, indices)
+         && (cfun->curr_properties & PROP_gimple_lvec))
        return false;
       mask_type = build_vector_type (ssizetype, refnelts);
       tree op2 = vec_perm_indices_to_tree (mask_type, indices);
@@ -4238,7 +4239,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
                            ? elts[i].second + nelts : i);
          vec_perm_indices indices (sel, 2, nelts);
          machine_mode vmode = TYPE_MODE (type);
-         if (!can_vec_perm_const_p (vmode, vmode, indices))
+         if (!can_vec_perm_const_p (vmode, vmode, indices)
+             && (cfun->curr_properties & PROP_gimple_lvec))
            return false;
          mask_type = build_vector_type (ssizetype, nelts);
          blend_op2 = vec_perm_indices_to_tree (mask_type, indices);
-- 
2.43.0

Reply via email to