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)))