This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[GSoC][match-and-simplify] split match.pd
- From: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>, 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: Wed, 30 Jul 2014 23:24:28 +0530
- Subject: [GSoC][match-and-simplify] split match.pd
- Authentication-results: sourceware.org; auth=none
I have split match.pd in this patch.
Not sure if I have written the ChangeLog correctly though...
* match-bitwise.pd: New file.
* match-plusminus.pd: Likewise.
* match-constant-folding.pd: Likewise.
* match-builtin.pd: Likewise.
* match-rotate.pd): New file.
Adjust to use wi::eq_p and wi::add.
* (match.pd): Move plus-minus patterns to ...
(match-pluminus.pd): ... here.
Move bitwise paterns to ...
(match-bitwise.pd): ... here.
Move constant folding patterns to ...
(match-constant-folding.pd): ... here.
Move patterns on built-in functions to ...
(match-builtin.pd): ... here.
Move rotate patterns to ...
(match-rotate.pd): ... here.
Include match-plusminus.pd.
Include match-bitwise.pd.
Include match-constant-folding.pd.
Include match-builtin.pd.
Include match-rotate.pd.
Thanks,
Prathamesh
Index: gcc/match-bitwise.pd
===================================================================
--- gcc/match-bitwise.pd (revision 0)
+++ gcc/match-bitwise.pd (working copy)
@@ -0,0 +1,102 @@
+/* match-and-simplify patterns for simplify_bitwise_binary
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* 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 integral_op_p@0 @0)
+ @0)
+
+/* x & ~x -> 0 */
+(match_and_simplify
+ (bit_and:c integral_op_p@0 (bit_not @0))
+ { build_int_cst (type, 0); })
+
+/* ~x & ~y -> ~(x | y) */
+(match_and_simplify
+ (bit_and (bit_not integral_op_p@0) (bit_not @1))
+ (bit_not (bit_ior @0 @1)))
+
+/* ~x | ~y -> ~(x & y) */
+(match_and_simplify
+ (bit_ior (bit_not integral_op_p@0) (bit_not @1))
+ (bit_not (bit_and @0 @1)))
+
+/* x & (~x | y) -> y & x */
+(match_and_simplify
+ (bit_and:c integral_op_p@0 (bit_ior:c (bit_not @0) @1))
+ (bit_and @1 @0))
+
+/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */
+(match_and_simplify
+ (bit_and (bit_ior integral_op_p@0 INTEGER_CST_P@1) INTEGER_CST_P@2)
+ (bit_ior (bit_and @0 @2) (bit_and @1 @2)))
+
+/* x ^ ~0 -> ~x */
+(match_and_simplify
+ (bit_xor @0 integer_all_onesp@1)
+ (bit_not @0))
+
+/* (x | y) & x -> x */
+(match_and_simplify
+ (bit_and:c (bit_ior integral_op_p@0 @1) @0)
+ @0)
+
+/* (x & y) | x -> x */
+(match_and_simplify
+ (bit_ior:c (bit_and integral_op_p@0 @1) @0)
+ @0)
+
+/* (~x | y) & x -> x & y */
+(match_and_simplify
+ (bit_and:c (bit_ior:c (bit_not integral_op_p@0) @1) @0)
+ (bit_and @0 @1))
+
+/* (~x & y) | x -> x | y */
+(match_and_simplify
+ (bit_ior:c (bit_and:c (bit_not integral_op_p@0) @1) @0)
+ (bit_ior @0 @1))
+
+/* ~~x -> x */
+(match_and_simplify
+ (bit_not (bit_not integral_op_p@0))
+ @0)
+
+/* ((a & b) & ~a) -> 0 */
+(match_and_simplify
+ (bit_and:c (bit_and integral_op_p@0 @1) (bit_not @0))
+ { build_int_cst (type, 0); })
Index: gcc/match-builtin.pd
===================================================================
--- gcc/match-builtin.pd (revision 0)
+++ gcc/match-builtin.pd (working copy)
@@ -0,0 +1,44 @@
+/* match-and-simplify patterns for builtin functions
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* One builtin function to atom. */
+(match_and_simplify
+ (BUILT_IN_SQRT (mult @0 @0))
+ @0)
+/* One builtin function to builtin function. */
+(match_and_simplify
+ (BUILT_IN_CABS (complex:c @0 real_zerop))
+ (BUILT_IN_FABS @0))
+/* One builtin function to expr. */
+(match_and_simplify
+ (BUILT_IN_CABS (complex @0 @0))
+ (mult (BUILT_IN_FABS @0) { build_real (TREE_TYPE (@0), real_value_truncate (TYPE_MODE (TREE_TYPE (@0)), dconst_sqrt2 ())); }))
+/* One nested fn. */
+(match_and_simplify
+ (mult:c (BUILT_IN_POW @0 @1) @0)
+ (BUILT_IN_POW @0 (PLUS_EXPR @1 { build_one_cst (TREE_TYPE (@1)); })))
+(match_and_simplify
+ (BUILT_IN_POW @0 REAL_CST_P@1)
+ /* This needs to be conditionalized on flag_unsafe_math_optimizations,
+ but we keep it for now to exercise function re-optimization.
+ It makes gcc.dg/pr43419.c FAIL execution though. */
+ (if (REAL_VALUES_EQUAL (TREE_REAL_CST (@1), dconsthalf)))
+ (BUILT_IN_SQRT @0))
+
Index: gcc/match-constant-folding.pd
===================================================================
--- gcc/match-constant-folding.pd (revision 0)
+++ gcc/match-constant-folding.pd (working copy)
@@ -0,0 +1,66 @@
+/* match-and-simplify patterns for simple constant foldings to substitute gimple_fold_stmt_to_constant_2
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+(for op in plus pointer_plus minus bit_ior bit_xor
+ (match_and_simplify
+ (op @0 integer_zerop)
+ @0))
+
+(match_and_simplify
+ (minus @0 @0)
+ { build_zero_cst (type); })
+
+(match_and_simplify
+ (mult @0 integer_zerop@1)
+ @1)
+
+/* Make sure to preserve divisions by zero. This is the reason why
+ we don't simplify x / x to 1 or 0 / x to 0. */
+(for op in mult trunc_div ceil_div floor_div round_div
+ (match_and_simplify
+ (op @0 integer_onep)
+ @0))
+
+(match_and_simplify
+ (trunc_mod @0 integer_onep)
+ { build_zero_cst (type); })
+/* Same applies to modulo operations, but fold is inconsistent here
+ and simplifies 0 % x to 0. */
+(match_and_simplify
+ (trunc_mod integer_zerop@0 @1)
+ (if (!integer_zerop (@1)))
+ @0)
+
+(match_and_simplify
+ (bit_ior @0 integer_all_onesp@1)
+ @1)
+
+(match_and_simplify
+ (bit_and @0 integer_all_onesp)
+ @0)
+
+(match_and_simplify
+ (bit_and @0 integer_zerop@1)
+ @1)
+
+(match_and_simplify
+ (bit_xor @0 @0)
+ { build_zero_cst (type); })
+
+
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 213234)
+++ gcc/match.pd (working copy)
@@ -21,48 +21,6 @@ You should have received a copy of the G
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-/* Simple constant foldings to substitute gimple_fold_stmt_to_constant_2. */
-(for op in plus pointer_plus minus bit_ior bit_xor
- (match_and_simplify
- (op @0 integer_zerop)
- @0))
-
-(match_and_simplify
- (minus @0 @0)
- { build_zero_cst (type); })
-
-(match_and_simplify
- (mult @0 integer_zerop@1)
- @1)
-
-/* Make sure to preserve divisions by zero. This is the reason why
- we don't simplify x / x to 1 or 0 / x to 0. */
-(for op in mult trunc_div ceil_div floor_div round_div
- (match_and_simplify
- (op @0 integer_onep)
- @0))
-
-(match_and_simplify
- (trunc_mod @0 integer_onep)
- { build_zero_cst (type); })
-/* Same applies to modulo operations, but fold is inconsistent here
- and simplifies 0 % x to 0. */
-(match_and_simplify
- (trunc_mod integer_zerop@0 @1)
- (if (!integer_zerop (@1)))
- @0)
-(match_and_simplify
- (bit_ior @0 integer_all_onesp@1)
- @1)
-(match_and_simplify
- (bit_and @0 integer_all_onesp)
- @0)
-(match_and_simplify
- (bit_and @0 integer_zerop@1)
- @1)
-(match_and_simplify
- (bit_xor @0 @0)
- { build_zero_cst (type); })
/* tree-ssa/ifc-pr44710.c requires a < b ? c : d to fold to 1.
??? probably runs into issue of recursive folding of a < b op0. */
/* tree-ssa/ssa-ccp-16.c wants to fold "hello"[i_2] to 0
@@ -98,96 +56,6 @@ along with GCC; see the file COPYING3.
#endif
-/* Transforms formerly done by tree-ssa-forwprop.c:associate_plusminus */
-
-/* ??? Have match_and_simplify groups guarded with common
- predicates on the outermost type? */
-
-/* Contract negates. */
-(match_and_simplify
- (plus:c @0 (negate @1))
- (if (!TYPE_SATURATING (type)))
- (minus @0 @1))
-(match_and_simplify
- (minus @0 (negate @1))
- (if (!TYPE_SATURATING (type)))
- (plus @0 @1))
-
-
-/* Match patterns that allow contracting a plus-minus pair
- irrespective of overflow issues.
- ??? !TYPE_SATURATING condition missing.
- ??? !FLOAT_TYPE_P && !FIXED_POINT_TYPE_P condition missing
- because of saturation to +-Inf. */
-
-(if (!TYPE_SATURATING (type)
- && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type))
- (match_and_simplify
- (minus (plus @0 @1) @0)
- @1)
-
- (match_and_simplify
- (minus (minus @0 @1) @0)
- (negate @1))
-
- (match_and_simplify
- (minus (plus @0 @1) @1)
- @0)
-
- (match_and_simplify
- (plus:c (minus @0 @1) @1)
- @0))
-
-/* (CST +- A) +- CST -> CST' +- A. */
-/* match_and_simplify handles constant folding for us so we can
- implement these as re-association patterns.
- Watch out for operand order and constant canonicalization
- we do! A - CST -> A + -CST, CST + A -> A + CST. */
-(match_and_simplify
- (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2)
- /* If the constant operation overflows we cannot do the transform
- as we would introduce undefined overflow, for example
- with (a - 1) + INT_MIN. */
- (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2))))
- (plus @0 @1))
-(match_and_simplify
- (plus (minus INTEGER_CST_P@0 @1) INTEGER_CST_P@2)
- (minus (plus @0 @2) @1))
-/* TODO:
- (A +- CST) +- CST -> A +- CST
- ~A + A -> -1
- ~A + 1 -> -A
- A - (A +- B) -> -+ B
- A +- (B +- A) -> +- B
- CST +- (CST +- A) -> CST +- A
- CST +- (A +- CST) -> CST +- A
- A + ~A -> -1
- (T)(P + A) - (T)P -> (T)A
- */
-
-/* ~A + A -> -1 */
-(match_and_simplify
- (plus:c (bit_not @0) @0)
- { build_all_ones_cst (type); })
-
-/* ~A + 1 -> -A */
-(match_and_simplify
- (plus (bit_not integral_op_p@0) integer_onep)
- (negate @0))
-
-/* A - (A +- B) -> -+ B */
-(match_and_simplify
- (minus @0 (plus:c @0 @1))
- (negate @1))
-(match_and_simplify
- (minus @0 (minus @0 @1))
- @1)
-
-/* (T)(P + A) - (T)P -> (T) A */
-(match_and_simplify
- (minus (convert (pointer_plus @0 @1))
- (convert @0))
- (convert @1))
/* Patterns required to avoid SCCVN testsuite regressions. */
@@ -233,124 +101,11 @@ along with GCC; see the file COPYING3.
(fma INTEGER_CST_P@0 INTEGER_CST_P@1 @3)
(plus (mult @0 @1) @3))
-/* One builtin function to atom. */
-(match_and_simplify
- (BUILT_IN_SQRT (mult @0 @0))
- @0)
-/* One builtin function to builtin function. */
-(match_and_simplify
- (BUILT_IN_CABS (complex:c @0 real_zerop))
- (BUILT_IN_FABS @0))
-/* One builtin function to expr. */
-(match_and_simplify
- (BUILT_IN_CABS (complex @0 @0))
- (mult (BUILT_IN_FABS @0) { build_real (TREE_TYPE (@0), real_value_truncate (TYPE_MODE (TREE_TYPE (@0)), dconst_sqrt2 ())); }))
-/* One nested fn. */
-(match_and_simplify
- (mult:c (BUILT_IN_POW @0 @1) @0)
- (BUILT_IN_POW @0 (PLUS_EXPR @1 { build_one_cst (TREE_TYPE (@1)); })))
-(match_and_simplify
- (BUILT_IN_POW @0 REAL_CST_P@1)
- /* This needs to be conditionalized on flag_unsafe_math_optimizations,
- but we keep it for now to exercise function re-optimization.
- It makes gcc.dg/pr43419.c FAIL execution though. */
- (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 integral_op_p@0 @0)
- @0)
-
-/* x & ~x -> 0 */
-(match_and_simplify
- (bit_and:c integral_op_p@0 (bit_not @0))
- { build_int_cst (type, 0); })
-
-/* ~x & ~y -> ~(x | y) */
-(match_and_simplify
- (bit_and (bit_not integral_op_p@0) (bit_not @1))
- (bit_not (bit_ior @0 @1)))
-
-/* ~x | ~y -> ~(x & y) */
-(match_and_simplify
- (bit_ior (bit_not integral_op_p@0) (bit_not @1))
- (bit_not (bit_and @0 @1)))
-
-/* x & (~x | y) -> y & x */
-(match_and_simplify
- (bit_and:c integral_op_p@0 (bit_ior:c (bit_not @0) @1))
- (bit_and @1 @0))
-
-/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */
-(match_and_simplify
- (bit_and (bit_ior integral_op_p@0 INTEGER_CST_P@1) INTEGER_CST_P@2)
- (bit_ior (bit_and @0 @2) (bit_and @1 @2)))
-
-/* x ^ ~0 -> ~x */
-(match_and_simplify
- (bit_xor @0 integer_all_onesp@1)
- (bit_not @0))
-
-/* (x | y) & x -> x */
-(match_and_simplify
- (bit_and:c (bit_ior integral_op_p@0 @1) @0)
- @0)
-
-/* (x & y) | x -> x */
-(match_and_simplify
- (bit_ior:c (bit_and integral_op_p@0 @1) @0)
- @0)
-
-/* (~x | y) & x -> x & y */
-(match_and_simplify
- (bit_and:c (bit_ior:c (bit_not integral_op_p@0) @1) @0)
- (bit_and @0 @1))
-
-/* (~x & y) | x -> x | y */
-(match_and_simplify
- (bit_ior:c (bit_and:c (bit_not integral_op_p@0) @1) @0)
- (bit_ior @0 @1))
-
-/* ~~x -> x */
-(match_and_simplify
- (bit_not (bit_not integral_op_p@0))
- @0)
-
-/* ((a & b) & ~a) -> 0 */
-(match_and_simplify
- (bit_and:c (bit_and integral_op_p@0 @1) (bit_not @0))
- { build_int_cst (type, 0); })
-
-/* (x << CNT1) OP (x >> CNT2) -> x r<< CNT1 OP being +, |, ^ */
-(for op in plus bit_ior bit_xor
-(match_and_simplify
- (op:c (lshift @0 INTEGER_CST_P@1) (rshift @0 INTEGER_CST_P@2))
- (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
- && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
- && tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2)
- && tree_to_uhwi (@1) + tree_to_uhwi (@2) == TYPE_PRECISION (type)))
- (lrotate @0 @1)))
-
+#include "match-plusminus.pd"
+#include "match-bitwise.pd"
+#include "match-rotate.pd"
+#include "match-builtin.pd"
+#include "match-constant-folding.pd"
/* ????s
Index: gcc/match-plusminus.pd
===================================================================
--- gcc/match-plusminus.pd (revision 0)
+++ gcc/match-plusminus.pd (working copy)
@@ -0,0 +1,108 @@
+/* match-and-simplify patterns for associate_plusminus
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* ??? Have match_and_simplify groups guarded with common
+ predicates on the outermost type? */
+
+/* Contract negates. */
+(match_and_simplify
+ (plus:c @0 (negate @1))
+ (if (!TYPE_SATURATING (type)))
+ (minus @0 @1))
+(match_and_simplify
+ (minus @0 (negate @1))
+ (if (!TYPE_SATURATING (type)))
+ (plus @0 @1))
+
+
+/* Match patterns that allow contracting a plus-minus pair
+ irrespective of overflow issues.
+ ??? !TYPE_SATURATING condition missing.
+ ??? !FLOAT_TYPE_P && !FIXED_POINT_TYPE_P condition missing
+ because of saturation to +-Inf. */
+
+(if (!TYPE_SATURATING (type)
+ && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type))
+ (match_and_simplify
+ (minus (plus @0 @1) @0)
+ @1)
+
+ (match_and_simplify
+ (minus (minus @0 @1) @0)
+ (negate @1))
+
+ (match_and_simplify
+ (minus (plus @0 @1) @1)
+ @0)
+
+ (match_and_simplify
+ (plus:c (minus @0 @1) @1)
+ @0))
+
+/* (CST +- A) +- CST -> CST' +- A. */
+/* match_and_simplify handles constant folding for us so we can
+ implement these as re-association patterns.
+ Watch out for operand order and constant canonicalization
+ we do! A - CST -> A + -CST, CST + A -> A + CST. */
+(match_and_simplify
+ (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2)
+ /* If the constant operation overflows we cannot do the transform
+ as we would introduce undefined overflow, for example
+ with (a - 1) + INT_MIN. */
+ (if (!TREE_OVERFLOW (@1 = int_const_binop (PLUS_EXPR, @1, @2))))
+ (plus @0 @1))
+(match_and_simplify
+ (plus (minus INTEGER_CST_P@0 @1) INTEGER_CST_P@2)
+ (minus (plus @0 @2) @1))
+/* TODO:
+ (A +- CST) +- CST -> A +- CST
+ ~A + A -> -1
+ ~A + 1 -> -A
+ A - (A +- B) -> -+ B
+ A +- (B +- A) -> +- B
+ CST +- (CST +- A) -> CST +- A
+ CST +- (A +- CST) -> CST +- A
+ A + ~A -> -1
+ (T)(P + A) - (T)P -> (T)A
+ */
+
+/* ~A + A -> -1 */
+(match_and_simplify
+ (plus:c (bit_not @0) @0)
+ { build_all_ones_cst (type); })
+
+/* ~A + 1 -> -A */
+(match_and_simplify
+ (plus (bit_not integral_op_p@0) integer_onep)
+ (negate @0))
+
+/* A - (A +- B) -> -+ B */
+(match_and_simplify
+ (minus @0 (plus:c @0 @1))
+ (negate @1))
+(match_and_simplify
+ (minus @0 (minus @0 @1))
+ @1)
+
+/* (T)(P + A) - (T)P -> (T) A */
+(match_and_simplify
+ (minus (convert (pointer_plus @0 @1))
+ (convert @0))
+ (convert @1))
+
Index: gcc/match-rotate.pd
===================================================================
--- gcc/match-rotate.pd (revision 0)
+++ gcc/match-rotate.pd (working copy)
@@ -0,0 +1,29 @@
+/* match-and-simplify patterns for simplify_rotate
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* (x << CNT1) OP (x >> CNT2) -> x r<< CNT1 OP being +, |, ^ */
+(for op in plus bit_ior bit_xor
+(match_and_simplify
+ (op:c (lshift @0 INTEGER_CST_P@1) (rshift @0 INTEGER_CST_P@2))
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && TYPE_PRECISION (type) == GET_MODE_PRECISION (TYPE_MODE (type))
+ && tree_fits_uhwi_p (@1) && tree_fits_uhwi_p (@2)
+ && wi::eq_p (TYPE_PRECISION (type), wi::add (@1, @2))))
+ (lrotate @0 @1)))