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

sophana <ml-gnubugzilla at worldspot dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |CLOSED

--- Comment #3 from sophana <ml-gnubugzilla at worldspot dot net> ---
Thanks for your answer.

I made some tests. You are right, it is the addition overflow that causes the
wrong result on all the next divisions:

Looking deeper, I just learnt that (signed) integer overflow cause undefined
behaviour (and not with unsigned)

The overflow bit is raised in the hardware and changes the behaviour of signed
division, and the division behaviour in case of overflow is also undefined.

I still can't explain why this behaviour disapears when:
- 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!

I changed the loop arguments which shows that the division is not stateless
(because of the overflow bit)

int main(){
    xLoop16(
        0x4337d8c0000LL
    ,    0x233dcbc8LL
    ,    -0x048974b0L
    ,    0x18235a18L
    ,    4
    );
}


$ gcc test.c -O1 && ./a.out
>>4337d8c0000/db768b50 = ffffe291 
>>433a0c9cbc8/fd76e568 = fffe57c9 
>>433c4079790/1f773f80 = 00002230 
>>433e7456358/41779998 = 0000106f 
>>4340a832f20/6377f3b0 = 00000ad1 
>>4342dc0fae8/85784dc8 = fffff738 
>>43450fec6b0/a778a7e0 = fffff3d8 
>>434743c9278/c97901f8 = ffffec43 
[skok@power4 ~]$ gcc test.c -O3 && ./a.out
>>4337d8c0000/db768b50 = ffffe291 
>>433a0c9cbc8/fd76e568 = fffe57c9 
>>433c4079790/1f773f80 = 00002230 
>>433e7456358/41779998 = 0000106f 
>>4340a832f20/6377f3b0 = 00000ad1 
>>4342dc0fae8/85784dc8 = 00000810 
>>43450fec6b0/a778a7e0 = 0000066d 
>>434743c9278/c97901f8 = 00000557 

Only the last 3 divisions become unsigned after the overflow occurs.

Sorry for the invalid bug

Reply via email to