aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2024-12-17 11:17:14 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2024-12-17 11:18:11 +0100
commit1eb41aeb49a491f5b18d160074e651a76afc655a (patch)
tree5be5d22bb9e5bbf7230746d5f222ad00af235d26
parent96fb71883d438bdb241fdf9c7d12f945c5ba0c7f (diff)
downloadgcc-1eb41aeb49a491f5b18d160074e651a76afc655a.zip
gcc-1eb41aeb49a491f5b18d160074e651a76afc655a.tar.gz
gcc-1eb41aeb49a491f5b18d160074e651a76afc655a.tar.bz2
ipa: Better value ranges for pointer integer constants
When looking into cases where we know an actual argument of a call is a constant but we don't generate a singleton value-range for the jump function, I found out that the special handling of pointer constants does not work well for constant zero pointer values. In fact the code only attempts to see if it can figure out that an argument is not zero and if it can figure out any alignment information. With this patch, we try to use the value_range that ranger can give us in the jump function if we can and we query ranger for all kinds of arguments, not just SSA_NAMES (and so also pointer integer constants). If we cannot figure out a useful range we fall back again on figuring out non-NULLness with tree_single_nonzero_warnv_p. With this patch, we generate [prange] struct S * [0, 0] MASK 0x0 VALUE 0x0 instead of for example: [prange] struct S * [0, +INF] MASK 0xfffffffffffffff0 VALUE 0x0 for a zero constant passed in a call. If you are wondering why we check whether the value range obtained from range_of_expr can be undefined, even when the function returns true, that is because that can apparently happen fro default-definition SSA_NAMEs. gcc/ChangeLog: 2024-11-15 Martin Jambor <mjambor@suse.cz> * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Try harder to use the value range obtained from ranger for pointer values.
-rw-r--r--gcc/ipa-prop.cc35
1 files changed, 16 insertions, 19 deletions
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index ae309ec..f0b915b 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2396,28 +2396,27 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
value_range vr (TREE_TYPE (arg));
if (POINTER_TYPE_P (TREE_TYPE (arg)))
{
- bool addr_nonzero = false;
- bool strict_overflow = false;
-
- if (TREE_CODE (arg) == SSA_NAME
- && param_type
- && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
- && vr.nonzero_p ())
- addr_nonzero = true;
- else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
- addr_nonzero = true;
-
- if (addr_nonzero)
- vr.set_nonzero (TREE_TYPE (arg));
-
+ if (!get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
+ || vr.varying_p ()
+ || vr.undefined_p ())
+ {
+ bool strict_overflow = false;
+ if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
+ vr.set_nonzero (TREE_TYPE (arg));
+ else
+ vr.set_varying (TREE_TYPE (arg));
+ }
+ gcc_assert (!vr.undefined_p ());
unsigned HOST_WIDE_INT bitpos;
- unsigned align, prec = TYPE_PRECISION (TREE_TYPE (arg));
+ unsigned align = BITS_PER_UNIT;
- get_pointer_alignment_1 (arg, &align, &bitpos);
+ if (!vr.singleton_p ())
+ get_pointer_alignment_1 (arg, &align, &bitpos);
if (align > BITS_PER_UNIT
&& opt_for_fn (cs->caller->decl, flag_ipa_bit_cp))
{
+ unsigned prec = TYPE_PRECISION (TREE_TYPE (arg));
wide_int mask
= wi::bit_and_not (wi::mask (prec, false, prec),
wide_int::from (align / BITS_PER_UNIT - 1,
@@ -2425,12 +2424,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
wide_int value = wide_int::from (bitpos / BITS_PER_UNIT, prec,
UNSIGNED);
irange_bitmask bm (value, mask);
- if (!addr_nonzero)
- vr.set_varying (TREE_TYPE (arg));
vr.update_bitmask (bm);
ipa_set_jfunc_vr (jfunc, vr);
}
- else if (addr_nonzero)
+ else if (!vr.varying_p ())
ipa_set_jfunc_vr (jfunc, vr);
else
gcc_assert (!jfunc->m_vr);