[gcc r16-9272] middle-end/125875 - incomplete guards on VEC_PERM_EXPR folding

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:d7e04528080c1ae202c7021677dd60cef03df436

commit r16-9272-gd7e04528080c1ae202c7021677dd60cef03df436
Author: Richard Biener <[email protected]>
Date:   Fri Jun 26 10:55:29 2026 +0200

    middle-end/125875 - incomplete guards on VEC_PERM_EXPR folding
    
    This fixes up match.pd patterns using can_vec_perm_const_p on
    existing permutations to indicate whether we are before or
    after vector lowering.  For this to be correct we have to use
    the new vec_perm_indices CTOR taking the actual permuted inputs
    so can_vec_perm_const_p can also handle the vec_shl/vec_shr
    expansion path.
    
            PR middle-end/125875
            * match.pd: When checking for !can_vec_perm_const_p also
            allow variable permutes and use the vec_perm_indices CTOR
            with the original tree operands.
    
            * gcc.dg/torture/pr125875.c: New testcase.
    
    (cherry picked from commit f3475825fe0c609482ab30714f2d616f9c7b8fd7)

Diff:
---
 gcc/match.pd                            | 52 +++++++++++++--------------------
 gcc/testsuite/gcc.dg/torture/pr125875.c | 29 ++++++++++++++++++
 2 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 12054c6bcc53..87a6c2377962 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -11743,19 +11743,15 @@ and,
      machine_mode result_mode = TYPE_MODE (type);
      machine_mode op_mode = TYPE_MODE (TREE_TYPE (@2));
      int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
-     vec_perm_builder builder0;
-     vec_perm_builder builder1;
-     vec_perm_builder builder2 (nelts, nelts, 1);
+     vec_perm_indices sel0, sel1;
    }
-   (if (tree_to_vec_perm_builder (&builder0, @4)
-	&& tree_to_vec_perm_builder (&builder1, @5)
+   (if (tree_to_vec_perm_indices (&sel0, @2, @3, @4)
+	&& tree_to_vec_perm_indices (&sel1, @0, @0, @5)
 	&& TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0)))
 	   == TYPE_SIZE (TREE_TYPE (TREE_TYPE (@1))))
     (with
      {
-       vec_perm_indices sel0 (builder0, 2, nelts);
-       vec_perm_indices sel1 (builder1, 2, nelts);
-
+       vec_perm_builder builder2 (nelts, nelts, 1);
        for (int i = 0; i < nelts; i++)
 	 builder2.quick_push (sel0[sel1[i].to_constant ()]);
 
@@ -11769,9 +11765,9 @@ and,
 	  number of VEC_PERM_EXPRs that can't be handled.  */
        if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)
 	   || (single_use (@0)
-	       ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false)
-		  || !can_vec_perm_const_p (result_mode, op_mode, sel1, false))
-	       : !can_vec_perm_const_p (result_mode, op_mode, sel1, false)))
+	       ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true)
+		  || !can_vec_perm_const_p (result_mode, op_mode, sel1, true))
+	       : !can_vec_perm_const_p (result_mode, op_mode, sel1, true)))
 	 op0 = vec_perm_indices_to_tree (TREE_TYPE (@5), sel2);
      }
      (if (op0)
@@ -11793,18 +11789,15 @@ and,
      machine_mode result_mode = TYPE_MODE (type);
      machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1));
      int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
-     vec_perm_builder builder0;
-     vec_perm_builder builder1;
-     vec_perm_builder builder2 (nelts, nelts, 2);
+     vec_perm_indices sel0, sel1;
    }
