diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8afb6f85744d3f599b3ba18e4be0b143f8657da1..5fd429843f7ab14a868412d4336997ebc50db095 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Richard Guenther <rguenther@suse.de> + + * tree-ssa-structalias.c (find_func_aliases): Handle + pointer alignment via BIT_AND_EXPR. + * tree-vrp.c (extract_range_from_binary_expr): Likewise. + 2010-07-02 Richard Guenther <rguenther@suse.de> * tree-data-ref.c (initialize_data_dependence_relation): Handle diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 77ff17a6962554a6594f3ab87b90e532b47a845b..b0efcfa3473ae2987b24c8bcf3fe7ef317fbe27c 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4395,6 +4395,14 @@ find_func_aliases (gimple origt) if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR) get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), gimple_assign_rhs2 (t), &rhsc); + else if (gimple_assign_rhs_code (t) == BIT_AND_EXPR + && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST) + { + /* Aligning a pointer via a BIT_AND_EXPR is offsetting + the pointer. Handle it by offsetting it by UNKNOWN. */ + get_constraint_for_ptr_offset (gimple_assign_rhs1 (t), + NULL_TREE, &rhsc); + } else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t)) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 4f5db8069f52489b2c62ad0e0c25f640d0a77683..74b3a7ac1990906a0eeb71aca8ed67c3e1634fc0 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2188,15 +2188,30 @@ extract_range_from_binary_expr (value_range_t *vr, return; } - gcc_assert (code == POINTER_PLUS_EXPR); - /* For pointer types, we are really only interested in asserting - whether the expression evaluates to non-NULL. */ - if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) - set_value_range_to_nonnull (vr, expr_type); - else if (range_is_null (&vr0) && range_is_null (&vr1)) - set_value_range_to_null (vr, expr_type); + if (code == POINTER_PLUS_EXPR) + { + /* For pointer types, we are really only interested in asserting + whether the expression evaluates to non-NULL. */ + if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1)) + set_value_range_to_nonnull (vr, expr_type); + else if (range_is_null (&vr0) && range_is_null (&vr1)) + set_value_range_to_null (vr, expr_type); + else + set_value_range_to_varying (vr); + } + else if (code == BIT_AND_EXPR) + { + /* For pointer types, we are really only interested in asserting + whether the expression evaluates to non-NULL. */ + if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1)) + set_value_range_to_nonnull (vr, expr_type); + else if (range_is_null (&vr0) || range_is_null (&vr1)) + set_value_range_to_null (vr, expr_type); + else + set_value_range_to_varying (vr); + } else - set_value_range_to_varying (vr); + gcc_unreachable (); return; }