In http://gcc.gnu.org/ml/gcc/2010-08/msg00326.html Revital complained about MAX_EXPR no longer being recognized in: int foo (const unsigned char *tmp, int i, int val) { return (unsigned char)(((tmp[i] + val)>0xFF)?0xFF:(((tmp[i] + val)<0)?0:(tmp[i] + val))); } It is still recognized when using: int bar (const unsigned char *tmp, int i, int val) { int x = (((tmp[i] + val)>0xFF)?0xFF:(((tmp[i] + val)<0)?0:(tmp[i] + val))); return (unsigned char)x; } The regression is caused by folding being delayed in the C FE, while before the inner COND_EXPR has been optimized by fold_ternary* into MAX_EXPR, now it isn't immediately, thus convert_to_integer on the narrowing conversion propagates the (unsigned char) narrowing casts down into the operands and when fold_ternary* is actually called, it is too late, as the operands aren't considered equal.
Perhaps it would be nice for -O2 to consider for e.g. int a and b that (unsigned char) (a + b) is the same as (unsigned char) a + (unsigned char) b during VN. -- Summary: [4.5/4.6 Regression] Issues with integer narrowing conversions Product: gcc Version: 4.6.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45397