From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2136) id D50FE3858D33; Thu, 27 Apr 2023 11:59:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D50FE3858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682596750; bh=r4PZKsluTjil6QFA4joFKpfJxs8z0s03YQD76Bh0vbk=; h=From:To:Subject:Date:From; b=lF/ekEVGgGvBEPloaWb1xITetFAzuGoOUYPdCsFLStC6STfuAJg8bsF4YvBB12uAd NWPSZJfpsXDCerJGr3t7WnNMFD8+lNLp/24/ZbPeYjXLx4IXa4PztEiw+WFb5pg10Z Dl1GAMWuX9cmqueJGmyGg2ecUoDEa7U69BRHWVL4= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Aldy Hernandez To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-298] Normalize addresses in IPA before calling range_op_handler [PR109639] X-Act-Checkin: gcc X-Git-Author: Aldy Hernandez X-Git-Refname: refs/heads/master X-Git-Oldrev: a82c6ab0aade4124e1903dda6f6f85c4c317fcec X-Git-Newrev: 2b8ac1df6493eb1789c7c4d9f3df280ef9cf0ac4 Message-Id: <20230427115910.D50FE3858D33@sourceware.org> Date: Thu, 27 Apr 2023 11:59:10 +0000 (GMT) List-Id: https://gcc.gnu.org/g:2b8ac1df6493eb1789c7c4d9f3df280ef9cf0ac4 commit r14-298-g2b8ac1df6493eb1789c7c4d9f3df280ef9cf0ac4 Author: Aldy Hernandez Date: Thu Apr 27 12:05:36 2023 +0200 Normalize addresses in IPA before calling range_op_handler [PR109639] The old legacy code would allow building ranges containing symbolics, even though the entire ranger ecosystem does not handle them. These were normalized into non-zero ranges by helper functions in VRP (range_fold_*_expr) before calling the ranger. The only users of these functions should have been legacy VRP, which is no more. However, a handful of users crept into IPA, even though these functions shouldn't never been called outside of VRP or vr-values. The issue here is that IPA is building a range of [&foo, &foo] and expecting range_fold_binary to normalize it to non-zero. Fixed by adding a helper function before calling the range_op handler. I think these covers the problematic ranges. If not, I'll come up with something more generalized that does not involve polluting irange::set with the normalization code. After all, this only involves a handful of IPA places. I've also added an assert in irange::set() making it easier to detect any possible fallout without having to drill deep into the setter. gcc/ChangeLog: PR tree-optimization/109639 * ipa-cp.cc (ipa_value_range_from_jfunc): Normalize range. (propagate_vr_across_jump_function): Same. * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same. * ipa-prop.h (ipa_range_set_and_normalize): New. * value-range.cc (irange::set): Assert min and max are INTEGER_CST. Diff: --- gcc/ipa-cp.cc | 8 ++++++-- gcc/ipa-fnsummary.cc | 10 +++++----- gcc/ipa-prop.h | 14 ++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr109639.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr109643.c | 18 ++++++++++++++++++ gcc/value-range.cc | 3 +++ 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 9ec86d77992..a5b45a8e6b9 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1963,9 +1963,11 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs, { value_range op_res, res; tree op = ipa_get_jf_pass_through_operand (jfunc); - value_range op_vr (op, op); + value_range op_vr; range_op_handler handler (operation, vr_type); + ipa_range_set_and_normalize (op_vr, op); + if (!handler || !op_res.supports_type_p (vr_type) || !handler.fold_range (op_res, vr_type, srcvr, op_vr)) @@ -2757,10 +2759,12 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, else if (!ipa_edge_within_scc (cs)) { tree op = ipa_get_jf_pass_through_operand (jfunc); - value_range op_vr (op, op); + value_range op_vr; value_range op_res,res; range_op_handler handler (operation, operand_type); + ipa_range_set_and_normalize (op_vr, op); + if (!handler || !op_res.supports_type_p (operand_type) || !handler.fold_range (op_res, operand_type, diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index 48093a8b623..b328bb8ce14 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -500,9 +500,11 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, } else if (!op->val[1]) { - value_range op0 (op->val[0], op->val[0]); + value_range op0; range_op_handler handler (op->code, op->type); + ipa_range_set_and_normalize (op0, op->val[0]); + if (!handler || !res.supports_type_p (op->type) || !handler.fold_range (res, op->type, @@ -518,12 +520,10 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, { value_range res; value_range val_vr; - if (TREE_CODE (c->val) == INTEGER_CST) - val_vr.set (c->val, c->val); - else - val_vr.set_varying (TREE_TYPE (c->val)); range_op_handler handler (c->code, boolean_type_node); + ipa_range_set_and_normalize (val_vr, c->val); + if (!handler || !res.supports_type_p (boolean_type_node) || !handler.fold_range (res, boolean_type_node, vr, val_vr)) diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 7eb5c8f44ea..93785a6a8e6 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -1201,4 +1201,18 @@ tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree, /* In ipa-cp.cc */ void ipa_cp_cc_finalize (void); +/* Set R to the range of [VAL, VAL] while normalizing addresses to + non-zero. */ + +inline void +ipa_range_set_and_normalize (irange &r, tree val) +{ + if (TREE_CODE (val) == INTEGER_CST) + r.set (val, val); + else if (TREE_CODE (val) == ADDR_EXPR) + r.set_nonzero (TREE_TYPE (val)); + else + r.set_varying (TREE_TYPE (val)); +} + #endif /* IPA_PROP_H */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109639.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109639.c new file mode 100644 index 00000000000..897e62cfad6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109639.c @@ -0,0 +1,20 @@ +// { dg-do compile } +// { dg-options "-O2" } + +extern int k[]; +int m; +int* j(); +void f(int *howto) { + short __trans_tmp_1; + long offset = howto - k; + __trans_tmp_1 = offset; + for (;;) { + if (howto == 0) + return; + if (__trans_tmp_1) { + howto = j(); + m = *howto; + } + f(howto); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109643.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109643.c new file mode 100644 index 00000000000..2bd6f25e9ef --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109643.c @@ -0,0 +1,18 @@ +// { dg-do compile } +// { dg-options "-O2" } + +int g_variant_type_info_basic_table[1]; +int g_variant_type_info_check__g_boolean_var_, g_variant_type_info_get_index; +int *g_variant_type_info_get_info; +int g_assertion_message_expr(); +void g_variant_type_info_check(int *info) { + int index = info - g_variant_type_info_basic_table; + if (index) + g_variant_type_info_check__g_boolean_var_ = 1; + g_assertion_message_expr(); +} +void g_variant_type_info_get() { + g_variant_type_info_get_info = + g_variant_type_info_basic_table + g_variant_type_info_get_index; + g_variant_type_info_check(g_variant_type_info_get_info); +} diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 1a3013be6fd..c11c3f58d2c 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1074,6 +1074,9 @@ irange::set (tree min, tree max, value_range_kind kind) return; } + gcc_checking_assert (TREE_CODE (min) == INTEGER_CST); + gcc_checking_assert (TREE_CODE (max) == INTEGER_CST); + if (TREE_OVERFLOW_P (min)) min = drop_tree_overflow (min); if (TREE_OVERFLOW_P (max))