https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65493
Bug ID: 65493 Summary: bug with 64/32 division sign related to various factors (-O3) Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ml-gnubugzilla at worldspot dot net Hi Problem with a 64bit/32bit signed division with -O3 and various factors. I found this weirg bug when using -O3 on various gcc versions. platform: redhat el6.5 x84_64 tested gcc versions: 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) target x86: 32 and 64bit (-m32 and -m64) 4.9.0 self compiled, target x86 32 and 64bit 4.8.0 self compiled, target sparc the code: ##################### #include<stdint.h> #include<stdio.h> void __attribute__ ((noinline)) xLoop16( int64_t h , int64_t hInc , int32_t l , int32_t lInc , int nElem ){ for(;nElem>0;nElem-=1) { { int32_t x=h/l; printf(">>%08llx/%08x = %08x \n",h,l,x); h+=hInc; l+=lInc; } { int32_t x=h/l; printf(">>%08llx/%08x = %08x \n",h,l,x); h+=hInc; l+=lInc; } } } int main(){ xLoop16( 0x4337d8c0000LL , 0x233dcbc8LL , 0x748974b0L , 0x08235a18L , 4 ); } ############################ The good result: $ gcc test.c -O1 && ./a.out >>4337d8c0000/748974b0 = 0000093a >>433a0c9cbc8/7caccec8 = 000008a0 >>433c4079790/84d028e0 = fffff745 >>433e7456358/8cf382f8 = fffff6a6 >>4340a832f20/9516dd10 = fffff5f0 >>4342dc0fae8/9d3a3728 = fffff51b >>43450fec6b0/a55d9140 = fffff420 >>434743c9278/ad80eb58 = fffff2f4 The bad result: the division result is always positive, it has become an unsigned division: $ gcc test.c -O3 && ./a.out >>4337d8c0000/748974b0 = 0000093a >>433a0c9cbc8/7caccec8 = 000008a0 >>433c4079790/84d028e0 = 00000819 >>433e7456358/8cf382f8 = 000007a2 >>4340a832f20/9516dd10 = 00000737 >>4342dc0fae8/9d3a3728 = 000006d8 >>43450fec6b0/a55d9140 = 00000682 >>434743c9278/ad80eb58 = 00000634 What changes the result to the good one: - removing the noinline attribute - change the for loop: for(nElem=4;nElem>0;nElem-=1) { instead of for(;nElem>0;nElem-=1) { - there are 2 identical blocks in the loop. removing one gives a good result!