aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorAndrew Pinski <pinskia@physics.uc.edu>2005-07-21 19:33:45 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2005-07-21 12:33:45 -0700
commit9d24eb542cfde81c37ad94029f3d51375785b251 (patch)
treef83d95ac14a5aafcb09fd2420e89f60afb9ba7b4 /gcc/fold-const.c
parent35f5a23f7bc7c0a21bbaf8a0ca8c4be551b99c88 (diff)
downloadgcc-9d24eb542cfde81c37ad94029f3d51375785b251.zip
gcc-9d24eb542cfde81c37ad94029f3d51375785b251.tar.gz
gcc-9d24eb542cfde81c37ad94029f3d51375785b251.tar.bz2
re PR tree-optimization/19055 (Minor bit optimization with or and xor)
2005-07-21 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/19055 * gcc.dg/tree-ssa/pr19055.c: New test. * gcc.dg/tree-ssa/pr19055-2.c: New test. 2005-07-21 Andrew Pinski <pinskia@physics.uc.edu> PR middle-end/19055 * fold-const.c (fold_binary): Transform "(X | Y) ^ X" to "Y & ~ X". From-SVN: r102243
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 7b83eb3..acafd6a 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8059,6 +8059,54 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
goto bit_ior;
}
+ /* (X | Y) ^ X -> Y & ~ X*/
+ if (TREE_CODE (arg0) == BIT_IOR_EXPR
+ && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
+ {
+ tree t2 = TREE_OPERAND (arg0, 1);
+ t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
+ arg1);
+ t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
+ fold_convert (type, t1));
+ return t1;
+ }
+
+ /* (Y | X) ^ X -> Y & ~ X*/
+ if (TREE_CODE (arg0) == BIT_IOR_EXPR
+ && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
+ {
+ tree t2 = TREE_OPERAND (arg0, 0);
+ t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
+ arg1);
+ t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
+ fold_convert (type, t1));
+ return t1;
+ }
+
+ /* X ^ (X | Y) -> Y & ~ X*/
+ if (TREE_CODE (arg1) == BIT_IOR_EXPR
+ && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
+ {
+ tree t2 = TREE_OPERAND (arg1, 1);
+ t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
+ arg0);
+ t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
+ fold_convert (type, t1));
+ return t1;
+ }
+
+ /* X ^ (Y | X) -> Y & ~ X*/
+ if (TREE_CODE (arg1) == BIT_IOR_EXPR
+ && operand_equal_p (TREE_OPERAND (arg1, 1), arg0, 0))
+ {
+ tree t2 = TREE_OPERAND (arg1, 0);
+ t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
+ arg0);
+ t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
+ fold_convert (type, t1));
+ return t1;
+ }
+
/* Convert ~X ^ ~Y to X ^ Y. */
if (TREE_CODE (arg0) == BIT_NOT_EXPR
&& TREE_CODE (arg1) == BIT_NOT_EXPR)