https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987
--- Comment #5 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #4) > It seems that converting unsigned values to signed values, i.e. replacing > zero-extensions with sign-extensions and recombining sign-extensions with > loads could make sense in general. > > For example, the following code from CSiBE > mpeg2dec-0.3.1/libmpeg2/motion_comp.s contains sequences like: > > _MC_put_x_8_c: > .align 2 > .L24: > mov.b @r5,r0 > sett > extu.b r0,r1 > mov.b @(1,r5),r0 > extu.b r0,r0 > addc r1,r0 > shar r0 > mov.b r0,@r4 > sett > mov.b @(1,r5),r0 > extu.b r0,r3 > mov.b @(2,r5),r0 > extu.b r0,r1 > mov r3,r0 > addc r1,r0 > shar r0 > mov.b r0,@(1,r4) > .... > > Here effectively only 8 bit values are calculated. The zero-extensions can > be omitted, since the higher bits do not influence the result of the lowest > 8 bits and the higher bits are discarded after the 8 bit stores. Sorry, bad example. The zero-extensions can't be emitted in this case because of the right shift. In the following example bits > 15 are don't care void test_0 (unsigned short* x, int y, int z) { x[11] = ((x[0] + x[1] + 1) << 1) + ((x[2] + x[3] + 1) << 2) - y; } .. and there are no zero-extensions in this case. Using function arguments instead: void test_1 (unsigned short* x, unsigned short a, unsigned short b, unsigned short c, unsigned short d, unsigned short e) { x[11] = ((a + b + 1) << 1) + ((c + d + 1) << 2) - e; } ... brings back the zero extensions. This is probably because of the SH ABI (PR 52441), but in this case the extensions are really not needed.