Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 208539) +++ gcc/fold-const.c (working copy) @@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. #include "gimplify.h" #include "tree-dfa.h" #include "hash-table.h" /* Required for ENABLE_FOLD_CHECKING. */ +#include "tree-pretty-print.h" /* Nonzero if we are folding constants inside an initializer; zero otherwise. */ @@ -9698,6 +9699,33 @@ fold_comparison (location_t loc, enum tr fold_convert_loc (loc, cmp_type, arg1))); } + /* Fold (X >> CST1) > CST2 -> X > CST2 << CST1 */ + if (TREE_CODE (arg0) == RSHIFT_EXPR && code == GT_EXPR) + { + tree var = TREE_OPERAND (arg0, 0); + tree cst1 = TREE_OPERAND (arg0, 1); + if ((TREE_CODE (cst1) == INTEGER_CST || TREE_CODE (arg1) == VECTOR_CST) + && (TREE_CODE (arg1) == INTEGER_CST || TREE_CODE (arg1) == VECTOR_CST)) + return fold_build2_loc (loc, GT_EXPR, type, var, + fold_convert_loc (loc, TREE_TYPE (var), + int_const_binop (LSHIFT_EXPR, cst1, arg1))); + } + + /* Fold (X & CST) == 0 -> X <= ~CST */ + if (TREE_CODE (arg0) == BIT_AND_EXPR && code == EQ_EXPR && integer_zerop (arg1)) + { + tree var = TREE_OPERAND (arg0, 0); + tree cst = TREE_OPERAND (arg0, 1); + tree bit_not_expr; + + if (TREE_CODE (cst) == INTEGER_CST || TREE_CODE (cst) == VECTOR_CST) + { + bit_not_expr = fold_unary (BIT_NOT_EXPR, TREE_TYPE (cst), cst); + return fold_build2_loc (loc, LE_EXPR, type, var, + fold_convert_loc (loc, TREE_TYPE (var), bit_not_expr)); + } + } + return NULL_TREE; }