A possible gcc bug?

David Brown david@westcontrol.com
Fri Sep 7 06:57:00 GMT 2018


I am always wary of saying there might be a compiler bug - usually it is 
a bug in the user code.  But this time I am very suspicious.  The 
example here comes from a discussion in the comp.lang.c Usenet group.

Here is the code I have been testing:


unsigned char foo_u(unsigned int v) {
     return (v & 0x7f) | (v & ~0x7f ? 0x80 : 0);
}

unsigned char foo_s(int v) {
     return (v & 0x7f) | (v & ~0x7f ? 0x80 : 0);
}

unsigned char bar_s(int v) {
     int x = v & 0x7f;
     return (v & 0x7f) | (x ? 0x80 : 0);
}


int test_u_1(void) {
     return foo_u(0x01);		// Expect 0x01 = 1
}

int test_u_2(void) {
     return foo_u(0x1001);	// Expect 0x81 = 129
}

int test_s_1(void) {
     return foo_s(0x01);		// Expect 0x01 = 1
}

int test_s_2(void) {
     return foo_s(0x1001);	// Expect 0x81 = 129
}


The assembly code generated for this is:

foo_u(unsigned int):
         mov     edx, edi
         and     edx, 127
         and     edi, -128
         cmp     edi, 1
         sbb     eax, eax
         not     eax
         and     eax, -128
         or      eax, edx
         ret
foo_s(int):
         mov     eax, edi
         ret
bar_s(int):
         mov     edx, edi
         and     edx, 127
         and     edi, 127
         cmp     edi, 1
         sbb     eax, eax
         not     eax
         and     eax, -128
         or      eax, edx
         ret
test_u_1():
         mov     eax, 1
         ret
test_u_2():
         mov     eax, 129
         ret
test_s_1():
         mov     eax, 1
         ret
test_s_2():
         mov     eax, 1
         ret



When the code uses "int" rather than "unsigned int", in "foo_s", the 
compiler thinks the function can be optimised to a simple byte 
extraction.  I cannot see how that interpretation is valid.  And gcc 
cannot see it either, if there is an intermediate variable (in "bar_s"). 
  (The type of the intermediate "x" in "bar_s" does not matter - "int", 
"unsigned int", "auto", "__auto_type", const or not).

This effect is happening in the front-end.  It is independent of 
optimisation levels (-O gives the same results), the target processor (I 
tried a half-dozen targets), the compiler version (from gcc 4.4 upwards 
- gcc 4.1 gives the same code for foo_s as foo_u.  I haven't tried gcc 
4.2 or 4.3).  The results from the compiler evaluations in the "test_" 
functions shows that it this happens in the compiler analysis - it is 
not a code generation issue.

<https://godbolt.org> is great for this kind of testing!


Is there something going wrong in gcc here, or is there something I am 
missing?

mvh.,

David



More information about the Gcc mailing list