[gcc r14-10280] fold-const: Fix up CLZ handling in tree_call_nonnegative_warnv_p [PR115337]

Jakub Jelinek jakub@gcc.gnu.org
Tue Jun 4 14:26:42 GMT 2024


https://gcc.gnu.org/g:a88e13bd7e0f50011e7f7f6e05c6f5e2a031143c

commit r14-10280-ga88e13bd7e0f50011e7f7f6e05c6f5e2a031143c
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Jun 4 15:49:41 2024 +0200

    fold-const: Fix up CLZ handling in tree_call_nonnegative_warnv_p [PR115337]
    
    The function currently incorrectly assumes all the __builtin_clz* and .CLZ
    calls have non-negative result.  That is the case of the former which is UB
    on zero and has [0, prec-1] return value otherwise, and is the case of the
    single argument .CLZ as well (again, UB on zero), but for two argument
    .CLZ is the case only if the second argument is also nonnegative (or if we
    know the argument can't be zero, but let's do that just in the ranger IMHO).
    
    The following patch does that.
    
    2024-06-04  Jakub Jelinek  <jakub@redhat.com>
    
            PR tree-optimization/115337
            * fold-const.cc (tree_call_nonnegative_warnv_p) <CASE_CFN_CLZ>:
            If arg1 is non-NULL, RECURSE on it, otherwise return true.
    
            * gcc.dg/bitint-106.c: New test.
    
    (cherry picked from commit b82a816000791e7a286c7836b3a473ec0e2a577b)

Diff:
---
 gcc/fold-const.cc                 |  6 +++++-
 gcc/testsuite/gcc.dg/bitint-106.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 7b268964acc..f496b3436df 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -15241,7 +15241,6 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
     CASE_CFN_FFS:
     CASE_CFN_PARITY:
     CASE_CFN_POPCOUNT:
-    CASE_CFN_CLZ:
     CASE_CFN_CLRSB:
     case CFN_BUILT_IN_BSWAP16:
     case CFN_BUILT_IN_BSWAP32:
@@ -15250,6 +15249,11 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
       /* Always true.  */
       return true;
 
+    CASE_CFN_CLZ:
+      if (arg1)
+	return RECURSE (arg1);
+      return true;
+
     CASE_CFN_SQRT:
     CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
diff --git a/gcc/testsuite/gcc.dg/bitint-106.c b/gcc/testsuite/gcc.dg/bitint-106.c
new file mode 100644
index 00000000000..a36e8836690
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-106.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/115337 */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-O2" } */
+
+#if __BITINT_MAXWIDTH__ >= 129
+#define N 128
+#else
+#define N 63
+#endif
+
+_BitInt (N) g;
+int c;
+
+void
+foo (unsigned _BitInt (N + 1) z, _BitInt (N) *ret)
+{
+  c = __builtin_stdc_first_leading_one (z << N);
+  _BitInt (N) y = *(_BitInt (N) *) __builtin_memset (&g, c, 5);
+  *ret = y;
+}
+
+int
+main ()
+{
+  _BitInt (N) x;
+  foo (0, &x);
+  if (c || g || x)
+    __builtin_abort ();
+}


More information about the Gcc-cvs mailing list