mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-03 00:34:21 +08:00
fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B and -A CMP CST -> A CMP -CST which is redundant...
2015-06-26 Richard Biener <rguenther@suse.de> * fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B and -A CMP CST -> A CMP -CST which is redundant with a pattern in match.pd. Move (A | C) == D where C & ~D != 0 -> 0, (X ^ Y) ==/!= 0 -> X ==/!= Y, (X ^ Y) ==/!= {Y,X} -> {X,Y} ==/!= 0 and (X ^ C1) op C2 -> X op (C1 ^ C2) to ... * match.pd: ... patterns here. * gcc.dg/tree-ssa/forwprop-25.c: Adjust. From-SVN: r225007
This commit is contained in:
parent
8afaddaace
commit
66e1cacf60
@ -1,3 +1,13 @@
|
||||
2015-06-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* fold-const.c (fold_binary_loc): Remove -A CMP -B -> A CMP B
|
||||
and -A CMP CST -> A CMP -CST which is redundant with a pattern
|
||||
in match.pd.
|
||||
Move (A | C) == D where C & ~D != 0 -> 0, (X ^ Y) ==/!= 0 -> X ==/!= Y,
|
||||
(X ^ Y) ==/!= {Y,X} -> {X,Y} ==/!= 0 and
|
||||
(X ^ C1) op C2 -> X op (C1 ^ C2) to ...
|
||||
* match.pd: ... patterns here.
|
||||
|
||||
2015-06-26 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
* match.pd ((x | y) & ~(x & y) -> x ^ y,
|
||||
|
@ -12163,15 +12163,6 @@ fold_binary_loc (location_t loc,
|
||||
type);
|
||||
}
|
||||
|
||||
/* Similarly for a NEGATE_EXPR. */
|
||||
if (TREE_CODE (arg0) == NEGATE_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& 0 != (tem = negate_expr (fold_convert_loc (loc, TREE_TYPE (arg0),
|
||||
arg1)))
|
||||
&& TREE_CODE (tem) == INTEGER_CST
|
||||
&& !TREE_OVERFLOW (tem))
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);
|
||||
|
||||
/* Similarly for a BIT_XOR_EXPR; X ^ C1 == C2 is X == (C1 ^ C2). */
|
||||
if (TREE_CODE (arg0) == BIT_XOR_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
@ -12356,22 +12347,6 @@ fold_binary_loc (location_t loc,
|
||||
return omit_one_operand_loc (loc, type, rslt, arg0);
|
||||
}
|
||||
|
||||
/* If we have (A | C) == D where C & ~D != 0, convert this into 0.
|
||||
Similarly for NE_EXPR. */
|
||||
if (TREE_CODE (arg0) == BIT_IOR_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
{
|
||||
tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1);
|
||||
tree candnotd
|
||||
= fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
|
||||
TREE_OPERAND (arg0, 1),
|
||||
fold_convert_loc (loc, TREE_TYPE (arg0), notd));
|
||||
tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
|
||||
if (integer_nonzerop (candnotd))
|
||||
return omit_one_operand_loc (loc, type, rslt, arg0);
|
||||
}
|
||||
|
||||
/* If this is a comparison of a field, we may be able to simplify it. */
|
||||
if ((TREE_CODE (arg0) == COMPONENT_REF
|
||||
|| TREE_CODE (arg0) == BIT_FIELD_REF)
|
||||
@ -12429,32 +12404,6 @@ fold_binary_loc (location_t loc,
|
||||
}
|
||||
}
|
||||
|
||||
/* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */
|
||||
if (integer_zerop (arg1)
|
||||
&& TREE_CODE (arg0) == BIT_XOR_EXPR)
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
|
||||
TREE_OPERAND (arg0, 1));
|
||||
|
||||
/* (X ^ Y) == Y becomes X == 0. We know that Y has no side-effects. */
|
||||
if (TREE_CODE (arg0) == BIT_XOR_EXPR
|
||||
&& operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
|
||||
build_zero_cst (TREE_TYPE (arg0)));
|
||||
/* Likewise (X ^ Y) == X becomes Y == 0. X has no side-effects. */
|
||||
if (TREE_CODE (arg0) == BIT_XOR_EXPR
|
||||
&& operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
|
||||
&& reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 1),
|
||||
build_zero_cst (TREE_TYPE (arg0)));
|
||||
|
||||
/* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */
|
||||
if (TREE_CODE (arg0) == BIT_XOR_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
|
||||
fold_build2_loc (loc, BIT_XOR_EXPR, TREE_TYPE (arg1),
|
||||
TREE_OPERAND (arg0, 1), arg1));
|
||||
|
||||
/* Fold (~X & C) == 0 into (X & C) != 0 and (~X & C) != 0 into
|
||||
(X & C) == 0 when C is a single bit. */
|
||||
if (TREE_CODE (arg0) == BIT_AND_EXPR
|
||||
@ -12508,14 +12457,6 @@ fold_binary_loc (location_t loc,
|
||||
return omit_one_operand_loc (loc, type, res, arg0);
|
||||
}
|
||||
|
||||
/* Fold -X op -Y as X op Y, where op is eq/ne. */
|
||||
if (TREE_CODE (arg0) == NEGATE_EXPR
|
||||
&& TREE_CODE (arg1) == NEGATE_EXPR)
|
||||
return fold_build2_loc (loc, code, type,
|
||||
TREE_OPERAND (arg0, 0),
|
||||
fold_convert_loc (loc, TREE_TYPE (arg0),
|
||||
TREE_OPERAND (arg1, 0)));
|
||||
|
||||
/* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries. */
|
||||
if (TREE_CODE (arg0) == BIT_AND_EXPR
|
||||
&& TREE_CODE (arg1) == BIT_AND_EXPR)
|
||||
|
29
gcc/match.pd
29
gcc/match.pd
@ -1209,6 +1209,35 @@ along with GCC; see the file COPYING3. If not see
|
||||
(if (tem && !TREE_OVERFLOW (tem))
|
||||
(scmp @0 { tem; }))))))
|
||||
|
||||
|
||||
/* Equality compare simplifications from fold_binary */
|
||||
(for cmp (eq ne)
|
||||
|
||||
/* If we have (A | C) == D where C & ~D != 0, convert this into 0.
|
||||
Similarly for NE_EXPR. */
|
||||
(simplify
|
||||
(cmp (convert?@3 (bit_ior @0 INTEGER_CST@1)) INTEGER_CST@2)
|
||||
(if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0))
|
||||
&& wi::bit_and_not (@1, @2) != 0)
|
||||
{ constant_boolean_node (cmp == NE_EXPR, type); }))
|
||||
|
||||
/* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y. */
|
||||
(simplify
|
||||
(cmp (bit_xor @0 @1) integer_zerop)
|
||||
(cmp @0 @1))
|
||||
|
||||
/* (X ^ Y) == Y becomes X == 0.
|
||||
Likewise (X ^ Y) == X becomes Y == 0. */
|
||||
(simplify
|
||||
(cmp (bit_xor:c @0 @1) @0)
|
||||
(cmp @1 { build_zero_cst (TREE_TYPE (@1)); }))
|
||||
|
||||
/* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2). */
|
||||
(simplify
|
||||
(cmp (convert?@3 (bit_xor @0 INTEGER_CST@1)) INTEGER_CST@2)
|
||||
(if (tree_nop_conversion_p (TREE_TYPE (@3), TREE_TYPE (@0)))
|
||||
(cmp @0 (bit_xor @1 (convert @2))))))
|
||||
|
||||
/* Simplification of math builtins. */
|
||||
|
||||
(define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL)
|
||||
|
@ -1,3 +1,7 @@
|
||||
2015-06-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/forwprop-25.c: Adjust.
|
||||
|
||||
2015-06-26 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
* gcc.dg/fold-and-1.c: New test.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O1 -fdump-tree-forwprop1" } */
|
||||
/* { dg-options "-O1 -fdump-tree-cddce1" } */
|
||||
|
||||
struct rtx_def;
|
||||
typedef struct rtx_def *rtx;
|
||||
@ -37,7 +37,4 @@ convert_move (rtx to, rtx from, int unsignedp)
|
||||
0 : 0));
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } */
|
||||
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-not " ^ " "cddce1"} } */
|
||||
|
Loading…
Reference in New Issue
Block a user