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;
+  }
+}

Reply via email to