The following fixes the fix from r16-6709-ga4716ece529dfd some
more by making sure permute to one operand folding faces same
element number vectors but also insert a VIEW_CONVERT_EXPR for
the case one is VLA and one is VLS (when the VLA case is actually
constant, like with -msve-vector-bits=128). It also makes the
assert that output and input element numbers match done in
fold_vec_perm which this pattern eventually dispatches to into
a check (as the comment already indicates).
Testcases are in the target specific aarch64 testsuite already.
Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.
I'll push once that succeeded.
PR middle-end/123573
* fold-const.cc (fold_vec_perm): Actually check, not assert,
that input and output vector element numbers agree.
* match.pd (vec_perm @0 @1 @2): Make sure element numbers
are the same when folding to an input vector and wrap that
inside a VIEW_CONVERT_EXPR.
---
gcc/fold-const.cc | 5 ++---
gcc/match.pd | 6 +++---
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 52c92ad66b5..f7b712f0c78 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -10704,11 +10704,10 @@ fold_vec_perm (tree type, tree arg0, tree arg1, const
vec_perm_indices &sel)
/* For fall back case, we want to ensure we have VLS vectors
with equal length. */
- if (!sel.length ().is_constant (&nelts))
+ if (!sel.length ().is_constant (&nelts)
+ || !known_eq (sel.length (), TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))))
return NULL_TREE;
- gcc_assert (known_eq (sel.length (),
- TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))));
tree *in_elts = XALLOCAVEC (tree, nelts * 2);
if (!vec_cst_ctor_to_array (arg0, nelts, in_elts)
|| !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts))
diff --git a/gcc/match.pd b/gcc/match.pd
index c339762b90c..f29f7638d66 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11528,9 +11528,9 @@ and,
vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts_in);
}
(if (known_eq (nelts, nelts_in) && sel.series_p (0, 1, 0, 1))
- { op0; }
- (if (sel.series_p (0, 1, nelts_in, 1))
- { op1; }
+ (view_convert @0)
+ (if (known_eq (nelts, nelts_in) && sel.series_p (0, 1, nelts_in, 1))
+ (view_convert @1)
(with
{
if (!single_arg)
--
2.51.0