+2005-05-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/21294
+ * tree-vrp.c (vrp_expr_computes_nonzero): New.
+ (extract_range_from_expr): Call vrp_expr_computes_nonzero.
+
2005-05-02 Janis Johnson <janis187@us.ibm.com>
PR 19985
+2005-05-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/21294
+ * gcc.dg/tree-ssa/pr21294.c: New.
+
2005-05-02 Paolo Bonzini <bonzini@gnu.org>
* gcc.dg/altivec-3.c (vec_store): Do not use the old
--- /dev/null
+/* PR tree-optimization/21294
+ VRP did not notice that an address of the form &p->i is nonnull
+ when p is known to be nonnull. In this testcase, noticing that
+ allows us to eliminate the second "if" statement. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp-details" } */
+
+struct f {
+ int i;
+};
+
+int
+foo (struct f *p)
+{
+ if (p != 0)
+ if (&p->i != 0)
+ return 123;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Folding predicate" 1 "vrp"} } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
}
+/* Like expr_computes_nonzero, but this function uses value ranges
+ obtained so far. */
+
+static bool
+vrp_expr_computes_nonzero (tree expr)
+{
+ if (expr_computes_nonzero (expr))
+ return true;
+
+ /* If we have an expression of the form &X->a, then the expression
+ is nonnull if X is nonnull. */
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree base = get_base_address (TREE_OPERAND (expr, 0));
+
+ if (base != NULL_TREE
+ && TREE_CODE (base) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+ {
+ value_range *vr = get_value_range (TREE_OPERAND (base, 0));
+ if (range_is_nonnull (vr))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
/* Extract range information from a unary expression EXPR based on
the range of its operand and the expression code. */
extract_range_from_binary_expr (vr, expr);
else if (TREE_CODE_CLASS (code) == tcc_unary)
extract_range_from_unary_expr (vr, expr);
- else if (expr_computes_nonzero (expr))
+ else if (vrp_expr_computes_nonzero (expr))
set_value_range_to_nonnull (vr, TREE_TYPE (expr));
else if (TREE_CODE (expr) == INTEGER_CST)
set_value_range (vr, VR_RANGE, expr, expr);