Message ID | CAEwic4ajviWZZ=JoAC-AYOWzFThuv71_V_0dLTx2Wfh99Da2QQ@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Wed, Jul 13, 2011 at 9:34 AM, Kai Tietz <ktietz70@googlemail.com> wrote: > Hello, > > This patch adds support to fold_binary_loc for one-bit precision > typed bitwise-and expression. Similar ... your patch descriptions are useless btw. > ChangeLog > > 2011-07-13 Kai Tietz <ktietz@redhat.com> > > * fold-const.c (fold_binary_loc): Add > support for one-bit bitwise-and optimizeation. > > Bootstrapped and regression tested with prior patches of this series > for x86_64-pc-linux-gnu. > Ok for apply? > > Regards, > Kai > > Index: gcc/gcc/fold-const.c > =================================================================== > --- gcc.orig/gcc/fold-const.c 2011-07-13 08:43:37.000000000 +0200 > +++ gcc/gcc/fold-const.c 2011-07-13 08:58:38.692620200 +0200 > @@ -11062,6 +11062,48 @@ fold_binary_loc (location_t loc, > if (operand_equal_p (arg0, arg1, 0)) > return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); > > + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) > + { > + if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0)) > + return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); > + if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)) > + return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); > + /* Likewise for first arg. */ > + if (integer_zerop (arg0)) > + return omit_one_operand_loc (loc, type, arg0, arg1); > + > + /* !X & X is always false. ~X & X is always false. */ > + if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR > + || TREE_CODE (arg0) == BIT_NOT_EXPR) > + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) > + return omit_one_operand_loc (loc, type, integer_zero_node, arg1); > + /* X & !X is always false. X & ~X is always false. */ > + if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR > + || TREE_CODE (arg1) == BIT_NOT_EXPR) > + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) > + return omit_one_operand_loc (loc, type, integer_zero_node, arg0); > + > + /* (A < X) & (A + 1 > Y) ==> (A < X) & (A >= Y). Normally > + A + 1 > Y means (A >= Y) & (A != MAX), but in this case > + we know that A < X <= MAX. */ > + > + if (!TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) > + { > + tem = fold_to_nonsharp_ineq_using_bound (loc, arg0, arg1); > + if (tem && !operand_equal_p (tem, arg0, 0)) > + return fold_build2_loc (loc, code, type, tem, arg1); > + > + tem = fold_to_nonsharp_ineq_using_bound (loc, arg1, arg0); > + if (tem && !operand_equal_p (tem, arg1, 0)) > + return fold_build2_loc (loc, code, type, arg0, tem); > + } > + > + tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1); > + if (tem) > + return tem; > + > + } > + > /* ~X & X, (X == 0) & X, and !X & X are always zero. */ > if ((TREE_CODE (arg0) == BIT_NOT_EXPR > || TREE_CODE (arg0) == TRUTH_NOT_EXPR >
Index: gcc/gcc/fold-const.c =================================================================== --- gcc.orig/gcc/fold-const.c 2011-07-13 08:43:37.000000000 +0200 +++ gcc/gcc/fold-const.c 2011-07-13 08:58:38.692620200 +0200 @@ -11062,6 +11062,48 @@ fold_binary_loc (location_t loc, if (operand_equal_p (arg0, arg1, 0)) return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); + if (TYPE_PRECISION (type) == 1 && INTEGRAL_TYPE_P (type)) + { + if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0)) + return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg1)); + if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)) + return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0)); + /* Likewise for first arg. */ + if (integer_zerop (arg0)) + return omit_one_operand_loc (loc, type, arg0, arg1); + + /* !X & X is always false. ~X & X is always false. */ + if ((TREE_CODE (arg0) == TRUTH_NOT_EXPR + || TREE_CODE (arg0) == BIT_NOT_EXPR) + && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)) + return omit_one_operand_loc (loc, type, integer_zero_node, arg1); + /* X & !X is always false. X & ~X is always false. */ + if ((TREE_CODE (arg1) == TRUTH_NOT_EXPR + || TREE_CODE (arg1) == BIT_NOT_EXPR) + && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)) + return omit_one_operand_loc (loc, type, integer_zero_node, arg0); + + /* (A < X) & (A + 1 > Y) ==> (A < X) & (A >= Y). Normally + A + 1 > Y means (A >= Y) & (A != MAX), but in this case + we know that A < X <= MAX. */ + + if (!TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) + { + tem = fold_to_nonsharp_ineq_using_bound (loc, arg0, arg1); + if (tem && !operand_equal_p (tem, arg0, 0)) + return fold_build2_loc (loc, code, type, tem, arg1); + + tem = fold_to_nonsharp_ineq_using_bound (loc, arg1, arg0); + if (tem && !operand_equal_p (tem, arg1, 0)) + return fold_build2_loc (loc, code, type, arg0, tem); + } + + tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1); + if (tem) + return tem; + + } + /* ~X & X, (X == 0) & X, and !X & X are always zero. */ if ((TREE_CODE (arg0) == BIT_NOT_EXPR || TREE_CODE (arg0) == TRUTH_NOT_EXPR