http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50182
--- Comment #33 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-03-02 09:13:52 UTC --- After Jason's patch (which needs to be kept, it was a wrong-code bugfix), we get out of the FE the addition in int type, while previously it was in unsigned char type. I.e. int D.2177; signed char D.2138; T D.2178; T D.2179; T D.2180; signed char result; D.2138 = custom_constant_add<signed char>::do_shift (D.2177); D.2178 = (T) result; D.2179 = (T) D.2138; D.2180 = D.2178 + D.2179; result = (signed char) D.2180; where T used to be unsigned char before and now is int. And no GIMPLE optimization pass manages to narrow the addition operation (together with the previous sign extensions and following demotion) to an unsigned char operation (signed char would be wrong, because of the possible overflow). I bet such narrowing in these cases could even help the vectorizer, which if it were to vectorize this or similar loops (it doesn't in this case), would do the promotions/demotions needlessly.