On Thu, Nov 14, 2024 at 10:05:05AM -0500, Andrew MacLeod wrote:
> The inferred range mechanism is also initialized using cfun, so again
> introducing a use of cfun shouldnt be an issue.
> 
> Something like this ought to work I think?

Thanks.

Seems to work in quick smoke testing and I've added a testcase to cover
that.

So, I'll bootstrap/regtest it next.

2024-11-14  Jakub Jelinek  <ja...@redhat.com>
            Andrew MacLeod  <amacl...@redhat.com>

        PR c/117023
        * gimple-range-infer.cc (gimple_infer_range::gimple_infer_range):
        Handle also nonnull_if_nonzero attributes.

        * gcc.dg/tree-ssa/pr78154-2.c: New test.

--- gcc/gimple-range-infer.cc.jj        2024-10-24 18:53:39.355071463 +0200
+++ gcc/gimple-range-infer.cc   2024-11-14 17:46:37.033477580 +0100
@@ -184,6 +184,29 @@ gimple_infer_range::gimple_infer_range (
            }
          BITMAP_FREE (nonnullargs);
        }
+      if (fntype)
+       for (tree attrs = TYPE_ATTRIBUTES (fntype);
+            (attrs = lookup_attribute ("nonnull_if_nonzero", attrs));
+            attrs = TREE_CHAIN (attrs))
+         {
+           tree args = TREE_VALUE (attrs);
+           unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
+           unsigned int idx2
+             = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
+           if (idx < gimple_call_num_args (s)
+               && idx2 < gimple_call_num_args (s))
+             {
+               tree arg = gimple_call_arg (s, idx);
+               tree arg2 = gimple_call_arg (s, idx2);
+               if (!POINTER_TYPE_P (TREE_TYPE (arg))
+                   || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
+                 continue;
+               value_range r (TREE_TYPE (arg2));
+               if (get_range_query (cfun)->range_of_expr (r, arg2, s)
+                   && !r.contains_p (build_zero_cst (TREE_TYPE (arg2))))
+                 add_nonzero (arg);
+             }
+         }
       // Fallthru and walk load/store ops now.
     }
 
--- gcc/testsuite/gcc.dg/tree-ssa/pr78154-2.c.jj        2024-11-14 
18:01:10.190001548 +0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr78154-2.c   2024-11-14 18:08:07.352017948 
+0100
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp-slim -fdelete-null-pointer-checks" } */
+/* { dg-skip-if "" { keeps_null_pointer_checks } } */
+
+void foo (void *, __SIZE_TYPE__) __attribute__((nonnull_if_nonzero (1, 2)));
+void baz (void);
+
+void
+bar (void *a, void *b, void *c, void *d, void *e, __SIZE_TYPE__ n)
+{
+  foo (a, 42);
+  if (a == 0)
+    __builtin_abort ();
+  if (n)
+    {
+      foo (b, n);
+      if (b == 0)
+       __builtin_abort ();
+    }
+  if (n >= 42)
+    {
+      foo (c, n - 10);
+      if (c == 0)
+       __builtin_abort ();
+    }
+  foo (d, 0);
+  if (d == 0)
+    baz ();
+  if (n != 42)
+    {
+      foo (e, n);
+      if (e == 0)
+       baz ();
+    }
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_abort" "evrp" } } */
+/* { dg-final { scan-tree-dump-times "baz \\\(" 2 "evrp" } } */

        Jakub

Reply via email to