------- Comment #5 from bonzini at gnu dot org 2008-08-27 07:14 ------- With this patch:
Index: fold-const.c =================================================================== --- fold-const.c (revision 139423) +++ fold-const.c (working copy) @@ -7868,7 +7868,11 @@ fold_unary (enum tree_code code, tree ty very likely don't have maximal range for their precision and this transformation effectively doesn't preserve non-maximal ranges. */ if (TREE_CODE (type) == INTEGER_TYPE - && TREE_CODE (op0) == BIT_AND_EXPR + && (TREE_CODE (op0) == BIT_AND_EXPR + || TREE_CODE (op0) == BIT_IOR_EXPR + || TREE_CODE (op0) == BIT_XOR_EXPR + || TREE_CODE (op0) == PLUS_EXPR + || TREE_CODE (op0) == MINUS_EXPR) && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST) { tree and = op0; @@ -7906,7 +7910,7 @@ fold_unary (enum tree_code code, tree ty tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1), TREE_INT_CST_HIGH (and1), 0, TREE_OVERFLOW (and1)); - return fold_build2 (BIT_AND_EXPR, type, + return fold_build2 (TREE_CODE (op0), type, fold_convert (type, and0), tem); } } I can fold "(unsigned) (x + 1)" to "(unsigned) x + 1". The problem is that TER does not fold the trees it creates. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37242