-   (if (tree_to_vec_perm_builder (&builder0, @3)
-	&& tree_to_vec_perm_builder (&builder1, @4))
+   (if (tree_to_vec_perm_indices (&sel0, @1, @2, @3)
+        && tree_to_vec_perm_indices (&sel1, @5, @0, @4))
     (with
      {
-       vec_perm_indices sel0 (builder0, 2, nelts);
-       vec_perm_indices sel1 (builder1, 2, nelts);
        bool use_1 = false, use_2 = false;
 
+       vec_perm_builder builder2 (nelts, nelts, 2);
        for (int i = 0; i < nelts; i++)
          {
 	   if (known_lt ((poly_uint64)sel1[i], sel1.nelts_per_input ()))
@@ -11836,9 +11829,9 @@ and,
 	    number of VEC_PERM_EXPRs that can't be handled.  */
 	 if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)
 	     || (single_use (@0)
-		 ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false)
-		    || !can_vec_perm_const_p (result_mode, op_mode, sel1, false))
-		 : !can_vec_perm_const_p (result_mode, op_mode, sel1, false)))
+		 ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true)
+		    || !can_vec_perm_const_p (result_mode, op_mode, sel1, true))
+		 : !can_vec_perm_const_p (result_mode, op_mode, sel1, true)))
 	   op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2);
        }
        (if (op0)
@@ -11858,18 +11851,15 @@ and,
      machine_mode result_mode = TYPE_MODE (type);
      machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1));
      int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
-     vec_perm_builder builder0;
-     vec_perm_builder builder1;
-     vec_perm_builder builder2 (nelts, nelts, 2);
+     vec_perm_indices sel0, sel1;
    }
-   (if (tree_to_vec_perm_builder (&builder0, @3)
-	&& tree_to_vec_perm_builder (&builder1, @4))
+   (if (tree_to_vec_perm_indices (&sel0, @1, @2, @3)
+        && tree_to_vec_perm_indices (&sel1, @0, @5, @4))
     (with
      {
-       vec_perm_indices sel0 (builder0, 2, nelts);
-       vec_perm_indices sel1 (builder1, 2, nelts);
        bool use_1 = false, use_2 = false;
 
+       vec_perm_builder builder2 (nelts, nelts, 2);
        for (int i = 0; i < nelts; i++)
          {
 	   if (known_ge ((poly_uint64)sel1[i], sel1.nelts_per_input ()))
@@ -11900,9 +11890,9 @@ and,
 	    number of VEC_PERM_EXPRs that can't be handled.  */
 	 if (can_vec_perm_const_p (result_mode, op_mode, sel2, false)
 	     || (single_use (@0)
-		 ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false)
-		    || !can_vec_perm_const_p (result_mode, op_mode, sel1, false))
-		 : !can_vec_perm_const_p (result_mode, op_mode, sel1, false)))
+		 ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true)
+		    || !can_vec_perm_const_p (result_mode, op_mode, sel1, true))
+		 : !can_vec_perm_const_p (result_mode, op_mode, sel1, true)))
 	   op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2);
        }
        (if (op0)
diff --git a/gcc/testsuite/gcc.dg/torture/pr125875.c b/gcc/testsuite/gcc.dg/torture/pr125875.c
new file mode 100644
index 000000000000..0cccb190c734
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125875.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+typedef int16_t v4i16 __attribute__((vector_size(8)));
+v4i16 g7, g19;
+int64_t g16;
+_Bool f16_a0_c3, f16_a0_ob6;
+void f16_a0()
+{
+    int32_t ov10;
+    uint64_t __ov_tmp_g16 = __builtin_sub_overflow(0, 0, &__ov_tmp_g16);
+    g16 = __ov_tmp_g16;
+lbl_b1:
+    __builtin_mul_overflow(g16, g16, &ov10);
+    switch (ov10)
+    case 33:
+        goto lbl_sw_def57;
+lbl_sw_def15:
+    if (f16_a0_c3) goto lbl_b1;
+    g7 = __builtin_shufflevector(g7, g7, 4, 3, 4, 5);
+    f16_a0_ob6 = f16_a0;
+    g19 = g19 <= g19;
+lbl_bf43:
+    g19 = ~g19;
+    g7 = __builtin_shufflevector(g7, g19, 6, 7, 0, 1);
+lbl_sw_def57:
+    if (f16_a0_ob6) goto lbl_sw_def15;
+    goto lbl_bf43;
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.