https://gcc.gnu.org/g:3d4bfd43059c3a92b9608d3d17f8c045a58edda1
commit r15-8918-g3d4bfd43059c3a92b9608d3d17f8c045a58edda1 Author: Richard Biener <rguent...@suse.de> Date: Tue Mar 25 13:45:36 2025 +0100 middle-end/118795 - fix can_vec_perm_const_p query in match.pd When expanding to RTL we always use vec_perm_indices with two operands which can make a difference with respect to supported vs. unsupported. So the following adjusts a query in match.pd for target support which got this "wrong" and using 1 for a equal operand permute. PR middle-end/118795 * match.pd (vec_perm <vec_perm <a, b>> -> vec_perm <a, b>): Use the appropriate check to see whether the original outer permute was supported. * g++.dg/torture/pr118795.C: New testcase. Diff: --- gcc/match.pd | 2 +- gcc/testsuite/g++.dg/torture/pr118795.C | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index 98f637373242..ba036e528370 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11121,7 +11121,7 @@ and, (with { vec_perm_indices sel0 (builder0, 2, nelts); - vec_perm_indices sel1 (builder1, 1, nelts); + vec_perm_indices sel1 (builder1, 2, nelts); for (int i = 0; i < nelts; i++) builder2.quick_push (sel0[sel1[i].to_constant ()]); diff --git a/gcc/testsuite/g++.dg/torture/pr118795.C b/gcc/testsuite/g++.dg/torture/pr118795.C new file mode 100644 index 000000000000..fc40f81f7fd0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr118795.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +unsigned char *a(); +struct b { + void c() const; +}; +void b::c() const { + unsigned char *d = a(), *e = a(); + for (long f; f; ++f) { + e[0] = e[1] = e[2] = d[0]; + e[3] = d[0]; + d += 4; + e += 4; + } +}