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

Reply via email to