http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48734
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-04-26 06:56:46 UTC --- Reduced testcase: unsigned int foo (int x, unsigned int y, unsigned int z) { z &= (x == -__INT_MAX__ - 1 ? x : -x) > y; z &= (x == -__INT_MAX__ - 1 ? x : -x) > y; z &= (x == -__INT_MAX__ - 1 ? x : -x) > y; return z; } The problem is that fold (from maybe_fold_and_comparisons) in this case canonicalizes the comparison in: /* The following case also applies to X < signed_max+1 and X >= signed_max+1 because previous transformations. */ if (code == LE_EXPR || code == GT_EXPR) { tree st; st = signed_type_for (TREE_TYPE (arg1)); return fold_build2_loc (loc, code == LE_EXPR ? GE_EXPR : LT_EXPR, type, fold_convert_loc (loc, st, arg0), build_int_cst (st, 0)); } to include the extra cast to the signed cast and eliminate_redundant_comparison is prepared to handle just one operation instead of two. I think expecting fold to return some particular form of result is just wrong assumption, it will break sooner or later, so while the code could perhaps handle on extra cast or something similar, it needs to give up on elimination if the returned expression can't be handled.