mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-27 09:05:38 +08:00
tree-vrp.c (simplify_bit_ops_using_ranges): New function.
* tree-vrp.c (simplify_bit_ops_using_ranges): New function. (simplify_stmt_using_ranges): Use it. * gcc.dg/tree-ssa/vrp53.c: New test. From-SVN: r162115
This commit is contained in:
parent
8dc9f5bd88
commit
8556f58f76
@ -1,3 +1,8 @@
|
||||
2010-07-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-vrp.c (simplify_bit_ops_using_ranges): New function.
|
||||
(simplify_stmt_using_ranges): Use it.
|
||||
|
||||
2010-07-12 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
|
||||
|
||||
* config/spu/spu.h (struct spu_builtin_description): Remove FNDECL
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-07-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/vrp53.c: New test.
|
||||
|
||||
2010-07-12 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/44907
|
||||
|
24
gcc/testsuite/gcc.dg/tree-ssa/vrp53.c
Normal file
24
gcc/testsuite/gcc.dg/tree-ssa/vrp53.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp1" } */
|
||||
|
||||
int
|
||||
f1 (int x)
|
||||
{
|
||||
x &= 0xff;
|
||||
x += 0x400;
|
||||
x &= 0x7ff;
|
||||
return x;
|
||||
}
|
||||
|
||||
int
|
||||
f2 (int x)
|
||||
{
|
||||
x &= 0xff;
|
||||
x += 0x5400;
|
||||
x |= 0x4400;
|
||||
return x;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "\& (2047|0x7ff)" "vrp1" } } */
|
||||
/* { dg-final { scan-tree-dump-not "\\| (17408|0x4400)" "vrp1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp1" } } */
|
@ -6913,6 +6913,89 @@ simplify_abs_using_ranges (gimple stmt)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
|
||||
If all the bits that are being cleared by & are already
|
||||
known to be zero from VR, or all the bits that are being
|
||||
set by | are already known to be one from VR, the bit
|
||||
operation is redundant. */
|
||||
|
||||
static bool
|
||||
simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
|
||||
{
|
||||
tree op0 = gimple_assign_rhs1 (stmt);
|
||||
tree op1 = gimple_assign_rhs2 (stmt);
|
||||
tree op = NULL_TREE;
|
||||
value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
|
||||
value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
|
||||
double_int may_be_nonzero0, may_be_nonzero1;
|
||||
double_int must_be_nonzero0, must_be_nonzero1;
|
||||
double_int mask;
|
||||
|
||||
if (TREE_CODE (op0) == SSA_NAME)
|
||||
vr0 = *(get_value_range (op0));
|
||||
else if (is_gimple_min_invariant (op0))
|
||||
set_value_range_to_value (&vr0, op0, NULL);
|
||||
else
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (op1) == SSA_NAME)
|
||||
vr1 = *(get_value_range (op1));
|
||||
else if (is_gimple_min_invariant (op1))
|
||||
set_value_range_to_value (&vr1, op1, NULL);
|
||||
else
|
||||
return false;
|
||||
|
||||
if (!zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0, &must_be_nonzero0))
|
||||
return false;
|
||||
if (!zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1, &must_be_nonzero1))
|
||||
return false;
|
||||
|
||||
switch (gimple_assign_rhs_code (stmt))
|
||||
{
|
||||
case BIT_AND_EXPR:
|
||||
mask = double_int_and (may_be_nonzero0,
|
||||
double_int_not (must_be_nonzero1));
|
||||
if (double_int_zero_p (mask))
|
||||
{
|
||||
op = op0;
|
||||
break;
|
||||
}
|
||||
mask = double_int_and (may_be_nonzero1,
|
||||
double_int_not (must_be_nonzero0));
|
||||
if (double_int_zero_p (mask))
|
||||
{
|
||||
op = op1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BIT_IOR_EXPR:
|
||||
mask = double_int_and (may_be_nonzero0,
|
||||
double_int_not (must_be_nonzero1));
|
||||
if (double_int_zero_p (mask))
|
||||
{
|
||||
op = op1;
|
||||
break;
|
||||
}
|
||||
mask = double_int_and (may_be_nonzero1,
|
||||
double_int_not (must_be_nonzero0));
|
||||
if (double_int_zero_p (mask))
|
||||
{
|
||||
op = op0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (op == NULL_TREE)
|
||||
return false;
|
||||
|
||||
gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op, NULL);
|
||||
update_stmt (gsi_stmt (*gsi));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has
|
||||
a known value range VR.
|
||||
|
||||
@ -7198,6 +7281,15 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
|
||||
return simplify_abs_using_ranges (stmt);
|
||||
break;
|
||||
|
||||
case BIT_AND_EXPR:
|
||||
case BIT_IOR_EXPR:
|
||||
/* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
|
||||
if all the bits being cleared are already cleared or
|
||||
all the bits being set are already set. */
|
||||
if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
|
||||
return simplify_bit_ops_using_ranges (gsi, stmt);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user