From: rth Date: Sun, 1 Apr 2007 18:17:38 +0000 (+0000) Subject: PR tree-optimization/31169 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=6291249b40959d2fba26f20841b0bcc4bf63d80d PR tree-optimization/31169 * tree-vrp.c (extract_range_from_binary_expr) : Drop to varying if the range is outside [0, prec-1]. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123405 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d8f39bb7d9..81606be4cd3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-04-01 Richard Henderson + + PR tree-optimization/31169 + * tree-vrp.c (extract_range_from_binary_expr) : Drop + to varying if the range is outside [0, prec-1]. + 2007-04-01 Richard Sandiford PR target/31388 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 3b7358dc032..dbb97de887a 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1813,15 +1813,23 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) return; } - /* If we have a RSHIFT_EXPR with a possibly negative shift - count or an anti-range shift count drop to VR_VARYING. - We currently cannot handle the overflow cases correctly. */ - if (code == RSHIFT_EXPR - && (vr1.type == VR_ANTI_RANGE - || !vrp_expr_computes_nonnegative (op1, &sop))) + /* If we have a RSHIFT_EXPR with any shift values outside [0..prec-1], + then drop to VR_VARYING. Outside of this range we get undefined + behaviour from the shift operation. We cannot even trust + SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl + shifts, and the operation at the tree level may be widened. */ + if (code == RSHIFT_EXPR) { - set_value_range_to_varying (vr); - return; + if (vr1.type == VR_ANTI_RANGE + || !vrp_expr_computes_nonnegative (op1, &sop) + || (operand_less_p + (build_int_cst (TREE_TYPE (vr1.max), + TYPE_PRECISION (TREE_TYPE (expr)) - 1), + vr1.max) != 0)) + { + set_value_range_to_varying (vr); + return; + } } /* Multiplications and divisions are a bit tricky to handle, @@ -1838,9 +1846,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) the new range. */ /* Divisions by zero result in a VARYING value. */ - if ((code != MULT_EXPR - && code != RSHIFT_EXPR) - && (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1))) + else if (code != MULT_EXPR + && (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1))) { set_value_range_to_varying (vr); return;