]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/123038 - FFS/CTZ pattern incompatible with reductions
authorRichard Biener <rguenther@suse.de>
Sun, 7 Dec 2025 10:30:48 +0000 (11:30 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 8 Dec 2025 09:19:11 +0000 (10:19 +0100)
The pattern ends up using the argument more than one time which
isn't supported.  When FFS directly maps to CTZ + 1 it works though.

PR tree-optimization/123038
* tree-vect-patterns.cc (vect_recog_ctz_ffs_pattern): Reject
pattern for reductions when the call argument is used multiple
times.

* gcc.dg/vect/pr123038.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr123038.c [new file with mode: 0644]
gcc/tree-vect-patterns.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr123038.c b/gcc/testsuite/gcc.dg/vect/pr123038.c
new file mode 100644 (file)
index 0000000..bca831f
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+unsigned char f(int b)
+{
+  for (int a = 0; a < 10; a += 1)
+    b = __builtin_ffs(b);
+  return b;
+}
index 555986b4fec50120ce2561bd4573b9530848d03d..af64cb84e418600a9fc90d3010ac6d0abbafc7a5 100644 (file)
@@ -1914,6 +1914,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
        && val_new == prec)
       || (ifnnew == IFN_POPCOUNT && ifn == IFN_CTZ))
     {
+      if (vect_is_reduction (stmt_vinfo))
+       return NULL;
+
       /* .CTZ (X) = PREC - .CLZ ((X - 1) & ~X)
         .CTZ (X) = .POPCOUNT ((X - 1) & ~X).  */
       if (ifnnew == IFN_CLZ)
@@ -1952,6 +1955,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
     }
   else if (ifnnew == IFN_CLZ)
     {
+      if (vect_is_reduction (stmt_vinfo))
+       return NULL;
+
       /* .CTZ (X) = (PREC - 1) - .CLZ (X & -X)
         .FFS (X) = PREC - .CLZ (X & -X).  */
       sub = prec - (ifn == IFN_CTZ);
@@ -1971,6 +1977,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
     }
   else if (ifnnew == IFN_POPCOUNT)
     {
+      if (vect_is_reduction (stmt_vinfo))
+       return NULL;
+
       /* .CTZ (X) = PREC - .POPCOUNT (X | -X)
         .FFS (X) = (PREC + 1) - .POPCOUNT (X | -X).  */
       sub = prec + (ifn == IFN_FFS);
@@ -1993,6 +2002,11 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
       /* .FFS (X) = .CTZ (X) + 1.  */
       add = 1;
       val_cmp++;
+
+      if (vect_is_reduction (stmt_vinfo)
+         && defined_at_zero
+         && (!defined_at_zero_new || val != val_cmp))
+       return NULL;
     }
 
   /* Create B = .IFNNEW (A).  */