]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/114203 - wrong CLZ niter computation
authorRichard Biener <rguenther@suse.de>
Mon, 4 Mar 2024 09:38:31 +0000 (10:38 +0100)
committerRichard Biener <rguenther@suse.de>
Mon, 4 Mar 2024 10:44:54 +0000 (11:44 +0100)
For precision less than int we apply the adjustment to make it defined
at zero after the adjustment to make it compute CLZ rather than CTZ.
That's wrong.

PR tree-optimization/114203
* tree-ssa-loop-niter.cc (build_cltz_expr): Apply CTZ->CLZ
adjustment before making the result defined at zero.

* gcc.dg/torture/pr114203.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr114203.c [new file with mode: 0644]
gcc/tree-ssa-loop-niter.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr114203.c b/gcc/testsuite/gcc.dg/torture/pr114203.c
new file mode 100644 (file)
index 0000000..0ef6279
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+int __attribute__((noipa))
+foo (unsigned char b)
+{
+  int c = 0;
+
+  while (b) {
+      b >>= 1;
+      c++;
+  }
+
+  return c;
+}
+
+int main()
+{
+  if (foo(0) != 0)
+    __builtin_abort ();
+  return 0;
+}
index 038e4331661f9206033e620ca5b38ce55909421a..c6d010f6d8948c3a0cf7ff890a0f18b675d4dba0 100644 (file)
@@ -2288,6 +2288,9 @@ build_cltz_expr (tree src, bool leading, bool define_at_zero)
        src = fold_convert (unsigned_type_node, src);
 
       call = build_call_expr (fn, 1, src);
+      if (leading && prec < i_prec)
+       call = fold_build2 (MINUS_EXPR, integer_type_node, call,
+                           build_int_cst (integer_type_node, i_prec - prec));
       if (define_at_zero)
        {
          tree is_zero = fold_build2 (NE_EXPR, boolean_type_node, src,
@@ -2295,10 +2298,6 @@ build_cltz_expr (tree src, bool leading, bool define_at_zero)
          call = fold_build3 (COND_EXPR, integer_type_node, is_zero, call,
                              build_int_cst (integer_type_node, prec));
        }
-
-      if (leading && prec < i_prec)
-       call = fold_build2 (MINUS_EXPR, integer_type_node, call,
-                           build_int_cst (integer_type_node, i_prec - prec));
     }
 
   return call;