summaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-12 10:04:34 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-12 10:04:34 +0000
commit6b48fd258456d6394a9e8e0e6890177ddbe8936a (patch)
tree92d75a9c7880a8f395fec4f461dab201f1466a0a /gcc/tree-vrp.c
parentbce88dc2483fba98ca866e759c22b7cc68814f3f (diff)
downloadgcc-6b48fd258456d6394a9e8e0e6890177ddbe8936a.tar.gz
PR tree-optimization/52533
* tree-vrp.c (register_edge_assert_for_2): Use double_int type for mask, only handle shifts by non-zero in-range shift count, for LE_EXPR and GT_EXPR if new_val is maximum, don't add the assertion. * gcc.c-torture/compile/pr52533.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185219 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index d3922db038a..febe33f93c0 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4470,7 +4470,8 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
gimple def_stmt = SSA_NAME_DEF_STMT (name);
tree name2 = NULL_TREE, cst2 = NULL_TREE;
tree val2 = NULL_TREE;
- unsigned HOST_WIDE_INT mask[2] = { 0, 0 };
+ double_int mask = double_int_zero;
+ unsigned int prec = TYPE_PRECISION (TREE_TYPE (val));
/* Extract CST2 from the right shift. */
if (is_gimple_assign (def_stmt)
@@ -4480,23 +4481,13 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
cst2 = gimple_assign_rhs2 (def_stmt);
if (TREE_CODE (name2) == SSA_NAME
&& host_integerp (cst2, 1)
- && (unsigned HOST_WIDE_INT) tree_low_cst (cst2, 1)
- < 2 * HOST_BITS_PER_WIDE_INT
&& INTEGRAL_TYPE_P (TREE_TYPE (name2))
+ && IN_RANGE (tree_low_cst (cst2, 1), 1, prec - 1)
+ && prec <= 2 * HOST_BITS_PER_WIDE_INT
&& live_on_edge (e, name2)
&& !has_single_use (name2))
{
- if ((unsigned HOST_WIDE_INT) tree_low_cst (cst2, 1)
- < HOST_BITS_PER_WIDE_INT)
- mask[0] = ((unsigned HOST_WIDE_INT) 1
- << tree_low_cst (cst2, 1)) - 1;
- else
- {
- mask[1] = ((unsigned HOST_WIDE_INT) 1
- << (tree_low_cst (cst2, 1)
- - HOST_BITS_PER_WIDE_INT)) - 1;
- mask[0] = -1;
- }
+ mask = double_int_mask (tree_low_cst (cst2, 1));
val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);
}
}
@@ -4515,37 +4506,40 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
{
if (!TYPE_UNSIGNED (TREE_TYPE (val)))
{
- unsigned int prec = TYPE_PRECISION (TREE_TYPE (val));
tree type = build_nonstandard_integer_type (prec, 1);
tmp = build1 (NOP_EXPR, type, name2);
val2 = fold_convert (type, val2);
}
tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp, val2);
- new_val = build_int_cst_wide (TREE_TYPE (tmp), mask[0], mask[1]);
+ new_val = double_int_to_tree (TREE_TYPE (tmp), mask);
new_comp_code = comp_code == EQ_EXPR ? LE_EXPR : GT_EXPR;
}
else if (comp_code == LT_EXPR || comp_code == GE_EXPR)
new_val = val2;
else
{
- new_val = build_int_cst_wide (TREE_TYPE (val2),
- mask[0], mask[1]);
- new_val = fold_binary (BIT_IOR_EXPR, TREE_TYPE (val2),
- val2, new_val);
+ mask = double_int_ior (tree_to_double_int (val2), mask);
+ if (double_int_minus_one_p (double_int_sext (mask, prec)))
+ new_val = NULL_TREE;
+ else
+ new_val = double_int_to_tree (TREE_TYPE (val2), mask);
}
- if (dump_file)
+ if (new_val)
{
- fprintf (dump_file, "Adding assert for ");
- print_generic_expr (dump_file, name2, 0);
- fprintf (dump_file, " from ");
- print_generic_expr (dump_file, tmp, 0);
- fprintf (dump_file, "\n");
- }
+ if (dump_file)
+ {
+ fprintf (dump_file, "Adding assert for ");
+ print_generic_expr (dump_file, name2, 0);
+ fprintf (dump_file, " from ");
+ print_generic_expr (dump_file, tmp, 0);
+ fprintf (dump_file, "\n");
+ }
- register_new_assert_for (name2, tmp, new_comp_code, new_val,
- NULL, e, bsi);
- retval = true;
+ register_new_assert_for (name2, tmp, new_comp_code, new_val,
+ NULL, e, bsi);
+ retval = true;
+ }
}
}