gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison binaries.
2015-07-30 Richard Biener <rguenther@suse.de> * gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison binaries. Move X == 0, X == 1, X != 0, and X != 1 canonicalization ... (fold_stmt_1): ... here and work on GIMPLE directly. Remove redundant operand canonicalization. From-SVN: r226404
This commit is contained in:
parent
cb5ca3151b
commit
819ec64c36
@ -1,3 +1,10 @@
|
||||
2015-07-30 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison
|
||||
binaries. Move X == 0, X == 1, X != 0, and X != 1 canonicalization ...
|
||||
(fold_stmt_1): ... here and work on GIMPLE directly. Remove
|
||||
redundant operand canonicalization.
|
||||
|
||||
2015-07-30 David Sherwood <david.sherwood@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-simd.md (aarch64_ext<mode>): Replace call to
|
||||
|
@ -413,60 +413,20 @@ fold_gimple_assign (gimple_stmt_iterator *si)
|
||||
break;
|
||||
|
||||
case GIMPLE_BINARY_RHS:
|
||||
/* Try to canonicalize for boolean-typed X the comparisons
|
||||
X == 0, X == 1, X != 0, and X != 1. */
|
||||
if (gimple_assign_rhs_code (stmt) == EQ_EXPR
|
||||
|| gimple_assign_rhs_code (stmt) == NE_EXPR)
|
||||
{
|
||||
tree lhs = gimple_assign_lhs (stmt);
|
||||
tree op1 = gimple_assign_rhs1 (stmt);
|
||||
tree op2 = gimple_assign_rhs2 (stmt);
|
||||
tree type = TREE_TYPE (op1);
|
||||
if (TREE_CODE_CLASS (subcode) != tcc_comparison)
|
||||
{
|
||||
result = fold_binary_loc (loc, subcode,
|
||||
TREE_TYPE (gimple_assign_lhs (stmt)),
|
||||
gimple_assign_rhs1 (stmt),
|
||||
gimple_assign_rhs2 (stmt));
|
||||
|
||||
/* Check whether the comparison operands are of the same boolean
|
||||
type as the result type is.
|
||||
Check that second operand is an integer-constant with value
|
||||
one or zero. */
|
||||
if (TREE_CODE (op2) == INTEGER_CST
|
||||
&& (integer_zerop (op2) || integer_onep (op2))
|
||||
&& useless_type_conversion_p (TREE_TYPE (lhs), type))
|
||||
if (result)
|
||||
{
|
||||
enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
|
||||
bool is_logical_not = false;
|
||||
|
||||
/* X == 0 and X != 1 is a logical-not.of X
|
||||
X == 1 and X != 0 is X */
|
||||
if ((cmp_code == EQ_EXPR && integer_zerop (op2))
|
||||
|| (cmp_code == NE_EXPR && integer_onep (op2)))
|
||||
is_logical_not = true;
|
||||
|
||||
if (is_logical_not == false)
|
||||
result = op1;
|
||||
/* Only for one-bit precision typed X the transformation
|
||||
!X -> ~X is valied. */
|
||||
else if (TYPE_PRECISION (type) == 1)
|
||||
result = build1_loc (gimple_location (stmt), BIT_NOT_EXPR,
|
||||
type, op1);
|
||||
/* Otherwise we use !X -> X ^ 1. */
|
||||
else
|
||||
result = build2_loc (gimple_location (stmt), BIT_XOR_EXPR,
|
||||
type, op1, build_int_cst (type, 1));
|
||||
|
||||
STRIP_USELESS_TYPE_CONVERSION (result);
|
||||
if (valid_gimple_rhs_p (result))
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
result = fold_binary_loc (loc, subcode,
|
||||
TREE_TYPE (gimple_assign_lhs (stmt)),
|
||||
gimple_assign_rhs1 (stmt),
|
||||
gimple_assign_rhs2 (stmt));
|
||||
|
||||
if (result)
|
||||
{
|
||||
STRIP_USELESS_TYPE_CONVERSION (result);
|
||||
if (valid_gimple_rhs_p (result))
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_TERNARY_RHS:
|
||||
@ -3653,23 +3613,51 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
|
||||
{
|
||||
case GIMPLE_ASSIGN:
|
||||
{
|
||||
unsigned old_num_ops = gimple_num_ops (stmt);
|
||||
enum tree_code subcode = gimple_assign_rhs_code (stmt);
|
||||
tree lhs = gimple_assign_lhs (stmt);
|
||||
tree new_rhs;
|
||||
/* First canonicalize operand order. This avoids building new
|
||||
trees if this is the only thing fold would later do. */
|
||||
if ((commutative_tree_code (subcode)
|
||||
|| commutative_ternary_tree_code (subcode))
|
||||
&& tree_swap_operands_p (gimple_assign_rhs1 (stmt),
|
||||
gimple_assign_rhs2 (stmt), false))
|
||||
/* Try to canonicalize for boolean-typed X the comparisons
|
||||
X == 0, X == 1, X != 0, and X != 1. */
|
||||
if (gimple_assign_rhs_code (stmt) == EQ_EXPR
|
||||
|| gimple_assign_rhs_code (stmt) == NE_EXPR)
|
||||
{
|
||||
tree tem = gimple_assign_rhs1 (stmt);
|
||||
gimple_assign_set_rhs1 (stmt, gimple_assign_rhs2 (stmt));
|
||||
gimple_assign_set_rhs2 (stmt, tem);
|
||||
changed = true;
|
||||
tree lhs = gimple_assign_lhs (stmt);
|
||||
tree op1 = gimple_assign_rhs1 (stmt);
|
||||
tree op2 = gimple_assign_rhs2 (stmt);
|
||||
tree type = TREE_TYPE (op1);
|
||||
|
||||
/* Check whether the comparison operands are of the same boolean
|
||||
type as the result type is.
|
||||
Check that second operand is an integer-constant with value
|
||||
one or zero. */
|
||||
if (TREE_CODE (op2) == INTEGER_CST
|
||||
&& (integer_zerop (op2) || integer_onep (op2))
|
||||
&& useless_type_conversion_p (TREE_TYPE (lhs), type))
|
||||
{
|
||||
enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
|
||||
bool is_logical_not = false;
|
||||
|
||||
/* X == 0 and X != 1 is a logical-not.of X
|
||||
X == 1 and X != 0 is X */
|
||||
if ((cmp_code == EQ_EXPR && integer_zerop (op2))
|
||||
|| (cmp_code == NE_EXPR && integer_onep (op2)))
|
||||
is_logical_not = true;
|
||||
|
||||
if (is_logical_not == false)
|
||||
gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1);
|
||||
/* Only for one-bit precision typed X the transformation
|
||||
!X -> ~X is valied. */
|
||||
else if (TYPE_PRECISION (type) == 1)
|
||||
gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1);
|
||||
/* Otherwise we use !X -> X ^ 1. */
|
||||
else
|
||||
gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1,
|
||||
build_int_cst (type, 1));
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
new_rhs = fold_gimple_assign (gsi);
|
||||
|
||||
unsigned old_num_ops = gimple_num_ops (stmt);
|
||||
tree lhs = gimple_assign_lhs (stmt);
|
||||
tree new_rhs = fold_gimple_assign (gsi);
|
||||
if (new_rhs
|
||||
&& !useless_type_conversion_p (TREE_TYPE (lhs),
|
||||
TREE_TYPE (new_rhs)))
|
||||
|
Loading…
Reference in New Issue
Block a user