https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91202
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target|x86 |x86_64-*-* i?86-*-* CC| |jakub at gcc dot gnu.org, | |rguenth at gcc dot gnu.org Component|c |middle-end --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- If you use singed adds it makes a semantic difference and we narrow it to (unsigned char)a + (unsigned char)b to make it well-defined in case of overflow. I think the same issue applies for the shift where C says that a >> b is really (int)a >> b and thus it is well-defined if b == 24. If we write it as gimple (char)a >> b then we conclude b has to be in the range [0, 7] which would be wrong. So on GIMPLE we'd need to do (char)a >> (b&7) which I think wouldn't be nicely canonical. So this is probably best fixed at RTL expansion time or somewhen shortly before RTL expansion in a "narrowing/widening" pass taking into account target capabilities (and ABIs). I think the vectorizer has similar tricks in the pattern recognizer.