diff mbox series

[7/8] ipa: Verify that const jump functions have corresponding value range

Message ID ri64j4lrk9a.fsf@virgil.suse.cz
State New
Headers show
Series None | expand

Commit Message

Martin Jambor Nov. 5, 2024, 11:29 a.m. UTC
Hi,

Because the simplified way of extracting value ranges from functions
does not look at scalar constants (as one of the versions had been
doing before) but instead rely on the value range within the jump
function already capturing the constant, I have added a verifier that
it is indeed so.  After the fixes in the previous patches, the
verifier passes bootstrap and testsuite.

The verifier is however a bit lenient when it comes to pranges.  When
a prange for an ADDR_EXPR of a DECL results in a non-NULL prange
adjusted with known alignment, but this is then converted to an
integer because that is what the compiled source does as is the case
for example in testcase gcc.c-torture/compile/pr71109.c.  While as
long as we track the address in a prange we do capture the
non-nullness:

  [prange] void (*<Txxxx>) (void) [1, +INF] MASK 0xfffffffffffffffe VALUE 0x0

when it the range is folded into an integer we get

  Value range: [irange] int [-INF, +INF] MASK 0xfffffffe VALUE 0x0

which can contain zero.  I have not looked into detail whether there
is anything we can do about this case or what it would be.

Bootstrapped and tested on x86_64-linux, the whole patch series has
additionally passed LTO and profiled-LTO bootstrap on the same platform
and a bootstrap and testsuite on ppc64-linux.  Aarch64-linux bootstrap
and testing is in progress.  OK for master is that passes too?

Thanks,

Martin


gcc/ChangeLog:

2024-11-04  Martin Jambor  <mjambor@suse.cz>

	* ipa-cp.cc (ipa_check_const_jf_vr): New function.
	(ipa_value_range_from_jfunc): Call it when checking and when
	dealing with a constant jump function.
	(propagate_vr_across_jump_function): Likewise.
---
 gcc/ipa-cp.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
diff mbox series

Patch

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 92dd2af19e0..f979fcd561d 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1682,6 +1682,51 @@  ipa_vr_operation_and_type_effects (vrange &dst_vr,
 					    dst_type, src_type);
 }
 
+/* Given a constant function JFUNC, check that VR also contains all that should
+   have been deduced at the call-site, PARAM_TYPE is the type of the
+   parameter.  */
+
+DEBUG_FUNCTION void
+ipa_check_const_jf_vr (ipa_jump_func *jfunc, const vrange &vr,
+		       tree param_type)
+{
+  if (vr.singleton_p ())
+    return;
+
+  tree val = ipa_get_jf_constant (jfunc);
+  if (!ipa_vr_supported_type_p (TREE_TYPE (val)))
+    return;
+
+  if (POINTER_TYPE_P (TREE_TYPE (val)))
+    {
+      /* TODO: Non-nullness is sometimes lost here.  */
+      if (!POINTER_TYPE_P (param_type))
+	return;
+      bool strict_overflow = false;
+      if (zerop (val))
+	{
+	  if (is_a <prange> (vr) && vr.zero_p ())
+	    return;
+	}
+      else if (tree_single_nonzero_warnv_p (val, &strict_overflow))
+	{
+	  tree zero = build_zero_cst (param_type);
+	  if (!vr.contains_p (zero))
+	    return;
+	}
+      else
+	return;
+    }
+  fprintf (stderr, "Value range has not picked up expected information "
+	   "for an IPA invariant:\n");
+  fprintf (stderr, "Jump function: ");
+  ipa_dump_jump_function (stderr, jfunc);
+  fprintf (stderr, "Value range: ");
+  vr.dump (stderr);
+  fprintf (stderr, "\n");
+  gcc_unreachable ();
+}
+
 /* Given a PASS_THROUGH jump function JFUNC that takes as its source SRC_VR of
    SRC_TYPE and the result needs to be DST_TYPE, if any value range information
    can be deduced at all, intersect VR with it.  */
@@ -1747,6 +1792,10 @@  ipa_value_range_from_jfunc (vrange &vr,
 				       *jfunc->m_vr,
 				       NOP_EXPR, parm_type,
 				       jfunc->m_vr->type ());
+
+  if (flag_checking && jfunc->type == IPA_JF_CONST)
+    ipa_check_const_jf_vr (jfunc, vr, parm_type);
+
   if (vr.singleton_p ())
     return;
 
@@ -2540,6 +2589,9 @@  propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
 				       param_type,
 				       jfunc->m_vr->type ());
 
+  if (flag_checking && jfunc->type == IPA_JF_CONST)
+    ipa_check_const_jf_vr (jfunc, vr, param_type);
+
   if (jfunc->type == IPA_JF_PASS_THROUGH)
     {
       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);