On 11/14/24 05:26, Jakub Jelinek wrote:
Hi!
On top of the
https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668554.html
patch which introduces the nonnull_if_nonzero attribute (because
C2Y is allowing NULL arguments on various calls like memcpy, memset,
strncpy etc. as long as the count is 0) the following patch adds just
limited handling of the attribute in the ranger, in particular infers
nonnull for the pointer argument referenced in first argument of the
attribute if the second argument is a non-zero INTEGER_CST
(integer_nonzerop).
Ideally (as the FIXME says) I'd like to query arg2 range and check if
it doesn't contain zero, but am not sure such queries are possible from
gimple_infer_range (and if it is possible whether one can just query
the currently recorded range for it or if one can call something that
will try to compute the range by walking the def stmts etc.).
In theory, there is no reason we cant just call the current range
query. I dont think any cycles get introduced because the utilizing
pass must invoke the register_inferred_range routine in order to get
another call to infer_range(). And thats only done immediately after
folding statements, so the arguments should already be calculated anyway.
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?
diff --git a/gcc/gimple-range-infer.cc b/gcc/gimple-range-infer.cc
index 893f5cd41a7..407e47135a8 100644
--- a/gcc/gimple-range-infer.cc
+++ b/gcc/gimple-range-infer.cc
@@ -202,7 +202,9 @@ gimple_infer_range::gimple_infer_range (gimple *s,
bool use_rangeops)
|| !INTEGRAL_TYPE_P (TREE_TYPE (arg2))
|| integer_zerop (arg2))
continue;
- if (integer_nonzerop (arg2))
+ 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);
// FIXME: Can one query here whether arg2 has
// nonzero range if it is a SSA_NAME?
The rest fo the patch is OK btw.
Ok for trunk?
Could you handle as a follow-up the range querying if it is possible?
As for useful testcase, with the patch I'm going to post next
e.g. gcc.dg/tree-ssa/pr78154.c if the calls use d as destination (not dn)
and count that will have a range which doesn't include 0 and isn't constant.
2024-11-14 Jakub Jelinek <ja...@redhat.com>
PR c/117023
* gimple-range-infer.cc (gimple_infer_range::gimple_infer_range):
Handle also nonnull_if_nonzero attributes.
--- gcc/gimple-range-infer.cc.jj 2024-10-24 22:56:14.224156849 +0200
+++ gcc/gimple-range-infer.cc 2024-11-14 10:24:58.751315670 +0100
@@ -184,6 +184,30 @@ 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))
+ || integer_zerop (arg2))
+ continue;
+ if (integer_nonzerop (arg2))
+ add_nonzero (arg);
+ // FIXME: Can one query here whether arg2 has
+ // nonzero range if it is a SSA_NAME?
+ }
+ }
// Fallthru and walk load/store ops now.
}
Jakub