Pelles C forum

Pelles C => Bug reports => Topic started by: tfo on August 03, 2014, 07:16:29 PM

Title: Compiler optimization bug [Fixed in 8.00 RC 8]
Post by: tfo on August 03, 2014, 07:16:29 PM
Tested with 8.00 RC6 and 7.00 (refresh).

With any of the optimization options, bad code is generated.
With optimization on, gcd returns 0. With optimization off it returns 1, which is the correct result.

int gcd(int a, int b)
{
    if(b) return gcd(b,a%b);
    else return a;
}

int main(void)
{
    return gcd(1,1);
}
Title: Re: Compiler optimization bug
Post by: neo313 on August 03, 2014, 10:43:49 PM
Using a temp variable removes the bug, when optimizations are present.


#include <stdio.h>

int gcd(int a, int b)
{
    if( b != 0 )
{
const int c = a%b ;
return gcd( b , c ) ;
}
    else
{
return a ;
}
}

int main(void)
{
printf("%d\n" , gcd(1,1) ) ;

    return 0 ;
}



Both examples are with optimization, the problem is with the last two mov instructions, otherwise the code is the same.

(http://i.imgur.com/DlxoKVh.jpg)

Title: Re: Compiler optimization bug
Post by: frankie on August 04, 2014, 11:31:03 AM
Very nice the optimization that doesn't recall the sub sparing stack space and speeding-up execution!  :)
The error is the same in the 32 and 64 bits version:

;;;;; 32 Bits version
_gcd:
push              ebx
mov               ebx,dword ptr [esp+8]
mov               ecx,dword ptr [esp+C]
50: {
51:     if(b)
L9:
test              ecx,ecx
je                L18
52: return gcd(b,a%b);
mov               eax,ebx
cdq               
idiv              ecx
mov               ecx,edx ;---\
mov               ebx,ecx ;---+----------- WRONG! these instructions must be reversed
jmp               L9
53:     else
54: return a;
L18:
mov               eax,ebx
pop               ebx
ret               
lea               edi,[edi+0]
55: }


;;;;;;; 64 bits version
49: int gcd(int a, int b)

gcd:
mov               r8d,ecx
mov               ecx,edx
50: {
51:     if(b)
L5:
test              ecx,ecx
je                L16
52: return gcd(b,a%b);
mov               eax,r8d
cdq               
idiv              ecx
mov               ecx,edx ;---\
mov               r8d,ecx ;---+----------- WRONG! these instructions must be reversed
jmp               L5
53:     else
54: return a;
L16:
mov               eax,r8d
ret               
55: }


EDIT: I'm very tired today, my brain wan't cooperate! I posted two wrong answers in a row!!!  >:(
The problem is the order of the move instructions that reloads the parameters ...  :P
Maybe it's better to check if destination register is a result holding register to define the correct order of data assignement.
Title: Re: Compiler optimization bug
Post by: tfo on February 12, 2015, 12:46:07 AM
Not fixed in 8.00 RC7.
Title: Re: Compiler optimization bug
Post by: tfo on March 10, 2015, 04:49:18 AM
Fixed in 8.00 RC8.