From 89476fc9d110e788d4c9b81b1622b378466248b7 Mon Sep 17 00:00:00 2001 From: sayle Date: Tue, 2 Jan 2007 04:32:07 +0000 Subject: [PATCH] * fold-const.c (fold_binary) : Fold "(X^C1) eq/ne C2" into "X eq/ne (C1^C2)". Fold "(X^Z) eq/ne (Y^Z)" as "X eq/ne Y" when Z has no side-effects. Fold "(X^C1) eq/ne (Y^C2)" as "(X^(C1^C2)) eq/ne Y". * gcc.dg/fold-eqxor-4.c: New test case. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120333 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/fold-const.c | 39 +++++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/fold-eqxor-4.c | 22 +++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-eqxor-4.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 810f6e0..dca58fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-01-01 Roger Sayle + + * fold-const.c (fold_binary) : Fold "(X^C1) eq/ne C2" into + "X eq/ne (C1^C2)". Fold "(X^Z) eq/ne (Y^Z)" as "X eq/ne Y" when Z + has no side-effects. Fold "(X^C1) eq/ne (Y^C2)" as "(X^(C1^C2)) + eq/ne Y". + 2007-01-01 Mike Stump * configure.ac: Remove support for building with Apple's gcc-3.1. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 071ddcd..8826908 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10753,6 +10753,15 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) && ! TREE_CONSTANT_OVERFLOW (tem)) return fold_build2 (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 + && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) + return fold_build2 (code, type, TREE_OPERAND (arg0, 0), + fold_build2 (BIT_XOR_EXPR, TREE_TYPE (arg0), + fold_convert (TREE_TYPE (arg0), arg1), + TREE_OPERAND (arg0, 1))); + /* If we have X - Y == 0, we can convert that to X == Y and similarly for !=. Don't do this for ordered comparisons due to overflow. */ if (TREE_CODE (arg0) == MINUS_EXPR @@ -11106,6 +11115,36 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) build_int_cst (itype, 0)); } + if (TREE_CODE (arg0) == BIT_XOR_EXPR + && TREE_CODE (arg1) == BIT_XOR_EXPR) + { + tree arg00 = TREE_OPERAND (arg0, 0); + tree arg01 = TREE_OPERAND (arg0, 1); + tree arg10 = TREE_OPERAND (arg1, 0); + tree arg11 = TREE_OPERAND (arg1, 1); + tree itype = TREE_TYPE (arg0); + + /* Optimize (X ^ Z) op (Y ^ Z) as X op Y, and symmetries. + operand_equal_p guarantees no side-effects so we don't need + to use omit_one_operand on Z. */ + if (operand_equal_p (arg01, arg11, 0)) + return fold_build2 (code, type, arg00, arg10); + if (operand_equal_p (arg01, arg10, 0)) + return fold_build2 (code, type, arg00, arg11); + if (operand_equal_p (arg00, arg11, 0)) + return fold_build2 (code, type, arg01, arg10); + if (operand_equal_p (arg00, arg10, 0)) + return fold_build2 (code, type, arg01, arg11); + + /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y. */ + if (TREE_CODE (arg01) == INTEGER_CST + && TREE_CODE (arg11) == INTEGER_CST) + return fold_build2 (code, type, + fold_build2 (BIT_XOR_EXPR, itype, arg00, + fold_build2 (BIT_XOR_EXPR, itype, + arg01, arg11)), + arg10); + } return NULL_TREE; case LT_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b636d48..429382b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-01-01 Roger Sayle + + * gcc.dg/fold-eqxor-4.c: New test case. + 2007-01-02 Joseph Myers PR middle-end/30311 diff --git a/gcc/testsuite/gcc.dg/fold-eqxor-4.c b/gcc/testsuite/gcc.dg/fold-eqxor-4.c new file mode 100644 index 0000000..bdf31bc --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-eqxor-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +int test1(int a) +{ + return (a ^ 6) == 2; +} + +int test2(int b, int c, int d) +{ + return (b ^ d) == (c ^ d); +} + +int test3(int e, int f) +{ + return (e ^ 6) == (f ^ 4); +} + +/* { dg-final { scan-tree-dump-times "a == 4" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "b == c" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "e \\^ 2" 1 "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */ -- 2.7.4