diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86f48345cbe..1c603468525 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-10-18 Kugan Vivekanandarajah + + * ipa-prop.c (ipa_compute_jump_functions_for_edge): Set value range + for pointer type too. + (ipcp_update_vr): set_ptr_nonnull for pointer. + 2016-10-18 Kugan Vivekanandarajah * tree-ssa-alias.h (pt_solution_singleton_or_null_p): Renamed from diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index a1d761900f1..353b63821a9 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1668,7 +1668,22 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, useful_context = true; } - if (!POINTER_TYPE_P (TREE_TYPE (arg))) + if (POINTER_TYPE_P (TREE_TYPE (arg))) + { + if (TREE_CODE (arg) == SSA_NAME + && param_type + && get_ptr_nonnull (arg)) + { + jfunc->vr_known = true; + jfunc->m_vr.type = VR_ANTI_RANGE; + jfunc->m_vr.min = build_int_cst (TREE_TYPE (arg), 0); + jfunc->m_vr.max = build_int_cst (TREE_TYPE (arg), 0); + jfunc->m_vr.equiv = NULL; + } + else + gcc_assert (!jfunc->vr_known); + } + else { wide_int min, max; value_range_type type; @@ -5602,27 +5617,37 @@ ipcp_update_vr (struct cgraph_node *node) continue; if (vr[i].known - && INTEGRAL_TYPE_P (TREE_TYPE (ddef)) - && !POINTER_TYPE_P (TREE_TYPE (ddef)) && (vr[i].type == VR_RANGE || vr[i].type == VR_ANTI_RANGE)) { tree type = TREE_TYPE (ddef); unsigned prec = TYPE_PRECISION (type); - if (dump_file) + if (INTEGRAL_TYPE_P (TREE_TYPE (ddef))) { - fprintf (dump_file, "Setting value range of param %u ", i); - fprintf (dump_file, "%s[", - (vr[i].type == VR_ANTI_RANGE) ? "~" : ""); - print_decs (vr[i].min, dump_file); - fprintf (dump_file, ", "); - print_decs (vr[i].max, dump_file); - fprintf (dump_file, "]\n"); + if (dump_file) + { + fprintf (dump_file, "Setting value range of param %u ", i); + fprintf (dump_file, "%s[", + (vr[i].type == VR_ANTI_RANGE) ? "~" : ""); + print_decs (vr[i].min, dump_file); + fprintf (dump_file, ", "); + print_decs (vr[i].max, dump_file); + fprintf (dump_file, "]\n"); + } + set_range_info (ddef, vr[i].type, + wide_int_storage::from (vr[i].min, prec, + TYPE_SIGN (type)), + wide_int_storage::from (vr[i].max, prec, + TYPE_SIGN (type))); + } + else if (POINTER_TYPE_P (TREE_TYPE (ddef)) + && vr[i].type == VR_ANTI_RANGE + && wi::eq_p (vr[i].min, 0) + && wi::eq_p (vr[i].max, 0)) + { + if (dump_file) + fprintf (dump_file, "Setting nonnull for %u\n", i); + set_ptr_nonnull (ddef); } - set_range_info (ddef, vr[i].type, - wide_int_storage::from (vr[i].min, prec, - TYPE_SIGN (type)), - wide_int_storage::from (vr[i].max, prec, - TYPE_SIGN (type))); } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d59844272ce..94048db18e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-10-18 Kugan Vivekanandarajah + + * gcc.dg/ipa/vrp4.c: New test. + 2016-10-18 Kugan Vivekanandarajah * gcc.dg/torture/pr39074-2.c: Adjust testcase. diff --git a/gcc/testsuite/gcc.dg/ipa/vrp4.c b/gcc/testsuite/gcc.dg/ipa/vrp4.c new file mode 100644 index 00000000000..d7e1f26d23b --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/vrp4.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-cp-details" } */ + +static __attribute__((noinline, noclone)) +int foo (int *p) +{ + if (!p) + return 0; + *p = 1; +} + +struct st +{ + int a; + int b; +}; + +int bar (struct st *s) +{ + + if (!s) + return 0; + foo (&s->a); + foo (&s->b); +} + +/* { dg-final { scan-ipa-dump "Setting nonnull for 0" "cp" } } */