+2016-10-18 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ * tree-ssa-alias.h (pt_solution_singleton_or_null_p): Renamed from
+ pt_solution_singleton_p.
+ * tree-ssa-ccp.c (fold_builtin_alloca_with_align): Use renamed
+ pt_solution_singleton_or_null_p from pt_solution_singleton_p.
+ * tree-ssa-structalias.c (find_what_p_points_to): Preserve
+ pointer nonnull computed by VRP.
+ Also Conservatively set pt.null to 1.
+ (pt_solution_reset): Conservatively set pt.null to 1.
+ (pt_solution_singleton_or_null_p): Renamed from
+ pt_solution_singleton_p.
+ * tree-ssanames.h (set_ptr_nonnull): Declare.
+ (get_ptr_nonnull): Likewise.
+ * tree-ssanames.c (set_ptr_nonnull): New.
+ (get_ptr_nonnull): Likewise.
+ * tree-vrp.c (vrp_finalize): Set ptr that are nonnull.
+ (evrp_dom_walker::before_dom_children): Likewise.
+
2016-10-17 Eric Botcazou <ebotcazou@adacore.com>
* config/i386/i386.h (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Move to...
+2016-10-18 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ * gcc.dg/torture/pr39074-2.c: Adjust testcase.
+ * gcc.dg/torture/pr39074.c: Likewise.
+
2016-10-17 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/Wtrampolines.c: XFAIL warning on ia64-*-* and powerpc64-*-*.
}
/* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */
-/* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
}
/* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */
-/* { dg-final { scan-tree-dump "y.._., points-to vars: { D..... }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
/* In tree-ssa-structalias.c */
extern unsigned int compute_may_aliases (void);
extern bool pt_solution_empty_p (struct pt_solution *);
-extern bool pt_solution_singleton_p (struct pt_solution *, unsigned *);
+extern bool pt_solution_singleton_or_null_p (struct pt_solution *, unsigned *);
extern bool pt_solution_includes_global (struct pt_solution *);
extern bool pt_solution_includes (struct pt_solution *, const_tree);
extern bool pt_solutions_intersect (struct pt_solution *, struct pt_solution *);
{
bool singleton_p;
unsigned uid;
- singleton_p = pt_solution_singleton_p (&pi->pt, &uid);
+ singleton_p = pt_solution_singleton_or_null_p (&pi->pt, &uid);
gcc_assert (singleton_p);
SET_DECL_PT_UID (var, uid);
}
struct ptr_info_def *pi;
tree lookup_p = p;
varinfo_t vi;
+ bool nonnull = get_ptr_nonnull (p);
/* For parameters, get at the points-to set for the actual parm
decl. */
pi = get_ptr_info (p);
pi->pt = find_what_var_points_to (fndecl, vi);
+ /* Conservatively set to NULL from PTA (to true). */
+ pi->pt.null = 1;
+ /* Preserve pointer nonnull computed by VRP. See get_ptr_nonnull
+ in gcc/tree-ssaname.c for more information. */
+ if (nonnull)
+ set_ptr_nonnull (p);
}
{
memset (pt, 0, sizeof (struct pt_solution));
pt->anything = true;
+ pt->null = true;
}
/* Set the points-to solution *PT to point only to the variables
return the var uid in *UID. */
bool
-pt_solution_singleton_p (struct pt_solution *pt, unsigned *uid)
+pt_solution_singleton_or_null_p (struct pt_solution *pt, unsigned *uid)
{
if (pt->anything || pt->nonlocal || pt->escaped || pt->ipa_escaped
- || pt->null || pt->vars == NULL
+ || pt->vars == NULL
|| !bitmap_single_bit_set_p (pt->vars))
return false;
return SSA_NAME_RANGE_TYPE (name);
}
+/* Set nonnull attribute to pointer NAME. */
+
+void
+set_ptr_nonnull (tree name)
+{
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
+ struct ptr_info_def *pi = get_ptr_info (name);
+ pi->pt.null = 0;
+}
+
+/* Return nonnull attribute of pointer NAME. */
+bool
+get_ptr_nonnull (const_tree name)
+{
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
+ if (pi == NULL)
+ return false;
+ /* TODO Now pt->null is conservatively set to true in PTA
+ analysis. vrp is the only pass (including ipa-vrp)
+ that clears pt.null via set_ptr_nonull when it knows
+ for sure. PTA will preserves the pt.null value set by VRP.
+
+ When PTA analysis is improved, pt.anything, pt.nonlocal
+ and pt.escaped may also has to be considered before
+ deciding that pointer cannot point to NULL. */
+ return !pi->pt.null;
+}
+
/* Change non-zero bits bitmask of NAME. */
void
extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
unsigned int);
extern struct ptr_info_def *get_ptr_info (tree);
+extern void set_ptr_nonnull (tree);
+extern bool get_ptr_nonnull (const_tree);
extern tree copy_ssa_name_fn (struct function *, tree, gimple *);
extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
{
tree name = ssa_name (i);
- if (!name
- || POINTER_TYPE_P (TREE_TYPE (name))
- || (vr_value[i]->type == VR_VARYING)
- || (vr_value[i]->type == VR_UNDEFINED))
- continue;
+ if (!name
+ || (vr_value[i]->type == VR_VARYING)
+ || (vr_value[i]->type == VR_UNDEFINED)
+ || (TREE_CODE (vr_value[i]->min) != INTEGER_CST)
+ || (TREE_CODE (vr_value[i]->max) != INTEGER_CST))
+ continue;
- if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
- && (TREE_CODE (vr_value[i]->max) == INTEGER_CST)
- && (vr_value[i]->type == VR_RANGE
- || vr_value[i]->type == VR_ANTI_RANGE))
- set_range_info (name, vr_value[i]->type, vr_value[i]->min,
- vr_value[i]->max);
+ if (POINTER_TYPE_P (TREE_TYPE (name))
+ && ((vr_value[i]->type == VR_RANGE
+ && range_includes_zero_p (vr_value[i]->min,
+ vr_value[i]->max) == 0)
+ || (vr_value[i]->type == VR_ANTI_RANGE
+ && range_includes_zero_p (vr_value[i]->min,
+ vr_value[i]->max) == 1)))
+ set_ptr_nonnull (name);
+ else if (!POINTER_TYPE_P (TREE_TYPE (name)))
+ set_range_info (name, vr_value[i]->type, vr_value[i]->min,
+ vr_value[i]->max);
}
substitute_and_fold (op_with_constant_singleton_value_range,
def_operand_p def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
/* Set the SSA with the value range. */
if (def_p
- && TREE_CODE (DEF_FROM_PTR (def_p)) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p))))
+ && TREE_CODE (DEF_FROM_PTR (def_p)) == SSA_NAME)
{
tree def = DEF_FROM_PTR (def_p);
value_range *vr = get_value_range (def);
- if ((vr->type == VR_RANGE
- || vr->type == VR_ANTI_RANGE)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p)))
+ && (vr->type == VR_RANGE
+ || vr->type == VR_ANTI_RANGE)
&& (TREE_CODE (vr->min) == INTEGER_CST)
&& (TREE_CODE (vr->max) == INTEGER_CST))
set_range_info (def, vr->type, vr->min, vr->max);
+ else if (POINTER_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p)))
+ && ((vr->type == VR_RANGE
+ && range_includes_zero_p (vr->min,
+ vr->max) == 0)
+ || (vr->type == VR_ANTI_RANGE
+ && range_includes_zero_p (vr->min,
+ vr->max) == 1)))
+ set_ptr_nonnull (def);
}
}
else