https://gcc.gnu.org/g:d019ab4f115caab48316c185c007765719e93052

commit r15-6769-gd019ab4f115caab48316c185c007765719e93052
Author: Martin Jambor <mjam...@suse.cz>
Date:   Sat Jan 4 20:40:07 2025 +0100

    ipa-cp: Fold-convert values when necessary (PR 118138)
    
    PR 118138 and quite a few duplicates that it has acquired in a short
    time show that even though we are careful to make sure we do not loose
    any bits when newly allowing type conversions in jump-functions, we
    still need to perform the fold conversions during IPA constant
    propagation and not just at the end in order to properly perform
    sign-extensions or zero-extensions as appropriate.
    
    This patch does just that, changing a safety predicate we already use
    at the appropriate places to return the necessary type.
    
    gcc/ChangeLog:
    
    2025-01-03  Martin Jambor  <mjam...@suse.cz>
    
            PR ipa/118138
            * ipa-cp.cc (ipacp_value_safe_for_type): Return the appropriate
            type instead of a bool, accept NULL_TREE VALUEs.
            (propagate_vals_across_arith_jfunc): Use the new returned value of
            ipacp_value_safe_for_type.
            (propagate_vals_across_ancestor): Likewise.
            (propagate_scalar_across_jump_function): Likewise.
    
    gcc/testsuite/ChangeLog:
    
    2025-01-03  Martin Jambor  <mjam...@suse.cz>
    
            PR ipa/118138
            * gcc.dg/ipa/pr118138.c: New test.

Diff:
---
 gcc/ipa-cp.cc                       | 33 +++++++++++++++++++--------------
 gcc/testsuite/gcc.dg/ipa/pr118138.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 294389fba4c7..d89324a00775 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1448,19 +1448,23 @@ initialize_node_lattices (struct cgraph_node *node)
       }
 }
 
-/* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
-   PARAM_TYPE.  */
+/* Return VALUE if it is NULL_TREE or if it can be directly safely IPA-CP
+   propagated to a parameter of type PARAM_TYPE, or return a fold-converted
+   VALUE to PARAM_TYPE if that is possible.  Return NULL_TREE otherwise.  */
 
-static bool
+static tree
 ipacp_value_safe_for_type (tree param_type, tree value)
 {
+  if (!value)
+    return NULL_TREE;
   tree val_type = TREE_TYPE (value);
   if (param_type == val_type
-      || useless_type_conversion_p (param_type, val_type)
-      || fold_convertible_p (param_type, value))
-    return true;
+      || useless_type_conversion_p (param_type, val_type))
+    return value;
+  if (fold_convertible_p (param_type, value))
+    return fold_convert (param_type, value);
   else
-    return false;
+    return NULL_TREE;
 }
 
 /* Return the result of a (possibly arithmetic) operation on the constant
@@ -2210,8 +2214,8 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
            {
              tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
                                                     src_val, res_type);
-             if (!cstval
-                 || !ipacp_value_safe_for_type (res_type, cstval))
+             cstval = ipacp_value_safe_for_type (res_type, cstval);
+             if (!cstval)
                break;
 
              ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
@@ -2235,8 +2239,8 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
 
        tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
                                               src_val, res_type);
-       if (cstval
-           && ipacp_value_safe_for_type (res_type, cstval))
+       cstval = ipacp_value_safe_for_type (res_type, cstval);
+       if (cstval)
          ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
                                      src_offset);
        else
@@ -2284,8 +2288,8 @@ propagate_vals_across_ancestor (struct cgraph_edge *cs,
   for (src_val = src_lat->values; src_val; src_val = src_val->next)
     {
       tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
-
-      if (t && ipacp_value_safe_for_type (param_type, t))
+      t = ipacp_value_safe_for_type (param_type, t);
+      if (t)
        ret |= dest_lat->add_value (t, cs, src_val, src_idx);
       else
        ret |= dest_lat->set_contains_variable ();
@@ -2310,7 +2314,8 @@ propagate_scalar_across_jump_function (struct cgraph_edge 
*cs,
   if (jfunc->type == IPA_JF_CONST)
     {
       tree val = ipa_get_jf_constant (jfunc);
-      if (ipacp_value_safe_for_type (param_type, val))
+      val = ipacp_value_safe_for_type (param_type, val);
+      if (val)
        return dest_lat->add_value (val, cs, NULL, 0);
       else
        return dest_lat->set_contains_variable ();
diff --git a/gcc/testsuite/gcc.dg/ipa/pr118138.c 
b/gcc/testsuite/gcc.dg/ipa/pr118138.c
new file mode 100644
index 000000000000..5c94253f58b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr118138.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-inline" } */
+
+unsigned a = -1;
+int b, e, c = 1;
+unsigned long d;
+
+long f(long g) {
+  return g;
+}
+
+static long h(unsigned g) {
+  for (; b < 8; b++)
+    d = f(g);
+  e = a < d;
+  if (e)
+    c = 0;
+  return 0;
+}
+
+static void i(short g) {
+  h(g);
+}
+
+int main() {
+  i(-1);
+  if (c != 1)
+    __builtin_abort();
+  return 0;
+}

Reply via email to