------- Comment #11 from rguenth at gcc dot gnu dot org 2010-07-28 09:32 ------- I suppose that
uy = -ux; is really uy = (unsigned char) -(int) ux; as unsigned char promotes to int. We then incorrectly narrow this to -(signed char) ux. We do this again in convert_to_integer. Our bag of premature (and bogus) optimizations. case NEGATE_EXPR: case BIT_NOT_EXPR: /* This is not correct for ABS_EXPR, since we must test the sign before truncation. */ { tree typex; /* Don't do unsigned arithmetic where signed was wanted, or vice versa. */ if (TYPE_UNSIGNED (TREE_TYPE (expr))) typex = unsigned_type_for (type); else typex = signed_type_for (type); return convert (type, fold_build1 (ex_form, typex, convert (typex, TREE_OPERAND (expr, 0)))); well - I have no idea why we can't always choose an unsigned type here (testing that now). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45034