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.

Reply via email to