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

Reply via email to