aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2025-01-04 20:40:07 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2025-01-10 12:08:53 +0100
commitd019ab4f115caab48316c185c007765719e93052 (patch)
tree28ff4082978828f99c75a82befbe96a8c15af3ab /gcc
parent86175a64f167e3b1701132fa1684d76230054c36 (diff)
downloadgcc-d019ab4f115caab48316c185c007765719e93052.zip
gcc-d019ab4f115caab48316c185c007765719e93052.tar.gz
gcc-d019ab4f115caab48316c185c007765719e93052.tar.bz2
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 <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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-cp.cc33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr118138.c30
2 files changed, 49 insertions, 14 deletions
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 294389f..d89324a 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 0000000..5c94253
--- /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;
+}