[Bug target/53987] [SH] Unnecessary zero-extensions

olegendo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Dec 22 22:27:00 GMT 2014


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987

--- Comment #6 from Oleg Endo <olegendo at gcc dot gnu.org> ---
In the following example function

bool stack_is_background_free( unsigned short* _data, const size_t _size){

  size_t num_pixels_above_128 = 0;
  for(size_t index = 0;index< _size;++index){
    if(_data[index] > 128)
      num_pixels_above_128++;
  }

  return num_pixels_above_128 == _size;
}


unsigned 16 bit values are compared against an 8 bit constant, which results in
the following code:

        mov.w   @r4+,r1
        extu.w  r1,r1
        cmp/hi  r7,r1
        mov     #0,r1
        addc    r1,r3
        dt      r2
        bf      .L4

In this case, the zero extension can be omitted, since the comparison result
will always be 'true' if any bits >= 8 in the 16 bit value are set:

0x8000 (sign extend) -> 0xFFFF8000 (unsigned) > 0x80 = 1
0x8000 (zero extend) -> 0x00008000 (unsigned) > 0x80 = 1


The same would also apply for 8 bit values:

int test (unsigned char* x)
{
  return x[0] >= 127;
}

compiles to:
        mov.b   @r4,r1
        mov     #126,r2
        extu.b  r1,r1
        cmp/hi  r2,r1
        rts
        movt    r0

0x80 (sign extend) -> 0xFFFFFF80 (unsigned) > 0x7E = 1
0x80 (zero extend) -> 0x00000080 (unsigned) > 0x7E = 1



More information about the Gcc-bugs mailing list