On match-and-simplify branch I run into a recursion folding (bool_var & 1) == 0
via !(bool_var & 1) to (bool_var & 1) == 0 The appearant recursion prevention (well, not documented as such) in fold_truth_not_expr doesn't work because we still fold its result via the various fold_convert calls which on the branch results in folding (T)((bool_var & 1) == 0) to (bool_var & 1) == 0 with type T (thus folding that comparison again). The fix is simple as TRUTH_NOT_EXPR does not need to have the same type as its opearand (see fold_truth_not_expr for an existing example). Simply avoid all the excessive conversions and build it with the desired type in the first place. Btw, the simplification match-and-simplify has but fold-const.c on trunk has not (yet) which triggers this is (simplify (convert (eq @0 @1)) (if (TREE_CODE (type) == BOOLEAN_TYPE) (cmp @0 @1)) which folds of comparisons to bool into the comparison itself (that's from forwprop). Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2014-10-23 Richard Biener <rguent...@suse.de> * fold-const.c (fold_truth_not_expr): Take type as argument. (fold_unary_loc): Pass type to fold_truth_not_expr, remove redundant conversion. (fold_binary_loc): Build TRUTH_NOT_EXPR with the desired type directly. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 216549) +++ gcc/fold-const.c (working copy) @@ -3125,9 +3125,8 @@ omit_two_operands_loc (location_t loc, t problems with the dominator optimizer. */ static tree -fold_truth_not_expr (location_t loc, tree arg) +fold_truth_not_expr (location_t loc, tree type, tree arg) { - tree type = TREE_TYPE (arg); enum tree_code code = TREE_CODE (arg); location_t loc1, loc2; @@ -8108,10 +8107,7 @@ fold_unary_loc (location_t loc, enum tre and its values must be 0 or 1. ("true" is a fixed value perhaps depending on the language, but we don't handle values other than 1 correctly yet.) */ - tem = fold_truth_not_expr (loc, arg0); - if (!tem) - return NULL_TREE; - return fold_convert_loc (loc, type, tem); + return fold_truth_not_expr (loc, type, arg0); case REALPART_EXPR: if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE) @@ -12628,16 +12624,12 @@ fold_binary_loc (location_t loc, /* bool_var != 1 becomes !bool_var. */ if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1) && code == NE_EXPR) - return fold_convert_loc (loc, type, - fold_build1_loc (loc, TRUTH_NOT_EXPR, - TREE_TYPE (arg0), arg0)); + return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, arg0); /* bool_var == 0 becomes !bool_var. */ if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1) && code == EQ_EXPR) - return fold_convert_loc (loc, type, - fold_build1_loc (loc, TRUTH_NOT_EXPR, - TREE_TYPE (arg0), arg0)); + return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, arg0); /* !exp != 0 becomes !exp */ if (TREE_CODE (arg0) == TRUTH_NOT_EXPR && integer_zerop (arg1)