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 <mjam...@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 --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); -- 2.47.0