When computing arithmetic pass-through jump functions for parameters themselves (aka scalars), we allow a data preserving type conversion in between the call and the gimple calculation that is represented by the jump function. When doing the same for values passed in aggregates or passed by reference, we skip a chain of simple assignments but so far do not allow a type conversion between the corresponding store to memory and the gimple calculations even though now we do stream both types and so can represent the conversion. This patch simply allows a type conversion to occur also in this case.
Bootstrapped and tested and LTO bootstrapped on x86_64-linux but my plan is to propose this only in the next stage 1. Thanks, Martin gcc/ChangeLog: 2025-03-24 Martin Jambor <mjam...@suse.cz> * ipa-prop.cc (is_a_safe_conversion_stmt_p): New function. (skip_a_safe_conversion_op): Moved up in the file. Moved most of the functionality to is_a_safe_conversion_stmt_p. (analyze_agg_content_value): Allow skipping a data preserving conversion. --- gcc/ipa-prop.cc | 102 ++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 59ef00db823..edf644ec52e 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -1865,6 +1865,59 @@ build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list, } } +/* Return true if DEF is a statement that performs a simple type conversion + from an integer type to another integer type which is known to be able to + represent the values the operand of the conversion can hold. */ + +static bool +is_a_safe_conversion_stmt_p (gimple *def) +{ + if (!is_gimple_assign (def)) + return false; + + tree lhs = gimple_assign_lhs (def); + if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)) + || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)) + || !INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def)))) + return false; + + tree rhs1 = gimple_assign_rhs1 (def); + if (TYPE_PRECISION (TREE_TYPE (lhs)) + >= TYPE_PRECISION (TREE_TYPE (rhs1))) + return true; + + value_range vr (TREE_TYPE (rhs1)); + if (!get_range_query (cfun)->range_of_expr (vr, rhs1, def) + || vr.undefined_p ()) + return false; + + irange &ir = as_a <irange> (vr); + if (range_fits_type_p (&ir, TYPE_PRECISION (TREE_TYPE (lhs)), + TYPE_SIGN (TREE_TYPE (lhs)))) + return true; + + return false; +} + +/* If T is an SSA_NAME that is the result of a simple type conversion statement + from an integer type to another integer type which is known to be able to + represent the values the operand of the conversion can hold, return the + operand of that conversion, otherwise return T. */ + +static tree +skip_a_safe_conversion_op (tree t) +{ + if (TREE_CODE (t) != SSA_NAME + || SSA_NAME_IS_DEFAULT_DEF (t)) + return t; + + gimple *def = SSA_NAME_DEF_STMT (t); + if (is_a_safe_conversion_stmt_p (def)) + return gimple_assign_rhs1 (def); + else + return t; +} + /* Given an assignment statement STMT, try to collect information into AGG_VALUE that will be used to construct jump function for RHS of the assignment, from which content value of an aggregate part comes. @@ -1913,8 +1966,18 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi, return; /* Skip SSA copies. */ - while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS) + bool skipped_conversion = false; + while (true) { + if (gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS) + { + if (!skipped_conversion + && is_a_safe_conversion_stmt_p (stmt)) + skipped_conversion = true; + else + break; + } + if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1)) break; @@ -2360,43 +2423,6 @@ ipa_get_range_from_ip_invariant (vrange &r, tree val, cgraph_node *context_node) r.set (val, val); } -/* If T is an SSA_NAME that is the result of a simple type conversion statement - from an integer type to another integer type which is known to be able to - represent the values the operand of the conversion can hold, return the - operand of that conversion, otherwise return T. */ - -static tree -skip_a_safe_conversion_op (tree t) -{ - if (TREE_CODE (t) != SSA_NAME - || SSA_NAME_IS_DEFAULT_DEF (t)) - return t; - - gimple *def = SSA_NAME_DEF_STMT (t); - if (!is_gimple_assign (def) - || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)) - || !INTEGRAL_TYPE_P (TREE_TYPE (t)) - || !INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def)))) - return t; - - tree rhs1 = gimple_assign_rhs1 (def); - if (TYPE_PRECISION (TREE_TYPE (t)) - >= TYPE_PRECISION (TREE_TYPE (rhs1))) - return gimple_assign_rhs1 (def); - - value_range vr (TREE_TYPE (rhs1)); - if (!get_range_query (cfun)->range_of_expr (vr, rhs1, def) - || vr.undefined_p ()) - return t; - - irange &ir = as_a <irange> (vr); - if (range_fits_type_p (&ir, TYPE_PRECISION (TREE_TYPE (t)), - TYPE_SIGN (TREE_TYPE (t)))) - return gimple_assign_rhs1 (def); - - return t; -} - /* Compute jump function for all arguments of callsite CS and insert the information in the jump_functions array in the ipa_edge_args corresponding to this callsite. */ -- 2.48.1