/* Match-and-simplify patterns for shared GENERIC and GIMPLE folding. This file is consumed by genmatch which produces gimple-match.c and generic-match.c from it. Copyright (C) 2014 Free Software Foundation, Inc. Contributed by Richard Biener and Prathamesh Kulkarni 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 . */ /* Generic tree predicates we inherit. */ (define_predicates integer_onep integer_zerop integer_all_onesp real_zerop real_onep CONSTANT_CLASS_P tree_expr_nonnegative_p) /* Simplifications of operations with one constant operand and simplifications to constants or single values. */ (for op (plus pointer_plus minus bit_ior bit_xor) (simplify (op @0 integer_zerop) (non_lvalue @0))) /* Simplify x - x. This is unsafe for certain floats even in non-IEEE formats. In IEEE, it is unsafe because it does wrong for NaNs. Also note that operand_equal_p is always false if an operand is volatile. */ (simplify (minus @0 @0) (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (TYPE_MODE (type))) { build_zero_cst (type); })) (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 (mult trunc_div ceil_div floor_div round_div exact_div) (simplify (op @0 integer_onep) (non_lvalue @0))) /* Same applies to modulo operations, but fold is inconsistent here and simplifies 0 % x to 0, only preserving literal 0 % 0. */ (for op (ceil_mod floor_mod round_mod trunc_mod) /* 0 % X is always zero. */ (simplify (op integer_zerop@0 @1) /* But not for 0 % 0 so that we can get the proper warnings and errors. */ (if (!integer_zerop (@1)) @0)) /* X % 1 is always zero. */ (simplify (op @0 integer_onep) { build_zero_cst (type); })) /* x | ~0 -> ~0 */ (simplify (bit_ior @0 integer_all_onesp@1) @1) /* x & 0 -> 0 */ (simplify (bit_and @0 integer_zerop@1) @1) /* x ^ x -> 0 */ (simplify (bit_xor @0 @0) { build_zero_cst (type); }) /* Canonicalize X ^ ~0 to ~X. */ (simplify (bit_xor @0 integer_all_onesp@1) (bit_not @0)) /* x & ~0 -> x */ (simplify (bit_and @0 integer_all_onesp) (non_lvalue @0)) /* x & x -> x, x | x -> x */ (for bitop (bit_and bit_ior) (simplify (bitop @0 @0) (non_lvalue @0))) (simplify (abs (negate @0)) (abs @0)) (simplify (abs tree_expr_nonnegative_p@0) @0) /* Simplifications of conversions. */ /* Basic strip-useless-type-conversions / strip_nops. */ (for cvt (convert view_convert float fix_trunc) (simplify (cvt @0) (if ((GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@0))) || (GENERIC && type == TREE_TYPE (@0))) @0))) /* Contract view-conversions. */ (simplify (view_convert (view_convert @0)) (view_convert @0)) /* For integral conversions with the same precision or pointer conversions use a NOP_EXPR instead. */ (simplify (view_convert @0) (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0))) (convert @0))) /* Strip inner integral conversions that do not change precision or size. */ (simplify (view_convert (convert@0 @1)) (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) && (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))) && (TYPE_SIZE (TREE_TYPE (@0)) == TYPE_SIZE (TREE_TYPE (@1)))) (view_convert @1))) /* Re-association barriers around constants and other re-association barriers can be removed. */ (simplify (paren CONSTANT_CLASS_P@0) @0) (simplify (paren (paren@1 @0)) @1)