This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[GSoC][match-and-simplify] add bitwise patterns to match.pd
- From: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Diego Novillo <dnovillo at google dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Maxim Kuvyrkov <maxim dot kuvyrkov at linaro dot org>
- Date: Mon, 2 Jun 2014 17:03:04 +0530
- Subject: [GSoC][match-and-simplify] add bitwise patterns to match.pd
- Authentication-results: sourceware.org; auth=none
Hi,
I have tried to add few bitwise patterns from
tree-ssa-forwprop.c:simplify_bitwise_binary and the patterns
mentioned in Simplifications wiki (https://gcc.gnu.org/wiki/Simplifications).
How to write a test-case to match multiple gimple statements ?
Example: For the pattern: ~x | ~y -> ~(x & y)
test-case:
int f(int x, int y)
{
int t1 = ~x;
int t2 = ~y;
return t1 | t2;
}
fdump-tree-forwprop-details output:
gimple_match_and_simplified to _5 = ~_7;
f (int x, int y)
{
int t2;
int t1;
int _5;
int _7;
<bb 2>:
t1_2 = ~x_1(D);
t2_4 = ~y_3(D);
_7 = x_1(D) & y_3(D);
_5 = ~_7;
return _5;
}
I suppose we want to look for matching both:
_7 = x_1(D) & y_3(D);
_5 = ~_7;
so only matching on "gimple_match_and_simplified to _5 = ~_7" won't
be correct ?
The patterns for x & 0 -> 0 and x & -1 -> x don't get fired from forwprop.
I tried:
int f1(int x)
{
int t1 = 0;
return x & t1;
}
fdump-tree-forwprop-details shows following:
;; Function f1 (f1, funcdef_no=0, decl_uid=1743, symbol_order=0)
f1 (int x)
{
int t1;
<bb 2>:
return 0;
}
[gcc]
* match.pd: Add few patterns from simplify_bitwise_binary.
[gcc/testsuite]
* gcc.dg/tree-ssa/match-2.c: Add more test-cases.
Thanks and Regards,
Prathamesh
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 211017)
+++ gcc/match.pd (working copy)
@@ -189,6 +189,121 @@ to (minus @1 @0)
if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf))
(BUILT_IN_SQRT @0))
+/* TODO bitwise patterns:
+1] x & x -> x
+2] x & 0 -> 0
+3] x & -1 -> x
+4] x & ~x -> 0
+5] ~x & ~y -> ~(x | y)
+6] ~x | ~y -> ~(x & y)
+7] x & (~x | y) -> y & x
+8] (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2)
+9] x ^ x -> 0
+10] x ^ ~0 -> ~x
+11] (x | y) & x -> x
+12] (x & y) | x -> x
+13] (~x | y) & x -> x & y
+14] (~x & y) | x -> x | y
+15] ((a & b) & ~a) & ~b -> 0
+16] ~~x -> x
+*/
+
+/* x & x -> x */
+(match_and_simplify
+ (bit_and @0 @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ @0)
+
+/* x & ~x -> 0 */
+(match_and_simplify
+ (bit_and @0 (bit_not @0))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ { build_int_cst (TREE_TYPE (@0), 0); })
+
+/* x & 0 -> 0 */
+(match_and_simplify
+ (bit_and @0 @1)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && @1 == integer_zero_node)
+ { integer_zero_node; })
+
+/* x & -1 -> x */
+(match_and_simplify
+ (bit_and @0 @1)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && @1 == integer_minus_one_node)
+ @0)
+
+/* x ^ x -> 0 */
+(match_and_simplify
+ (bit_xor @0 @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ { build_int_cst (TREE_TYPE (@0), 0); })
+
+/* ~x & ~y -> ~(x | y) */
+(match_and_simplify
+ (bit_and (bit_not @0) (bit_not @1))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (bit_not (bit_ior @0 @1)))
+
+/* ~x | ~y -> ~(x & y) */
+(match_and_simplify
+ (bit_ior (bit_not @0) (bit_not @1))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (bit_not (bit_and @0 @1)))
+
+/* x & (~x | y) -> y & x */
+(match_and_simplify
+ (bit_and @0 (bit_ior (bit_not @0) @1))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (bit_and @1 @0))
+
+/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */
+(match_and_simplify
+ (bit_and (bit_ior @0 INTEGER_CST_P@1) INTEGER_CST_P@2)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ (bit_ior (bit_and @0 @2) (bit_and @1 @2)))
+
+/* x ^ ~0 -> ~x */
+(match_and_simplify
+ (bit_xor @0 @1)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && (@1 == integer_minus_one_node))
+ (bit_not @0))
+
+/* (x | y) & x -> x */
+(match_and_simplify
+ (bit_and (bit_ior @0 @1) @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ @0)
+
+/* (x & y) | x -> x */
+(match_and_simplify
+ (bit_ior (bit_and @0 @1) @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ @0)
+
+/* (~x | y) & x -> x & y */
+(match_and_simplify
+ (bit_and (bit_ior (bit_not @0) @1) @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (bit_and @0 @1))
+
+/* (~x & y) | x -> x & y */
+(match_and_simplify
+ (bit_ior (bit_and (bit_not @0) @1) @0)
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ (bit_and @0 @1))
+
+/* ~~x -> x */
+(match_and_simplify
+ (bit_not (bit_not @0))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ @0)
+
+/* ((a & b) & ~a) & ~b -> 0 */
+(match_and_simplify
+ (bit_and (bit_and (bit_and @0 @1) (bit_not @0)) (bit_not @1))
+ if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) && INTEGRAL_TYPE_P (TREE_TYPE (@1)))
+ { integer_zero_node; })
+
/* ????s
We cannot reasonably match vector CONSTRUCTORs or vector constants
Index: gcc/testsuite/gcc.dg/tree-ssa/match-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/match-2.c (revision 211017)
+++ gcc/testsuite/gcc.dg/tree-ssa/match-2.c (working copy)
@@ -115,4 +115,97 @@ double f14(double x)
}
/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+/* x & x -> x */
+int f15(int x)
+{
+ int t1 = x;
+ return t1 & x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* x & ~x -> 0 */
+int f16(int x)
+{
+ int t1 = ~x;
+ return t1 & x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= 0" "forwprop1" } } */
+
+/* x ^ x -> 0 */
+int f17(int x)
+{
+ int t1 = x;
+ return t1 ^ x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= 0" "forwprop1" } } */
+
+/* ~~x -> 0 */
+int f18(int x)
+{
+ int t1 = ~x;
+ return ~t1;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* (x | y) & x -> x */
+int f19(int x, int y)
+{
+ int t1 = x | y;
+ return t1 & x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* (x & y) | x -> x */
+int f20(int x, int y)
+{
+ int t1 = x & y;
+ return t1 | x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* (~x & y) | x -> x & y */
+int f21(int x, int y)
+{
+ int t1 = ~x;
+ int t2 = t1 & y;
+ return t2 | x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\) & y_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* (~x | y) & x -> x & y */
+int f22(int x, int y)
+{
+ int t1 = ~x;
+ int t2 = t1 | y;
+ return t2 & x;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\) & y_\\d\+\\(D\\)" "forwprop1" } } */
+
+/* ((x & y) & ~x) & ~y -> 0 */
+int f23(int x, int y)
+{
+ int t1 = x & y;
+ int t2 = ~x;
+ int t3 = t1 & t2;
+ int t4 = ~y;
+ return t3 & t4;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= 0" "forwprop1" } } */
+
+/* x & 0 -> 0 */
+int f24(int x)
+{
+ int t1 = 0;
+ return x & t1;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= 0" "forwprop1" } } */
+
+/* x & -1 -> x */
+int f25(int x)
+{
+ int t1 = -1;
+ return x & t1;
+}
+/* { dg-final { scan-tree-dump "gimple_match_and_simplified to \[^\n\r\]*= x_\\d\+\\(D\\)" "forwprop1" } } */
+
/* { dg-final { cleanup-tree-dump "forwprop2" } } */