]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-cp: Fold-convert values when necessary (PR 118138)
authorMartin Jambor <mjambor@suse.cz>
Sat, 4 Jan 2025 19:40:07 +0000 (20:40 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 10 Jan 2025 11:08:53 +0000 (12:08 +0100)
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  <mjambor@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  <mjambor@suse.cz>

PR ipa/118138
* gcc.dg/ipa/pr118138.c: New test.

gcc/ipa-cp.cc
gcc/testsuite/gcc.dg/ipa/pr118138.c [new file with mode: 0644]

index 294389fba4c7328b69ad56c5a0f0dbb888657986..d89324a0077577a7bc53311abc8cfb08ec8122c1 100644 (file)
@@ -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 (file)
index 0000000..5c94253
--- /dev/null
@@ -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;
+}